feat: first release under versioning standard#681
Conversation
The legacy Location.csv has a SiteNames column that was never transferred into the ThingIdLink table. This left site_name null for all wells in the API response. The script reads SiteNames from the CSV and inserts NMBGMR ThingIdLink rows for all matched wells. It is idempotent and safe to re-run after future well transfers.
Org-only contacts (no personal name) were returning a null label in search results. Use c.name or c.organization so those contacts appear with their organization name instead of a blank title.
PointID is not unique across all rows in Location.csv (MB-1005 appears twice with different SiteNames). Switch to matching LocationId against Thing.nma_pk_location, which is the UUID primary key from NM_Aquifer and has higher fidelity. Suggested by jacob-a-brown in PR #668.
…ntact-Names Fall back to organization name for org-only contacts in search
…script BDMS-787 site_name script
Added Cerro MDWCA, White Oaks Pottery, and El Rito MDWCA sa organizations to support the well inventory ingestion on 2026-05-01.
…ations Add new organization terms for well inventory ingestion
Bumps [python-multipart](https://github.com/Kludex/python-multipart) from 0.0.26 to 0.0.27. - [Release notes](https://github.com/Kludex/python-multipart/releases) - [Changelog](https://github.com/Kludex/python-multipart/blob/main/CHANGELOG.md) - [Commits](Kludex/python-multipart@0.0.26...0.0.27) --- updated-dependencies: - dependency-name: python-multipart dependency-version: 0.0.27 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [mako](https://github.com/sqlalchemy/mako) from 1.3.11 to 1.3.12. - [Release notes](https://github.com/sqlalchemy/mako/releases) - [Changelog](https://github.com/sqlalchemy/mako/blob/main/CHANGES) - [Commits](https://github.com/sqlalchemy/mako/commits) --- updated-dependencies: - dependency-name: mako dependency-version: 1.3.12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.6.3 to 2.7.0. - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](urllib3/urllib3@2.6.3...2.7.0) --- updated-dependencies: - dependency-name: urllib3 dependency-version: 2.7.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [authlib](https://github.com/authlib/authlib) from 1.6.11 to 1.6.12. - [Release notes](https://github.com/authlib/authlib/releases) - [Changelog](https://github.com/authlib/authlib/blob/1.6.12/docs/changelog.rst) - [Commits](authlib/authlib@v1.6.11...1.6.12) --- updated-dependencies: - dependency-name: authlib dependency-version: 1.6.12 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
NO TICKET: Add new required env to .env.example
Bumps [idna](https://github.com/kjd/idna) from 3.11 to 3.15. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md) - [Commits](kjd/idna@v3.11...v3.15) --- updated-dependencies: - dependency-name: idna dependency-version: '3.15' dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ge of Hope, and WSP
…for-well-inventory-ingestion-20260526 feat(lexicon): add new organization terms in support of the 2026-05-26 well inventory ingestion
…679) Bumps the gha-minor-and-patch group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 6.0.2 to 6.0.3 - [Release notes](https://github.com/actions/checkout/releases) - [Commits](actions/checkout@v6.0.2...v6.0.3) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gha-minor-and-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Summary
Adopt the Data Services Versioning Standard on OcotilloAPI. Wires
release-please + tag-triggered deploy per spec §§5–10.
- Bump `pyproject.toml` to **1.0.0**, add
`.release-please-manifest.json` + `release-please-config.json`.
- Add `release-please` workflow watching `production` and `hotfix/v*`.
- Add `hotfix-start` workflow (`workflow_dispatch`) that branches
`hotfix/vX.Y.(Z+1)` off the latest (or specified) `v*.*.*` tag.
- Add PR title lint (Conventional Commits).
- Retarget `CD (Production)` to fire on `v*.*.*` tag push (no more
push-to-branch deploys); drop the self-tagging step; inject
`APP_VERSION` into App Engine env.
- Surface version: `Settings.version` reads `APP_VERSION` env, falls
back to `importlib.metadata.version("OcotilloAPI")`. Public OpenAPI uses
`settings.version` (was hardcoded `0.0.1`). New `/health` returns
`{status, version}`.
- Remove obsolete Sentry release workflow.
## Why
Implements the Data Services Versioning Standard. Pins the public
contract at **1.0.0** so SemVer rules engage going forward.
## Release flow after merge
1. Merge this PR to `staging` (CD Staging deploys to staging env as
usual).
2. Open separate `staging` -> `production` promotion PR when ready to
cut 1.0.0.
3. On merge to `production`, `release-please` opens a Release PR titled
`chore(production): release 1.0.0`.
4. Merge the Release PR -> `v1.0.0` tag + GitHub Release created
automatically.
5. Tag push fires `CD (Production)` -> Alembic migrations + App Engine
deploy.
## Follow-up (manual, not in this PR)
- Apply branch protection on `production` (required reviews + status
checks). Squash-only merge is already enforced at the repo level.
## Test plan
- [ ] CI: `pr-title-lint` passes.
- [ ] CI: `unit-tests` / `bdd-tests` pass against the new `/health`
endpoint + `settings.version` change.
- [ ] Local: `curl localhost:8000/health` returns
`{"status":"ok","version":"1.0.0"}`.
- [ ] After staging deploy: hit the staging `/health` and confirm
version field present.
- [ ] After staging -> production promotion: `release-please` Release PR
appears on `production`.
- [ ] After Release PR merge: `v1.0.0` tag exists, `CD (Production)`
succeeds, prod `/health` returns the tagged version.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f0e9ec9387
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| types: | | ||
| feat | ||
| fix | ||
| perf | ||
| docs | ||
| chore | ||
| refactor | ||
| test | ||
| ci | ||
| build | ||
| style | ||
| revert | ||
| deps |
There was a problem hiding this comment.
Allow generated Jira PR titles or update the generator
This new linter requires PR titles to start with one of these Conventional Commit types, but the existing .github/workflows/jira_codex_pr.yml still creates and edits automated PRs with titles like ${JIRA_KEY}: ${SUMMARY} (for example BDMS-123: ...). Those PRs will now fail this required check on open/synchronize unless the generator is changed to emit a feat:/fix: title or this workflow explicitly permits the Jira-title format.
Useful? React with 👍 / 👎.
| run: | | ||
| BASE="${{ inputs.base_tag }}" | ||
| if [ -z "$BASE" ]; then | ||
| BASE="$(git tag --list 'v*.*.*' --sort=-v:refname | head -n1)" |
There was a problem hiding this comment.
Ignore prerelease tags when choosing the hotfix base
When base_tag is omitted, this glob also matches prerelease tags such as v1.2.3-rc.1 and v1.2.3rc1; this same change adds prerelease tagging/deployment paths, so the newest matching tag can easily be an RC. In that case the next step parses PAT as a non-numeric value like 3-rc.1 and aborts with “not strict SemVer,” making the default hotfix workflow fail until a GA tag is supplied manually. Filter to strict vX.Y.Z tags before sorting/selecting the default.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This PR introduces the repository’s first release under a standardized versioning/release process, aligns runtime version reporting with build metadata, and adds a small operational endpoint while updating dependencies.
Changes:
- Introduces release automation via release-please (config + manifest + workflow) and adds PR title Conventional Commit linting.
- Updates runtime version reporting (settings/OpenAPI) and adds a public
/healthendpoint that returns{status, version}. - Adds a one-time transfer script to backfill NMBGMR site names into
ThingIdLink, plus dependency lockfile/version bumps and assorted CI workflow updates.
Reviewed changes
Copilot reviewed 20 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Updates lock revision, bumps project version to 1.0.0, and refreshes a few dependency versions. |
requirements.txt |
Updates pinned dependency versions/hashes to match the refreshed lock/deps. |
pyproject.toml |
Bumps project version to 1.0.0 and updates a few pinned dependencies. |
core/settings.py |
Derives app version from APP_VERSION env var or installed package metadata. |
core/app.py |
Uses settings.version for OpenAPI versioning and adds a public /health endpoint. |
api/search.py |
Improves contact search labels by falling back to organization when name is missing. |
core/lexicon.json |
Adds several organization terms. |
transfers/migrate_nmbgmr_site_names.py |
New one-time, idempotent migration script for NMBGMR site names into ThingIdLink. |
.release-please-manifest.json |
Initializes release-please manifest at 1.0.0. |
release-please-config.json |
Adds release-please configuration for Python releases and changelog sections. |
.github/workflows/release-please.yml |
Adds release-please automation on production / hotfix/v* branches. |
.github/workflows/pr-title-lint.yml |
Enforces Conventional Commits on PR titles for squash-merge driven releases. |
.github/workflows/release.yml |
Removes prior Sentry release workflow. |
.github/workflows/tests.yml |
Bumps actions/checkout patch version. |
.github/workflows/jira_codex_pr.yml |
Updates pinned actions/checkout SHA. |
.github/workflows/format_code.yml |
Bumps actions/checkout patch version. |
.github/workflows/CD_testing.yml |
Bumps actions/checkout and injects APP_VERSION into rendered configs. |
.github/workflows/CD_staging.yml |
Bumps actions/checkout and injects APP_VERSION into rendered configs. |
.github/workflows/CD_production.yml |
Switches deploy trigger from branch push to release tags and injects APP_VERSION (tag). |
.github/workflows/hotfix-start.yml |
Adds workflow to create hotfix branches from the latest release tag. |
.github/app.template.yaml |
Adds APP_VERSION env var into the deployed App Engine config template. |
.env.example |
Adds example PYGEOAPI Postgres credential variables. |
| # Skip rows that already exist (idempotent). | ||
| existing_keys: set[tuple[int, str, str]] = set( | ||
| session.execute( | ||
| select( | ||
| ThingIdLink.thing_id, | ||
| ThingIdLink.alternate_organization, | ||
| ThingIdLink.alternate_id, | ||
| ).where(ThingIdLink.alternate_organization == ALTERNATE_ORGANIZATION) | ||
| ).all() | ||
| ) | ||
| logger.info( | ||
| "%d NMBGMR ThingIdLink rows already in the database", len(existing_keys) | ||
| ) | ||
|
|
||
| rows_to_insert = [ | ||
| r | ||
| for r in candidates | ||
| if (r["thing_id"], r["alternate_organization"], r["alternate_id"]) | ||
| not in existing_keys | ||
| ] |
| "package-name": "OcotilloAPI", | ||
| "prerelease": true, | ||
| "prerelease-type": "rc" | ||
| } |
Why
This PR addresses the following problem / context:
How
Implementation summary - the following was changed / added / removed:
Notes
Any special considerations, workarounds, or follow-up work to note?