Skip to content

Commit f1dd621

Browse files
montfortclaude
andauthored
ci: align release workflows with unified tag-push trigger (#35)
Both workflows now follow the same pattern: - Trigger on tag push (fw-* or cli-*) + workflow_dispatch for re-runs - Verify version in source (dist-manifest.yml / Cargo.toml) matches tag - Create release automatically if it doesn't exist, or upload assets with --clobber if it does (fixes fw-4.0.0 duplicate release error) Framework workflow gains: version verification, workflow_dispatch, idempotent release creation. CLI workflow changes: trigger moved from release:published to tag push, removing the need to manually create releases before CI runs. Updated CLAUDE.md release procedures to reflect the simplified flow. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3bb44c3 commit f1dd621

3 files changed

Lines changed: 67 additions & 44 deletions

File tree

.github/workflows/release-cli.yml

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
name: Release CLI
22

33
on:
4-
# Trigger when a release with cli-* tag is published via GitHub UI or API
5-
release:
6-
types: [published]
7-
# Allow manual trigger (useful when release already exists without binaries)
4+
push:
5+
tags:
6+
- 'cli-*'
7+
# Allow manual trigger (useful for re-runs or when tag already exists)
88
workflow_dispatch:
99
inputs:
1010
tag:
11-
description: 'Release tag (e.g., cli-1.1.0)'
11+
description: 'Release tag (e.g., cli-3.0.0)'
1212
required: true
1313

1414
permissions:
@@ -25,36 +25,30 @@ jobs:
2525
outputs:
2626
tag: ${{ steps.resolve.outputs.tag }}
2727
version: ${{ steps.resolve.outputs.version }}
28-
should_run: ${{ steps.resolve.outputs.should_run }}
2928
steps:
3029
- name: Resolve tag and version
3130
id: resolve
3231
shell: bash
3332
run: |
34-
# Determine the tag from the trigger source
3533
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
3634
TAG="${{ github.event.inputs.tag }}"
3735
else
38-
TAG="${{ github.event.release.tag_name }}"
36+
TAG="${{ github.ref_name }}"
3937
fi
4038
41-
# Only process cli-* tags
4239
if [[ "$TAG" != cli-* ]]; then
43-
echo "Skipping: tag '$TAG' is not a CLI release"
44-
echo "should_run=false" >> "$GITHUB_OUTPUT"
45-
exit 0
40+
echo "ERROR: tag '$TAG' is not a CLI release (must start with cli-)"
41+
exit 1
4642
fi
4743
4844
VERSION="${TAG#cli-}"
4945
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
5046
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
51-
echo "should_run=true" >> "$GITHUB_OUTPUT"
5247
echo "Building CLI $VERSION from tag $TAG"
5348
5449
build-cli:
5550
name: Build CLI (${{ matrix.target }})
5651
needs: [resolve-version]
57-
if: needs.resolve-version.outputs.should_run == 'true'
5852
runs-on: ${{ matrix.os }}
5953
strategy:
6054
matrix:
@@ -142,15 +136,14 @@ jobs:
142136
find release-artifacts -type f \( -name "*.zip" -o -name "*.tar.gz" \) -exec cp {} release/ \;
143137
ls -la release/
144138
145-
- name: Upload to existing release or create new one
139+
- name: Create or update GitHub Release
146140
env:
147141
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
148142
shell: bash
149143
run: |
150144
TAG="${{ needs.resolve-version.outputs.tag }}"
151145
VERSION="${{ needs.resolve-version.outputs.version }}"
152146
153-
# Check if release already exists
154147
if gh release view "$TAG" > /dev/null 2>&1; then
155148
echo "Release $TAG exists, uploading binaries..."
156149
gh release upload "$TAG" release/* --clobber
@@ -159,5 +152,6 @@ jobs:
159152
gh release create "$TAG" \
160153
--title "DevTrail CLI $VERSION" \
161154
--generate-notes \
155+
--latest \
162156
release/*
163157
fi

.github/workflows/release-framework.yml

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ on:
44
push:
55
tags:
66
- 'fw-*'
7+
workflow_dispatch:
8+
inputs:
9+
tag:
10+
description: 'Release tag (e.g., fw-4.1.0)'
11+
required: true
712

813
permissions:
914
contents: write
@@ -14,12 +19,26 @@ jobs:
1419
runs-on: ubuntu-latest
1520
steps:
1621
- uses: actions/checkout@v5
22+
with:
23+
ref: ${{ github.event.inputs.tag || github.ref_name }}
1724

18-
- name: Extract version from tag
25+
- name: Resolve tag and version
1926
id: version
2027
run: |
21-
VERSION="${GITHUB_REF_NAME#fw-}"
28+
TAG="${{ github.event.inputs.tag || github.ref_name }}"
29+
VERSION="${TAG#fw-}"
30+
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
2231
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
32+
echo "Packaging Framework $VERSION from tag $TAG"
33+
34+
- name: Verify dist-manifest.yml version matches tag
35+
run: |
36+
MANIFEST_VERSION=$(grep '^version:' dist/dist-manifest.yml | sed 's/version: *"\(.*\)"/\1/')
37+
TAG_VERSION="${{ steps.version.outputs.version }}"
38+
if [ "$MANIFEST_VERSION" != "$TAG_VERSION" ]; then
39+
echo "ERROR: dist-manifest.yml version ($MANIFEST_VERSION) does not match tag version ($TAG_VERSION)"
40+
exit 1
41+
fi
2342
2443
- name: Create distribution ZIP
2544
run: |
@@ -29,11 +48,21 @@ jobs:
2948
zip -r "../devtrail-fw-${{ steps.version.outputs.version }}.zip" .
3049
cd ..
3150
32-
- name: Create GitHub Release
51+
- name: Create or update GitHub Release
3352
env:
3453
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3554
run: |
36-
gh release create "${{ github.ref_name }}" \
37-
--title "DevTrail Framework ${{ steps.version.outputs.version }}" \
38-
--generate-notes \
39-
"devtrail-fw-${{ steps.version.outputs.version }}.zip"
55+
TAG="${{ steps.version.outputs.tag }}"
56+
VERSION="${{ steps.version.outputs.version }}"
57+
ASSET="devtrail-fw-${VERSION}.zip"
58+
59+
if gh release view "$TAG" > /dev/null 2>&1; then
60+
echo "Release $TAG exists, uploading asset..."
61+
gh release upload "$TAG" "$ASSET" --clobber
62+
else
63+
echo "Creating release $TAG..."
64+
gh release create "$TAG" \
65+
--title "DevTrail Framework $VERSION" \
66+
--generate-notes \
67+
"$ASSET"
68+
fi

CLAUDE.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,40 +76,31 @@ git commit -m "chore: bump CLI version to X.Y.Z"
7676
# Push, create PR, merge to main
7777
```
7878

79-
### Step 3: Create GitHub release
79+
### Step 3: Create and push tag
8080

8181
```bash
82-
gh release create cli-X.Y.Z \
83-
--title "DevTrail CLI X.Y.Z" \
84-
--notes "Release notes here..." \
85-
--latest
82+
git tag cli-X.Y.Z
83+
git push origin cli-X.Y.Z
8684
```
8785

88-
### Step 4: CI builds binaries automatically
89-
90-
The `release-cli.yml` workflow triggers automatically when a release with a `cli-*` tag is published. It:
86+
The `release-cli.yml` workflow triggers automatically:
9187

92-
1. Compiles for 4 platforms in parallel:
88+
1. Verifies `Cargo.toml` version matches the tag
89+
2. Compiles for 4 platforms in parallel:
9390
- `x86_64-unknown-linux-gnu` (Ubuntu)
9491
- `x86_64-apple-darwin` (macOS Intel)
9592
- `aarch64-apple-darwin` (macOS ARM)
9693
- `x86_64-pc-windows-msvc` (Windows)
97-
2. Packages each as `.tar.gz` (Unix) or `.zip` (Windows)
98-
3. Uploads all binaries to the existing release
94+
3. Packages each as `.tar.gz` (Unix) or `.zip` (Windows)
95+
4. Creates the GitHub release and uploads all binaries
9996

100-
**If CI doesn't trigger** (e.g., release was created before workflow was merged), run manually:
97+
**If CI needs re-running**, trigger manually:
10198

10299
```bash
103100
gh workflow run release-cli.yml -f tag=cli-X.Y.Z
104101
```
105102

106-
### Step 5: Delete old release (optional)
107-
108-
```bash
109-
gh release delete cli-OLD.VERSION --yes
110-
```
111-
112-
### Step 6: Verify
103+
### Step 4: Verify
113104

114105
```bash
115106
gh release view cli-X.Y.Z --json assets --jq '.assets[].name'
@@ -135,6 +126,8 @@ Update version references in docs:
135126
- `README.md` and `docs/i18n/es/README.md` (versioning tables)
136127
- `dist/.devtrail/00-governance/QUICK-REFERENCE.md` (EN + ES footer)
137128
- `dist/.devtrail/00-governance/AGENT-RULES.md` (EN + ES footer)
129+
- `dist/.devtrail/00-governance/DOCUMENTATION-POLICY.md` (EN + ES footer)
130+
- `dist/.devtrail/00-governance/C4-DIAGRAM-GUIDE.md` (EN + ES footer)
138131

139132
### Step 2: Commit and merge
140133

@@ -153,8 +146,15 @@ git push origin fw-X.Y.Z
153146
```
154147

155148
The `release-framework.yml` workflow triggers automatically:
156-
1. Packages `dist/` contents into `devtrail-fw-X.Y.Z.zip`
157-
2. Creates the GitHub release with the ZIP as asset
149+
1. Verifies `dist-manifest.yml` version matches the tag
150+
2. Packages `dist/` contents into `devtrail-fw-X.Y.Z.zip`
151+
3. Creates the GitHub release with the ZIP as asset
152+
153+
**If CI needs re-running**, trigger manually:
154+
155+
```bash
156+
gh workflow run release-framework.yml -f tag=fw-X.Y.Z
157+
```
158158

159159
### Step 4: Verify
160160

0 commit comments

Comments
 (0)