1616 IMAGE_NAME : thevibeworks/deva
1717
1818jobs :
19+ prepare :
20+ name : Prepare Release Metadata
21+ runs-on : ubuntu-latest
22+ outputs :
23+ release_tag : ${{ steps.release.outputs.release_tag }}
24+ steps :
25+ - name : Resolve release tag
26+ id : release
27+ shell : bash
28+ run : |
29+ set -euo pipefail
30+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
31+ release_tag="${{ github.event.inputs.tag }}"
32+ else
33+ release_tag="${GITHUB_REF#refs/tags/}"
34+ fi
35+ [ -n "$release_tag" ] || { echo "error: empty release tag" >&2; exit 1; }
36+ echo "release_tag=$release_tag" >> "$GITHUB_OUTPUT"
37+
38+ resolve-versions :
39+ name : Resolve Tool Versions
40+ runs-on : ubuntu-latest
41+ outputs :
42+ claude_code_version : ${{ steps.versions.outputs.claude_code_version }}
43+ codex_version : ${{ steps.versions.outputs.codex_version }}
44+ gemini_cli_version : ${{ steps.versions.outputs.gemini_cli_version }}
45+ atlas_cli_version : ${{ steps.versions.outputs.atlas_cli_version }}
46+ copilot_api_version : ${{ steps.versions.outputs.copilot_api_version }}
47+ steps :
48+ - name : Checkout
49+ uses : actions/checkout@v4
50+
51+ - name : Setup Node
52+ uses : actions/setup-node@v4
53+ with :
54+ node-version : " 22"
55+
56+ - name : Resolve versions
57+ id : versions
58+ env :
59+ GH_TOKEN : ${{ github.token }}
60+ run : bash ./scripts/resolve-tool-versions.sh
61+
62+ - name : Summary
63+ run : |
64+ cat <<EOF >> "$GITHUB_STEP_SUMMARY"
65+ ## Release Tool Versions
66+
67+ - Claude Code: \`${{ steps.versions.outputs.claude_code_version }}\`
68+ - Codex: \`${{ steps.versions.outputs.codex_version }}\`
69+ - Gemini CLI: \`${{ steps.versions.outputs.gemini_cli_version }}\`
70+ - Atlas CLI: \`${{ steps.versions.outputs.atlas_cli_version }}\`
71+ - Copilot API: \`${{ steps.versions.outputs.copilot_api_version }}\`
72+ EOF
73+
1974 build-and-push :
2075 name : Build and Push Docker Image
76+ needs : [prepare, resolve-versions]
2177 runs-on : ubuntu-latest
2278 permissions :
2379 contents : read
2480 packages : write
2581 steps :
2682 - name : Checkout
2783 uses : actions/checkout@v4
84+ with :
85+ ref : ${{ needs.prepare.outputs.release_tag }}
2886
2987 - name : Set up QEMU
3088 uses : docker/setup-qemu-action@v3
45103 with :
46104 images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
47105 tags : |
48- type=ref,event=tag
49- type=raw,value=latest,enable={{is_default_branch}}
106+ type=raw,value=${{ needs.prepare.outputs.release_tag }}
107+ type=raw,value=latest
50108
51109 - name : Build and push base image
52110 uses : docker/build-push-action@v5
@@ -59,17 +117,25 @@ jobs:
59117 labels : ${{ steps.meta.outputs.labels }}
60118 cache-from : type=gha
61119 cache-to : type=gha,mode=max
120+ build-args : |
121+ CLAUDE_CODE_VERSION=${{ needs.resolve-versions.outputs.claude_code_version }}
122+ CODEX_VERSION=${{ needs.resolve-versions.outputs.codex_version }}
123+ GEMINI_CLI_VERSION=${{ needs.resolve-versions.outputs.gemini_cli_version }}
124+ ATLAS_CLI_VERSION=${{ needs.resolve-versions.outputs.atlas_cli_version }}
125+ COPILOT_API_VERSION=${{ needs.resolve-versions.outputs.copilot_api_version }}
62126
63127 build-and-push-rust :
64128 name : Build and Push Rust Profile Image
65129 runs-on : ubuntu-latest
66- needs : build-and-push
130+ needs : [prepare, build-and-push]
67131 permissions :
68132 contents : read
69133 packages : write
70134 steps :
71135 - name : Checkout
72136 uses : actions/checkout@v4
137+ with :
138+ ref : ${{ needs.prepare.outputs.release_tag }}
73139
74140 - name : Set up QEMU
75141 uses : docker/setup-qemu-action@v3
90156 with :
91157 images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
92158 tags : |
93- type=ref,event=tag,suffix= -rust
94- type=raw,value=rust,enable={{is_default_branch}}
159+ type=raw,value=${{ needs.prepare.outputs.release_tag }} -rust
160+ type=raw,value=rust
95161
96162 - name : Build and push rust image
97163 uses : docker/build-push-action@v5
@@ -105,51 +171,33 @@ jobs:
105171 cache-from : type=gha
106172 cache-to : type=gha,mode=max
107173 build-args : |
108- BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
174+ BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.prepare.outputs.release_tag }}
109175
110176 release :
111177 name : Create GitHub Release
112178 runs-on : ubuntu-latest
113- needs : [build-and-push, build-and-push-rust]
179+ needs : [prepare, build-and-push, build-and-push-rust]
114180 permissions :
115181 contents : write
116182 steps :
117183 - name : Checkout
118184 uses : actions/checkout@v4
119185 with :
186+ ref : ${{ needs.prepare.outputs.release_tag }}
120187 fetch-depth : 0
121188
122- - name : Get version from tag
123- id : version
124- run : |
125- if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
126- echo "version=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
127- else
128- echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
129- fi
130-
131- - name : Update version in deva.sh
132- run : |
133- VERSION="${{ steps.version.outputs.version }}"
134- # Remove 'v' prefix if present
135- VERSION=${VERSION#v}
136- sed -i "s/^VERSION=.*/VERSION=\"$VERSION\"/" deva.sh
137- git config --local user.email "action@github.com"
138- git config --local user.name "GitHub Action"
139- git add deva.sh
140- git commit -m "Update version to $VERSION" || echo "No changes to commit"
141-
142189 - name : Generate release notes
143190 id : release_notes
191+ shell : bash
144192 run : |
145- # Get the previous tag
146- PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "")
193+ set -euo pipefail
194+ RELEASE_TAG="${{ needs.prepare.outputs.release_tag }}"
195+ PREVIOUS_TAG="$(git tag --sort=-version:refname | grep -Fxv "$RELEASE_TAG" | head -1 || true)"
147196
148- # Generate release notes
149197 if [ -n "$PREVIOUS_TAG" ]; then
150198 echo "## Changes since $PREVIOUS_TAG" > release_notes.md
151199 echo "" >> release_notes.md
152- git log --pretty=format:"- %s (%h)" $PREVIOUS_TAG..HEAD >> release_notes.md
200+ git log --pretty=format:"- %s (%h)" " $PREVIOUS_TAG..$RELEASE_TAG" >> release_notes.md
153201 else
154202 echo "## Initial Release" > release_notes.md
155203 echo "" >> release_notes.md
@@ -160,11 +208,11 @@ jobs:
160208 echo "## Docker Images" >> release_notes.md
161209 echo "" >> release_notes.md
162210 echo "**Base Profile (Python, Node, Go):**" >> release_notes.md
163- echo "- \`ghcr.io/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }} \`" >> release_notes.md
211+ echo "- \`ghcr.io/${{ env.IMAGE_NAME }}:$RELEASE_TAG \`" >> release_notes.md
164212 echo "- \`ghcr.io/${{ env.IMAGE_NAME }}:latest\`" >> release_notes.md
165213 echo "" >> release_notes.md
166214 echo "**Rust Profile (includes Rust toolchain):**" >> release_notes.md
167- echo "- \`ghcr.io/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version } }-rust\`" >> release_notes.md
215+ echo "- \`ghcr.io/${{ env.IMAGE_NAME }}:${RELEASE_TAG }-rust\`" >> release_notes.md
168216 echo "- \`ghcr.io/${{ env.IMAGE_NAME }}:rust\`" >> release_notes.md
169217 echo "" >> release_notes.md
170218 echo "## Supported Architectures" >> release_notes.md
@@ -175,8 +223,8 @@ jobs:
175223 - name : Create Release
176224 uses : softprops/action-gh-release@v1
177225 with :
178- tag_name : ${{ steps.version .outputs.version }}
179- name : Release ${{ steps.version .outputs.version }}
226+ tag_name : ${{ needs.prepare .outputs.release_tag }}
227+ name : Release ${{ needs.prepare .outputs.release_tag }}
180228 body_path : release_notes.md
181229 generate_release_notes : true
182230 append_body : true
0 commit comments