Skip to content

Add GitHub-Release-only CD for ci on main - #13

Merged
xnoto merged 2 commits into
mainfrom
ci/github-release-cd
Sep 2, 2026
Merged

Add GitHub-Release-only CD for ci on main#13
xnoto merged 2 commits into
mainfrom
ci/github-release-cd

Conversation

@xnoto

@xnoto xnoto commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds GitHub-Release-only CD to cflan and enforces an explicit changelog for every release and every pull request:

  • .github/workflows/release.yml triggers only on a completed, successful ci workflow run for a push to main (workflow_run), checks out the exact CI-tested head SHA, builds the wheel and sdist on Python 3.11, generates SHA256SUMS, and creates a GitHub Release tagged v<version> from pyproject.toml, targeting exactly the checked-out SHA.
  • The release body is exactly the ## [<version>] section of CHANGELOG.md, extracted at release time and passed to gh release create --notes-file. If that version heading or its content is absent, the job fails closed before any tag or release is created. --generate-notes is no longer used.
  • CHANGELOG.md is converted to a Keep-a-Changelog-style document with an empty ## Unreleased section and a ## [1.1.0] - 2026-09-02 section summarizing the already-merged 1.1.0 public-readiness and dry-run/test changes plus this CD change, in reader-ready Added/Changed sections.
  • ci.yml gains a changelog job that runs only for pull requests and fails unless CHANGELOG.md differs between the PR head SHA and base SHA, with a remediation message: every PR must add a user-facing Unreleased note, or promote it into a versioned section when increasing the version. All existing CI jobs are unchanged.
  • A repository-local .github/PULL_REQUEST_TEMPLATE.md (based on the organization template, every heading preserved, no HTML comments) adds a required ## Documentation and changelog checklist.
  • AGENTS.md, README.md, and CONTRIBUTING.md document the policy: every PR updates the changelog, a release version promotes Unreleased into [<version>], CD publishes only the exact versioned section, and release publication does not prove installation/host/DNS behavior.

Safety properties (unchanged or strengthened):

  • Least privilege: contents: write only on release; contents: read on ci; job if rejects PR and non-main CI runs; no manual dispatch.
  • Concurrency groups by source revision (release-<sha>) with cancel-in-progress: false.
  • Skips cleanly when the release for the tag already exists; fails closed when the tag exists without a release, and now also when the versioned changelog section is missing or empty — tags are never moved or reused for a different revision.

Type of change

  • CI / reusable workflow
  • Documentation

Documentation and changelog

  • CHANGELOG.md updated with a reader-ready, user-facing note under ## Unreleased — and the already-merged 1.1.0 notes are promoted into ## [1.1.0] - 2026-09-02, matching the current pyproject.toml version
  • When changing version in pyproject.toml, the Unreleased notes are promoted into a ## [<version>] - YYYY-MM-DD section — version is unchanged (1.1.0); the section for it is prepared by this PR
  • N/A

Validation

  • Required pull-request checks pass — ci (lint/test matrix, package build smoke test, mypy, and the new changelog enforcement job) is the authoritative validation for this PR; status reported in checks.
  • Generated or centrally distributed files were regenerated by their owning automation, not hand-edited — N/A; no generated files changed.

The release.yml workflow itself cannot execute until merged, because workflow_run triggers only fire for workflows present on the default branch; its trigger, gating, and notes extraction are therefore validated by review, not by a run. The new changelog CI job runs on this PR and validates itself against this PR's changelog change.

Impact and rollout

Self-contained repository change. After merge, the first successful ci run on main with version 1.1.0 will attempt to create GitHub Release v1.1.0 whose body is exactly the ## [1.1.0] - 2026-09-02 changelog section (skipped if the release already exists; fails closed if the tag exists without a release or the section is missing/empty). No PyPI, no deployment, no installed-host changes. Release publication is artifact publication only and does not prove installation, host, or DNS behavior.

Safety and secrets

  • Contains no plaintext secrets, decrypted SOPS values, state files, kubeconfigs, tokens, or private endpoints — changed text manually inspected; only ${{ github.token }} and the pre-existing ${{ secrets.CODECOV_TOKEN }} workflow expressions appear (Advanced Security secret scanning is not enabled on this repository, so automated scanning was unavailable).
  • No local OpenTofu init/plan/apply/destroy/import/state operations were run or claimed — plans come from pull-request checks
  • Breaking or irreversible effects are described above with rollback notes — none; rollback is deleting the workflow and template files.

This change was produced by an AI agent via the GitHub MCP.

- Add .github/workflows/release.yml: workflow_run on ci completion, gated
  to successful push runs on main, least-privilege contents:write,
  per-revision concurrency, checkout of the exact CI head SHA, Python 3.11
  build of wheel+sdist, SHA256SUMS generation, and gh release create
  targeting the checked-out SHA with generated notes.
- Skip cleanly when the release already exists; fail closed when the tag
  exists without a release so tags are never moved or reused.
- Document the CD lifecycle in README and CHANGELOG.
@xnoto
xnoto requested a review from a team as a code owner September 2, 2026 01:08
- Convert CHANGELOG.md to Keep-a-Changelog format with an empty
  Unreleased section and a versioned [1.1.0] - 2026-09-02 section.
- release.yml: extract exactly the versioned CHANGELOG section and use
  it as the GitHub Release body via gh release create --notes-file;
  fail closed before tag/release creation when the section is missing
  or empty.
- ci.yml: add a pull-request-only changelog job that fails unless
  CHANGELOG.md differs between the PR head and base SHAs.
- Add a repository-local pull request template with a required
  Documentation and changelog section.
- Document the policy in AGENTS.md, README.md, and CONTRIBUTING.md.
@xnoto
xnoto merged commit ce28939 into main Sep 2, 2026
7 checks passed
@xnoto
xnoto deleted the ci/github-release-cd branch September 2, 2026 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant