1- name : Create Release
1+ name : Build and Attach Release Binaries
22permissions :
33 contents : write
44
55on :
66 workflow_dispatch :
77 inputs :
8- version :
9- description : " Version to release (format: vX.Y.Z)"
8+ release_tag :
9+ description : " Release tag to attach binaries to (format: vX.Y.Z)"
1010 required : true
1111 type : string
12- is_production :
13- description : " Production release"
14- required : true
15- default : true
16- type : boolean
1712
1813jobs :
19- validate-release :
14+ validate-and-test :
2015 runs-on : ubuntu-latest
2116 outputs :
2217 major : ${{ steps.extract-version.outputs.major }}
@@ -26,10 +21,31 @@ jobs:
2621 - name : Checkout code
2722 uses : actions/checkout@v4
2823
24+ - name : Verify draft release exists
25+ env :
26+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
27+ run : |
28+ RELEASE_TAG="${{ github.event.inputs.release_tag }}"
29+
30+ # Check if release exists
31+ if ! gh release view "$RELEASE_TAG" > /dev/null 2>&1; then
32+ echo "::error::Release with tag $RELEASE_TAG does not exist"
33+ exit 1
34+ fi
35+
36+ # Check if it's a draft
37+ IS_DRAFT=$(gh release view "$RELEASE_TAG" --json isDraft -q .isDraft)
38+ if [ "$IS_DRAFT" != "true" ]; then
39+ echo "::error::Release $RELEASE_TAG is not a draft release"
40+ exit 1
41+ fi
42+
43+ echo "✓ Draft release $RELEASE_TAG found"
44+
2945 - name : Validate version format and extract components
3046 id : extract-version
3147 run : |
32- VERSION="${{ github.event.inputs.version }}"
48+ VERSION="${{ github.event.inputs.release_tag }}"
3349
3450 # Validate format (must be vX.Y.Z)
3551 if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
@@ -107,7 +123,7 @@ jobs:
107123 BINARY_OUTPUT=$(./mbvpn version)
108124
109125 # Expected output is single line: v0.0.9
110- EXPECTED_VERSION="${{ github.event.inputs.version }}"
126+ EXPECTED_VERSION="${{ github.event.inputs.release_tag }}"
111127
112128 # Trim any whitespace
113129 BINARY_OUTPUT=$(echo "$BINARY_OUTPUT" | tr -d '[:space:]')
@@ -125,83 +141,9 @@ jobs:
125141
126142 echo "✓ Binary version validation passed"
127143
128- - name : Validation summary
129- run : |
130- echo "======================================"
131- echo "Release Validation Summary"
132- echo "======================================"
133- echo "✓ Version format validated"
134- echo "✓ Source code version matches input"
135- echo "✓ Unit tests passed"
136- echo "✓ Build successful"
137- echo "✓ Binary version output validated"
138- echo ""
139- echo "Version: ${{ github.event.inputs.version }}"
140- echo "Ready to create release"
141- echo "======================================"
142-
143- create-release :
144- needs : validate-release
145- runs-on : ubuntu-latest
146- outputs :
147- MAJOR : ${{ needs.validate-release.outputs.major }}
148- MINOR : ${{ needs.validate-release.outputs.minor }}
149- PATCH : ${{ needs.validate-release.outputs.patch }}
150- steps :
151- - name : Checkout code
152- uses : actions/checkout@v4
153-
154- - name : Generate Release Notes
155- id : release-notes
156- run : |
157- VERSION="${{ github.event.inputs.version }}"
158-
159- # Get the previous tag
160- PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
161-
162- # Start building release notes
163- cat > release_notes.md << 'EOF'
164- ## What's Changed
165-
166- EOF
167-
168- # If we have a previous tag, generate changelog
169- if [ -n "$PREVIOUS_TAG" ]; then
170- # Add commit range link
171- echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREVIOUS_TAG}...${VERSION}" >> release_notes.md
172- echo "" >> release_notes.md
173-
174- # Get commits since last tag
175- git log ${PREVIOUS_TAG}..HEAD --pretty=format:"* %s by @%an in %H" --no-merges > commits.txt
176-
177- # Extract issue references and create proper links
178- while IFS= read -r line; do
179- # Replace commit hash with link
180- line=$(echo "$line" | sed -E "s/ in ([0-9a-f]{40})/ in [\1](https:\/\/github.com\/${{ github.repository }}\/commit\/\1)/")
181- # Replace issue references with links
182- line=$(echo "$line" | sed -E "s/#([0-9]+)/[#\1](https:\/\/github.com\/${{ github.repository }}\/issues\/\1)/g")
183- echo "$line" >> release_notes.md
184- done < commits.txt
185- else
186- echo "Initial release of MBVPN $VERSION" >> release_notes.md
187- fi
188-
189- echo "" >> release_notes.md
190- echo '```' >> release_notes.md
191-
192- - name : Create GitHub Release (Draft)
193- env :
194- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
195- run : |
196- gh release create ${{ github.event.inputs.version }} \
197- --title "MBVPN ${{ github.event.inputs.version }}" \
198- --notes-file release_notes.md \
199- --draft
200-
201144 build-binaries :
202- needs : create-release
145+ needs : validate-and-test
203146 runs-on : ubuntu-latest
204- environment : ${{ github.event.inputs.is_production == 'true' && 'prod' || 'stage' }}
205147 strategy :
206148 matrix :
207149 arch : [amd64, arm64, 386]
@@ -222,9 +164,9 @@ jobs:
222164
223165 - name : Build for ${{ matrix.os }}-${{ matrix.arch }}
224166 env :
225- VERSION_MAJOR : ${{ needs.create-release .outputs.MAJOR }}
226- VERSION_MINOR : ${{ needs.create-release .outputs.MINOR }}
227- VERSION_PATCH : ${{ needs.create-release .outputs.PATCH }}
167+ VERSION_MAJOR : ${{ needs.validate-and-test .outputs.major }}
168+ VERSION_MINOR : ${{ needs.validate-and-test .outputs.minor }}
169+ VERSION_PATCH : ${{ needs.validate-and-test .outputs.patch }}
228170 VERSION_BUILD : ${{ github.run_number }}
229171 run : |
230172 GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} task build-release
@@ -234,4 +176,4 @@ jobs:
234176 env :
235177 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
236178 run : |
237- gh release upload ${{ github.event.inputs.version }} ${{ env.BINARY_NAME }}
179+ gh release upload ${{ github.event.inputs.release_tag }} ${{ env.BINARY_NAME }}
0 commit comments