Skip to content

Commit 30aa7f2

Browse files
authored
Initial commit
0 parents  commit 30aa7f2

23 files changed

+904
-0
lines changed

.coveragerc

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[run]
2+
omit =
3+
# files to omit from coverage. should be sample files etc
4+
# */connection_sample.py
5+
6+
[report]
7+
exclude_lines =
8+
# Don't complain if non-runnable code isn't run:
9+
if __name__ == .__main__.

.editorconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
[*.py]
4+
indent_size = 4
5+
6+
[*]
7+
indent_style = space
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true

.github/actions/deploy/action.yml

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Deploy
2+
description: Deploy to GCP
3+
inputs:
4+
project_id:
5+
description: "The GCP project ID"
6+
required: true
7+
identity_provider:
8+
description: "The identity provider for the workload identity"
9+
required: true
10+
service_account_email:
11+
description: "The service account email"
12+
required: true
13+
pause_schedule_job:
14+
description: "Pause the scheduler job"
15+
required: false
16+
default: "no"
17+
github_token:
18+
description: "The GitHub token"
19+
required: true
20+
21+
runs:
22+
using: composite
23+
steps:
24+
- name: 🗝️ Authenticate to Google Cloud
25+
id: auth
26+
uses: google-github-actions/auth@v2
27+
with:
28+
workload_identity_provider: ${{ inputs.identity_provider }}
29+
service_account: ${{ inputs.service_account_email }}
30+
token_format: "access_token"
31+
32+
- name: 🐳 Set up Docker Buildx
33+
id: builder
34+
uses: docker/setup-buildx-action@v3
35+
36+
- name: 🗝️ Authenticate Docker to Google Cloud
37+
uses: docker/login-action@v3
38+
with:
39+
registry: us-central1-docker.pkg.dev
40+
username: oauth2accesstoken
41+
password: ${{ steps.auth.outputs.access_token }}
42+
43+
- name: 🏷️ Extract tags from GitHub
44+
id: meta
45+
uses: docker/metadata-action@v5
46+
with:
47+
github-token: ${{ inputs.github_token }}
48+
images: us-central1-docker.pkg.dev/${{ inputs.project_id }}/images/job
49+
tags: |
50+
type=ref,suffix=-{{sha}},event=branch
51+
type=ref,prefix=pr-,suffix=-{{sha}},event=pr
52+
type=semver,pattern={{version}}
53+
latest
54+
55+
- name: 📦 Build and push image
56+
uses: docker/build-push-action@v6
57+
with:
58+
builder: ${{ steps.builder.outputs.name }}
59+
tags: ${{ steps.meta.outputs.tags }}
60+
context: .
61+
file: ./Dockerfile
62+
push: true
63+
cache-from: type=gha
64+
cache-to: type=gha,mode=max
65+
provenance: false
66+
67+
- name: ☁️ Set up Cloud SDK
68+
uses: google-github-actions/setup-gcloud@v2
69+
70+
- name: 🚀 Deploy Cloud Run Job
71+
uses: google-github-actions/deploy-cloudrun@v2
72+
with:
73+
project_id: ${{ inputs.project_id }}
74+
region: us-central1
75+
image: us-central1-docker.pkg.dev/${{ inputs.project_id }}/images/job:latest
76+
job: default
77+
secrets: /secrets/app/secrets.json=skid-secrets:latest
78+
secrets_update_strategy: overwrite
79+
timeout: 3h
80+
flags: |
81+
--memory=3Gi
82+
--task-timeout=3h
83+
--max-retries=0
84+
--service-account=cloud-run-sa@${{ inputs.project_id }}.iam.gserviceaccount.com
85+
86+
- name: 🕰️ Create Cloud Scheduler
87+
shell: bash
88+
run: |
89+
for i in $(gcloud scheduler jobs list --location=us-central1 --uri); do
90+
gcloud scheduler jobs delete $i --quiet
91+
done
92+
gcloud scheduler jobs create http skinname-schedule \
93+
--description="Trigger the skinname-skid bot once a week on saturday evening" \
94+
--schedule="0 3 * * 1" \
95+
--time-zone=America/Denver \
96+
--location=us-central1 \
97+
--uri="https://us-central1-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${{ inputs.project_id }}/jobs/default:run" \
98+
--oauth-service-account-email=scheduler-sa@${{ inputs.project_id }}.iam.gserviceaccount.com
99+
100+
- name: 🙅 Pause Scheduler Job
101+
shell: bash
102+
if: inputs.pause_schedule_job != 'no'
103+
run: |
104+
gcloud scheduler jobs pause "skinname-schedule" --location=us-central1 --quiet

.github/dependabot.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: pip
4+
directory: /
5+
schedule:
6+
interval: monthly
7+
groups:
8+
safe-dependencies:
9+
update-types: ["minor", "patch"]
10+
major-dependencies:
11+
update-types: ["major"]
12+
commit-message:
13+
prefix: deps
14+
prefix-development: deps(dev)
15+
- package-ecosystem: github-actions
16+
directory: /
17+
schedule:
18+
interval: monthly
19+
groups:
20+
ci-dependencies:
21+
dependency-type: "production"

.github/workflows/pull_request.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Pull Request Events
2+
3+
on: pull_request
4+
5+
concurrency:
6+
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
7+
cancel-in-progress: true
8+
9+
jobs:
10+
test:
11+
name: Unit tests
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: ⬇️ Set up code
16+
uses: actions/checkout@v4
17+
with:
18+
show-progress: false
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version-file: .python-version
24+
cache: pip
25+
cache-dependency-path: setup.py
26+
27+
- name: Install libkrb5 for Kerberos on Linux
28+
run: |
29+
sudo apt-get update
30+
sudo apt-get install -y libkrb5-dev
31+
32+
- name: Install module
33+
run: pip install .[tests]
34+
35+
- name: 🧶 Lint
36+
run: ruff check --output-format=github .
37+
38+
- name: 🧪 Run pytest
39+
run: pytest

.github/workflows/push.yml

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Push Events
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- dev
8+
9+
concurrency:
10+
group: "${{ github.head_ref || github.ref }}"
11+
cancel-in-progress: true
12+
13+
jobs:
14+
release:
15+
name: Create release
16+
if: github.ref_name == 'main'
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: write
20+
pull-requests: write
21+
22+
steps:
23+
- name: 🚀 Create Release
24+
uses: agrc/release-composite-action@v1
25+
with:
26+
repo-token: ${{ secrets.GITHUB_TOKEN }}
27+
github-app-id: ${{ secrets.UGRC_RELEASE_BOT_APP_ID }}
28+
github-app-key: ${{ secrets.UGRC_RELEASE_BOT_APP_KEY }}
29+
github-app-name: ${{ secrets.UGRC_RELEASE_BOT_NAME }}
30+
github-app-email: ${{ secrets.UGRC_RELEASE_BOT_EMAIL }}
31+
release-type: python
32+
extra-files: src/skidname/version.py
33+
34+
deploy-dev:
35+
name: Deploy to Cloud Run (dev)
36+
runs-on: ubuntu-latest
37+
if: github.ref_name == 'dev'
38+
environment:
39+
name: dev
40+
permissions:
41+
id-token: write
42+
contents: read
43+
44+
steps:
45+
- name: ⬇️ Set up code
46+
uses: actions/checkout@v4
47+
with:
48+
show-progress: false
49+
50+
- name: 🚀 Deploy
51+
uses: ./.github/actions/deploy
52+
timeout-minutes: 15
53+
with:
54+
project_id: ${{ secrets.PROJECT_ID }}
55+
identity_provider: ${{ secrets.IDENTITY_PROVIDER }}
56+
service_account_email: ${{ secrets.SERVICE_ACCOUNT_EMAIL }}
57+
pause_schedule_job: "yes"
58+
github_token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Release Events
2+
on:
3+
release:
4+
types: [published]
5+
6+
jobs:
7+
deploy-prod:
8+
name: Deploy Prod
9+
runs-on: ubuntu-latest
10+
environment:
11+
name: prod
12+
permissions:
13+
id-token: write
14+
contents: read
15+
16+
steps:
17+
- name: ⬇️ Set up code
18+
uses: actions/checkout@v4
19+
20+
- name: 🚀 Deploy
21+
uses: ./.github/actions/deploy
22+
timeout-minutes: 15
23+
with:
24+
project_id: ${{ secrets.PROJECT_ID }}
25+
identity_provider: ${{ secrets.IDENTITY_PROVIDER }}
26+
service_account_email: ${{ secrets.SERVICE_ACCOUNT_EMAIL }}
27+
github_token: ${{ secrets.GITHUB_TOKEN }}
28+
29+
notify:
30+
name: Notifications
31+
runs-on: ubuntu-latest
32+
needs: deploy-prod
33+
permissions:
34+
contents: read
35+
pull-requests: write
36+
issues: write
37+
38+
steps:
39+
- name: Release Notifier
40+
uses: agrc/release-issue-notifications-action@v1
41+
with:
42+
repo-token: ${{ secrets.GITHUB_TOKEN }}

.gitignore

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
secrets.json
2+
sheets-sa.json
3+
4+
*.py[cod]
5+
6+
# Packages
7+
.eggs/
8+
*.egg
9+
*.egg-info
10+
dist
11+
build
12+
eggs
13+
parts
14+
bin
15+
var
16+
sdist
17+
develop-eggs
18+
.installed.cfg
19+
lib
20+
lib64
21+
__pycache__
22+
23+
# Installer logs
24+
pip-log.txt
25+
26+
*.pyt.xml
27+
*.csv.xml
28+
arc.dir
29+
.pytest_cache
30+
__pycache__
31+
32+
.env/
33+
.DS_Store
34+
cov.xml
35+
.coverage

.python-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.11

.vscode/extensions.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
3+
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
4+
// List of extensions which should be recommended for users of this workspace.
5+
"recommendations": [
6+
"editorconfig.editorconfig",
7+
"njpwerner.autodocstring",
8+
"ms-python.vscode-pylance",
9+
"ms-python.python",
10+
"donjayamanne.python-environment-manager",
11+
"charliermarsh.ruff",
12+
"tamasfe.even-better-toml"
13+
],
14+
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
15+
"unwantedRecommendations": []
16+
}

.vscode/settings.json

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"cSpell.words": [
3+
"accesstoken",
4+
"agrc",
5+
"arcgis",
6+
"arcpy",
7+
"Buildx",
8+
"cloudrun",
9+
"Codecov",
10+
"finditer",
11+
"getenv",
12+
"instafail",
13+
"libkrb",
14+
"mapserv",
15+
"metatable",
16+
"mssql",
17+
"ODBC",
18+
"oidc",
19+
"opensgid",
20+
"palletjack",
21+
"pgsql",
22+
"psycopg",
23+
"pygsheets",
24+
"pyodbc",
25+
"pytest",
26+
"rindex",
27+
"sgid",
28+
"skidname",
29+
"skinname",
30+
"UGRC",
31+
"venv",
32+
"worknote"
33+
],
34+
"editor.formatOnSave": true,
35+
"editor.rulers": [120],
36+
"coverage-gutters.showGutterCoverage": false,
37+
"coverage-gutters.showLineCoverage": true,
38+
"coverage-gutters.showRulerCoverage": false,
39+
"coverage-gutters.highlightdark": "rgb(61, 153, 112, .05)",
40+
"coverage-gutters.noHighlightDark": "rgb(255, 65, 54, .05)",
41+
"coverage-gutters.partialHighlightDark": "rgb(255, 133, 27, .05)",
42+
"python.languageServer": "Pylance",
43+
"python.testing.pytestEnabled": true,
44+
"python.testing.pytestArgs": ["--no-cov"],
45+
"editor.codeActionsOnSave": {
46+
"source.organizeImports": "explicit"
47+
},
48+
"[python]": {
49+
"editor.defaultFormatter": "charliermarsh.ruff",
50+
"editor.formatOnSave": true
51+
}
52+
}

0 commit comments

Comments
 (0)