Skip to content

Fix release provenance, E2E cleanup race, and stale docs - #157

Open
ClaudiaFang wants to merge 1 commit into
mainfrom
ci/release-lifecycle-and-concurrency-fixes
Open

Fix release provenance, E2E cleanup race, and stale docs#157
ClaudiaFang wants to merge 1 commit into
mainfrom
ci/release-lifecycle-and-concurrency-fixes

Conversation

@ClaudiaFang

Copy link
Copy Markdown
Member

Summary

  • Split the release lifecycle: ci.yml's publish job (build → attest → semantic-release, all inline against the pre-tag commit) is replaced with release-metadata (semantic-release only — tag/changelog/GitHub Release shell entry, no build/attest/upload). A new release-build.yml, triggered by release: published, calls firstsun-dev/.github's obsidian-plugin-release-build.yml — the same shared workflow watermark-bucket-uploader already uses — to check out the exact tag, build once, attest, upload, and sha256-verify the upload. This fixes a real provenance gap: the old job attested github.sha, but @semantic-release/git tags a later chore(release): commit, so the attestation never actually corresponded to the released commit, and there was no upload-integrity verification at all.
  • .releaserc.json: dropped @semantic-release/github's assets config (upload now only happens in release-build.yml) and the stale feat/use-shared-workflow branch entry (confirmed gone via gh api).
  • Fixed a live race: e2e-pr-cleanup.yml/e2e-branch-cleanup.yml used concurrency group e2e-<branch>-<provider>, which no longer matches ci.yml's actual ci-<branch> group since ci.yml moved off per-provider groups — so cleanup no longer queued behind a live E2E run despite both files' comments claiming it did. A PR-close or branch-delete could delete an E2E namespace mid-run. Both now use ci-<branch> to genuinely match. (One caveat left as an explicit comment in e2e-branch-cleanup.yml: whether delete events' github.event.ref carries a refs/heads/ prefix couldn't be verified offline — flagged rather than silently assumed correct.)
  • Updated docs/testing/real-provider-e2e.md, which still described the old per-source/per-provider concurrency scheme and conflated job-level fork-gating (skipped) with step-level workflow_dispatch gating (success with skipped steps).

No changes to changes, gitea-e2e, provider-e2e, lint, unit-test, build, or required-checks — the E2E DAG itself is untouched.

Part of a cross-repo CI architecture review across firstsun-dev/.github, watermark-bucket-uploader, and git-files-sync. Companion PR: firstsun-dev/.github#19.

Test plan

  • python3 -c "import yaml,sys; yaml.safe_load(open(sys.argv[1]))" passed on all modified/new workflow YAML (done locally)
  • .releaserc.json parses as valid JSON (done locally)
  • Pre-commit hooks (lint + build) passed on this branch
  • End-to-end: merge, cut a real release, confirm release-metadata creates a tag with no assets, release-build.yml fires on release: published, and the resulting GitHub Release has main.js/manifest.json/styles.css with an attestation matching the exact tagged commit
  • Trigger a PR close / branch delete while a provider-e2e run is deliberately kept alive (keep_branch: true) to confirm cleanup now queues instead of racing

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_011zVvyzHgtk7C51dpi8CGrp

🤖 Generated with Claude Code

…eanup concurrency race, update stale docs

- Replace ci.yml's `publish` job (build+attest+semantic-release, all inline
  and pre-tag) with `release-metadata` (semantic-release only: tag,
  changelog, GitHub Release shell entry). The old job attested `github.sha`
  but semantic-release's `@semantic-release/git` plugin tags a *later*
  `chore(release):` commit -- the attestation never matched the actual
  released commit.
- Add `release-build.yml`, triggered by `release: published`, calling
  `firstsun-dev/.github`'s `obsidian-plugin-release-build.yml` (same
  pattern already used by watermark-bucket-uploader): checkout the exact
  tag, build once, attest, upload, and sha256-verify the uploaded bytes --
  none of which the old `publish` job did.
- Drop `@semantic-release/github`'s `assets` config in `.releaserc.json` --
  asset upload now happens only in `release-build.yml`, never from
  semantic-release itself. Also drop the stale `feat/use-shared-workflow`
  branch entry (confirmed via `gh api` to no longer exist).
- Fix `e2e-pr-cleanup.yml`/`e2e-branch-cleanup.yml`'s concurrency group:
  they used `e2e-<branch>-<provider>`, which no longer matches ci.yml's
  actual `ci-<branch>` group after ci.yml moved off per-provider groups --
  so cleanup no longer queued behind a live E2E run as their own comments
  claimed, letting a PR-close/branch-delete cleanup race a live
  provider-e2e run and delete its namespace mid-flight. Now both use
  `ci-<branch>` to genuinely match.
- Update docs/testing/real-provider-e2e.md, which still described the old
  per-source/per-provider concurrency scheme and conflated job-level
  fork-gating (skipped) with step-level workflow_dispatch gating (success
  with skipped steps).

Part of a cross-repo CI architecture review across firstsun-dev/.github,
watermark-bucket-uploader, and git-files-sync.
@sonarqubecloud

sonarqubecloud Bot commented Sep 2, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

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