Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/app.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ handlers:
env_variables:
MODE: "production"
ENVIRONMENT: "${ENVIRONMENT}"
APP_VERSION: "${APP_VERSION}"
DB_DRIVER: "cloudsql"
Comment thread
jirhiker marked this conversation as resolved.
CLOUD_SQL_INSTANCE_NAME: "${CLOUD_SQL_INSTANCE_NAME}"
CLOUD_SQL_DATABASE: "${CLOUD_SQL_DATABASE}"
Expand Down
20 changes: 6 additions & 14 deletions .github/workflows/CD_production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ name: CD (Production)

on:
push:
branches: [production]
tags:
- 'v*.*.*' # GA releases: v1.0.0, v1.4.2
- 'v*.*.*-*' # SemVer pre-releases: v1.0.0-rc.1
- 'v*.*.*[a-z]*' # PEP 440 pre-releases: v1.0.0rc1, v1.0.0b2 (release-please-python form)
Comment on lines +5 to +8

permissions:
contents: write
contents: read

jobs:
production-deploy:
Expand Down Expand Up @@ -66,6 +69,7 @@ jobs:

- name: Render App Engine configs
env:
APP_VERSION: ${{ github.ref_name }}
ENVIRONMENT: "production"
CLOUD_SQL_INSTANCE_NAME: "${{ secrets.CLOUD_SQL_INSTANCE_NAME }}"
CLOUD_SQL_DATABASE: "${{ vars.CLOUD_SQL_DATABASE }}"
Expand Down Expand Up @@ -141,15 +145,3 @@ jobs:
- name: Remove rendered configs
run: |
rm app.yaml

# Use PR author's username as git user name
- name: Set up git user
run: |
git config --global user.name "${{ github.actor }}"
git config --global user.email "${{ github.actor }}@users.noreply.github.com"

# ":" are not alloed in git tags, so replace with "-"
- name: Tag commit
run: |
git tag -a "production-deploy-$(date -u +%Y-%m-%d)T$(date -u +%H-%M-%S%z)" -m "production gcloud deployment: $(date -u +%Y-%m-%d)T$(date -u +%H:%M:%S%z)"
git push origin --tags
1 change: 1 addition & 0 deletions .github/workflows/CD_staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:

- name: Render App Engine configs
env:
APP_VERSION: "${{ github.ref_name }}-${{ github.sha }}"
ENVIRONMENT: "staging"
CLOUD_SQL_INSTANCE_NAME: "${{ secrets.CLOUD_SQL_INSTANCE_NAME }}"
CLOUD_SQL_DATABASE: "${{ vars.CLOUD_SQL_DATABASE }}"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/CD_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:

- name: Render App Engine configs
env:
APP_VERSION: "${{ github.ref_name }}-${{ github.sha }}"
ENVIRONMENT: "staging"
CLOUD_SQL_INSTANCE_NAME: "${{ secrets.CLOUD_SQL_INSTANCE_NAME }}"
CLOUD_SQL_DATABASE: "${{ vars.CLOUD_SQL_DATABASE }}"
Expand Down
90 changes: 90 additions & 0 deletions .github/workflows/hotfix-start.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: hotfix-start

# Creates a hotfix branch off a release tag per the Data Services Versioning
# Standard §10. Workflow:
# 1. Run this workflow (optionally pin base_tag; default = latest v*.*.*).
# 2. Push fix commit(s) to the new hotfix/vX.Y.(Z+1) branch via PR.
# 3. release-please opens a Release PR on the hotfix branch.
# 4. Merge it -> tag vX.Y.(Z+1) -> CD (Production) deploys.
# 5. Open a forward-merge PR from hotfix/vX.Y.(Z+1) back into production.

on:
workflow_dispatch:
inputs:
base_tag:
description: 'Release tag to branch from (e.g. v1.4.2). Empty = latest v*.*.* tag.'
required: false
type: string

permissions:
contents: write

jobs:
create-hotfix-branch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
with:
fetch-depth: 0

- name: Resolve base tag
id: base
run: |
BASE="${{ inputs.base_tag }}"
if [ -z "$BASE" ]; then
BASE="$(git tag --list 'v*.*.*' --sort=-v:refname | head -n1)"
fi
Comment on lines +34 to +36
if [ -z "$BASE" ]; then
echo "No release tag found (expected v*.*.* tags)." >&2
exit 1
fi
if ! git rev-parse -q --verify "refs/tags/$BASE" >/dev/null; then
echo "Tag $BASE not found in repo." >&2
exit 1
fi
echo "tag=$BASE" >> "$GITHUB_OUTPUT"

- name: Compute next PATCH version + branch name
id: next
run: |
BASE="${{ steps.base.outputs.tag }}"
VER="${BASE#v}"
IFS='.' read -r MAJ MIN PAT <<<"$VER"
if ! [[ "$MAJ" =~ ^[0-9]+$ && "$MIN" =~ ^[0-9]+$ && "$PAT" =~ ^[0-9]+$ ]]; then
echo "Base tag $BASE is not strict SemVer vX.Y.Z." >&2
exit 1
fi
NEXT_VER="${MAJ}.${MIN}.$((PAT+1))"
BRANCH="hotfix/v${NEXT_VER}"
echo "version=${NEXT_VER}" >> "$GITHUB_OUTPUT"
echo "branch=${BRANCH}" >> "$GITHUB_OUTPUT"

- name: Guard against existing branch
run: |
if git ls-remote --exit-code --heads origin "${{ steps.next.outputs.branch }}" >/dev/null 2>&1; then
echo "Branch ${{ steps.next.outputs.branch }} already exists on origin. Aborting." >&2
exit 1
fi

- name: Create + push hotfix branch
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "${{ steps.next.outputs.branch }}" "${{ steps.base.outputs.tag }}"
git push origin "${{ steps.next.outputs.branch }}"

- name: Summary
run: |
{
echo "### Hotfix branch ready"
echo ""
echo "- Base tag: \`${{ steps.base.outputs.tag }}\`"
echo "- New branch: \`${{ steps.next.outputs.branch }}\`"
echo "- Target version: \`v${{ steps.next.outputs.version }}\`"
echo ""
echo "Next steps:"
echo "1. Open a fix PR targeting \`${{ steps.next.outputs.branch }}\` (Conventional Commit title, \`fix:\` prefix)."
echo "2. After merge, release-please will open a Release PR on the hotfix branch."
echo "3. Merge the Release PR -> tag \`v${{ steps.next.outputs.version }}\` -> CD (Production) deploys."
echo "4. Open a forward-merge PR \`${{ steps.next.outputs.branch }}\` -> \`production\`."
} >> "$GITHUB_STEP_SUMMARY"
38 changes: 38 additions & 0 deletions .github/workflows/pr-title-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: pr-title-lint

# Enforces Conventional Commits on PR titles so squash-merged commits drive
# release-please correctly. See Data Services Versioning Standard §7.

on:
pull_request:
types: [opened, edited, reopened, synchronize]

permissions:
pull-requests: read

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
perf
docs
chore
refactor
test
ci
build
style
revert
deps
requireScope: false
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
PR title subject must start with a lowercase letter.
Example: `feat: add /wells/{id}/assets endpoint`
21 changes: 21 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: release-please

on:
push:
branches:
- production
- 'hotfix/v*'

permissions:
contents: write
pull-requests: write

jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
target-branch: ${{ github.ref_name }}
26 changes: 0 additions & 26 deletions .github/workflows/release.yml

This file was deleted.

3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "1.0.0"
}
7 changes: 6 additions & 1 deletion core/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def full_openapi():
def public_openapi():
schema = get_openapi(
title="Ocotillo API (Public)",
version="0.0.1",
version=settings.version,
description="Public API schema (anonymous users)",
routes=app.routes,
)
Expand Down Expand Up @@ -218,6 +218,11 @@ async def swagger_ui_redirect():
async def warmup():
return {"status": "ok"}

@app.get("/health", tags=["meta"])
@public_route
async def health():
return {"status": "ok", "version": settings.version}
Comment thread
jirhiker marked this conversation as resolved.
Comment thread
jirhiker marked this conversation as resolved.
Comment thread
jirhiker marked this conversation as resolved.
Comment on lines +221 to +224

return app


Expand Down
13 changes: 12 additions & 1 deletion core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@
# limitations under the License.
# ===============================================================================
import os
from importlib.metadata import PackageNotFoundError, version as _pkg_version


def _resolve_version() -> str:
env = os.getenv("APP_VERSION")
if env:
return env.removeprefix("v")
try:
return _pkg_version("OcotilloAPI")
except PackageNotFoundError:
return "0.0.0"


class Settings:
version = "0.0.1"
version = _resolve_version()

def __init__(self):
self.mode = os.getenv("MODE", "") # Default mode
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "OcotilloAPI"
version = "0.1.0"
version = "1.0.0"
Comment thread
jirhiker marked this conversation as resolved.
description = "FastAPI backend and CLI for managing Ocotillo groundwater locations, wells, assets, and bulk water-level data transfers."
readme = "README.md"
requires-python = ">=3.13"
Expand Down
29 changes: 29 additions & 0 deletions release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"release-type": "python",
"include-v-in-tag": true,
"include-component-in-tag": false,
"bump-minor-pre-major": false,
"bump-patch-for-minor-pre-major": false,
"changelog-sections": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "perf", "section": "Performance" },
{ "type": "deps", "section": "Dependencies" },
{ "type": "revert", "section": "Reverts" },
{ "type": "docs", "section": "Documentation", "hidden": true },
{ "type": "chore", "section": "Chores", "hidden": true },
{ "type": "refactor", "section": "Refactors", "hidden": true },
{ "type": "test", "section": "Tests", "hidden": true },
{ "type": "build", "section": "Build", "hidden": true },
{ "type": "ci", "section": "CI", "hidden": true },
{ "type": "style", "section": "Style", "hidden": true }
],
"packages": {
".": {
"package-name": "OcotilloAPI",
"prerelease": true,
"prerelease-type": "rc"
}
Comment on lines +23 to +27
Comment on lines +23 to +27
}
}
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading