Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
34 changes: 34 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Release

on:
push:
tags:
- 'v[0-9]*'

# Least-privilege: this phase (T008) only validates the tag against the
# workspace version, no build/package/checksum/publish work yet (that's
# T009-T012). `contents: write` is what release *creation* will eventually
# need; nothing broader is required at any point in this workflow.
permissions:
contents: write
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated

jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Unlike ci.yml's shallow default: T014's release-notes script
# needs full tag/commit history to run `git describe` against
# previous tags.
fetch-depth: 0
# No authenticated git operations happen after checkout in this
# phase; a later phase that needs to authenticate (e.g. `gh
# release create`) does so via an explicit token, not a
# persisted git credential.
persist-credentials: false

- name: Validate release tag against workspace version (FR-002, FR-004, FR-010)
run: .github/scripts/validate-release-tag.sh "${GITHUB_REF_NAME}"
15 changes: 14 additions & 1 deletion specs/005-ci-release-versioning/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,27 @@ created with the packaged CLI binary attached.

### Implementation for User Story 2

- [ ] **T008** [US2] Create `.github/workflows/release.yml` triggered on
- [x] **T008** [US2] Create `.github/workflows/release.yml` triggered on
SemVer tag pushes (`v[0-9]*`), least-privilege `permissions:` including
`contents: write` for release creation, actions pinned per T001's
convention. **Checkout step MUST use `fetch-depth: 0`** (full history) —
unlike `ci.yml`'s shallow default, T014's release-notes script needs full
tag/commit history to run `git describe` against previous tags. Calls
T005's version/tag validation as its first real step — fails fast before
any build/package work on mismatch (FR-002, FR-004, FR-010, SC-006).
**Done 2026-08-13**: `.github/workflows/release.yml` — triggers on
`v[0-9]*` tag pushes, `contents: write` only, pinned `actions/checkout`
matching `ci.yml`'s SHA, `fetch-depth: 0` + `persist-credentials: false`.
Its only step beyond checkout calls `validate-release-tag.sh` against
`$GITHUB_REF_NAME` (a plain env-var expansion inside `run:`, not a
`${{ }}` template interpolation, to avoid the tag-name shell-injection
footgun that pattern has). Verified: YAML parses (Ruby's `Psych`, no
`pyyaml` available locally); `validate-release-tag.sh` itself already has
fixture tests (T005) and was re-run manually against this repo's real
`Cargo.toml` version for both a matching and a mismatched tag. Build,
packaging, checksums, and the atomic release-creation step are separate
tasks (T009-T012) — this workflow does nothing on a real tag push yet
beyond validating it.
- [ ] **T009** [US2] Build the `iklo` executable in release mode
(`cargo build --release -p iklo-cli`) only after `make test` passes
(FR-002).
Expand Down