11name : Build & Release AWSCLI-Addons
2- run-name : " Build & Release AWSCLI-Addons v${{ inputs.version || github.ref_name }} by @${{ github.actor }}"
2+ run-name : " Build & Release v${{ inputs.version || github.ref_name }} by @${{ github.actor }}"
33
44on :
55 push :
1616 type : boolean
1717 default : false
1818
19+ env :
20+ RAW_VERSION : ${{ inputs.version || github.ref_name }}
21+ REPO_URL : " https://github.com/${{ github.repository }}"
22+
1923permissions :
2024 contents : write
21- packages : write
22- actions : read
25+ # packages: write
26+ # actions: read
2327
2428
2529jobs :
26-
2730 check_version :
2831 name : " Check if Release Exists"
2932 runs-on : ubuntu-latest
3033 outputs :
31- should_run : ${{ steps.check .outputs.should_run }}
34+ clean_version : ${{ steps.version_logic .outputs.version }}
3235 steps :
33- - name : Checkout (minimal)
34- uses : actions/checkout@v4
35- with :
36- fetch-depth : 0
37-
38- - name : Check version availability
39- id : check
36+ - uses : actions/checkout@v4
37+ - name : Version & Availability Logic
38+ id : version_logic
4039 env :
4140 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
4241 run : |
43- VERSION="${{ inputs.version || github.ref_name }}"
44- # Check if release exists
45- if gh release view "$VERSION" >/dev/null 2>&1; then
46- if [ "${{ inputs.force }}" = "true" ]; then
47- echo "Release $VERSION exists but 'force' is true. Proceeding..."
48- echo "should_run=true" >> $GITHUB_OUTPUT
49- else
50- echo "::error::Release $VERSION already exists. Stopping to save build minutes."
51- echo "should_run=false" >> $GITHUB_OUTPUT
52- exit 1 # This stops the whole workflow immediately
53- fi
54- else
55- echo "should_run=true" >> $GITHUB_OUTPUT
42+ # Add 'v' only if it's missing
43+ [[ "$RAW_VERSION" == v* ]] && VERSION="$RAW_VERSION" || VERSION="v$RAW_VERSION"
44+
45+ # Validate Format (v1.2.3)
46+ if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
47+ echo "::error::Invalid format: $VERSION. Use 1.2.3 or v1.2.3"
48+ exit 1
5649 fi
5750
51+ # Check GitHub for existing release
52+ if gh release view "$VERSION" >/dev/null 2>&1 && [ "${{ inputs.force }}" != "true" ]; then
53+ echo "::error::Release $VERSION already exists. Re-run with 'force: true'."
54+ exit 1
55+ fi
56+
57+ # Export for other jobs
58+ echo "version=$VERSION" >> $GITHUB_OUTPUT
59+
5860 build :
5961 name : Build (${{ matrix.os }})
6062 needs : [check_version]
61- if : needs.check_version.outputs.should_run == 'true'
63+ env :
64+ VERSION : ${{ needs.check_version.outputs.clean_version }}
6265 runs-on : ${{ matrix.os }}
6366 strategy :
6467 matrix :
@@ -74,26 +77,20 @@ jobs:
7477
7578 - name : Detect OS and ARCH
7679 id : info
77- shell : bash
7880 run : |
79- # Detect OS (linux, darwin)
8081 OS=$(uname -s | tr '[:upper:]' '[:lower:]')
81-
82- # Detect Arch (amd64, arm64)
8382 ARCH=$(uname -m)
83+
8484 [ "$ARCH" == "x86_64" ] && ARCH="amd64"
8585 [ "$ARCH" == "aarch64" ] && ARCH="arm64"
8686
8787 # Set the output variable
8888 echo "artifact_name=awscli-addons-${OS}-${ARCH}" >> $GITHUB_OUTPUT
8989
9090
91- - name : Run Build Script
92- shell : bash
91+ - name : Build Binary
9392 run : |
94- VERSION="${{ github.event.inputs.version }}"
9593 ./tools/build.sh quick "${VERSION}"
96-
9794 # Move the binary to the unique name defined above
9895 mv dist/awscli-addons "dist/${{ steps.info.outputs.artifact_name }}"
9996
@@ -105,29 +102,16 @@ jobs:
105102
106103 release :
107104 name : Create Release
108- needs : [build]
105+ needs : [build, check_version]
106+ env :
107+ VERSION : ${{ needs.check_version.outputs.clean_version }}
109108 runs-on : ubuntu-latest
110109 steps :
111110 - name : Checkout code
112111 uses : actions/checkout@v4
113112 with :
114113 fetch-depth : 0
115114
116- - name : Check if Release Exists
117- id : check_release
118- shell : bash
119- env :
120- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
121- run : |
122- VERSION="${{ inputs.version || github.ref_name }}"
123- # Check via GitHub CLI
124- EXISTS=$(gh release view "$VERSION" --json tagName --jq '.tagName' 2>/dev/null || echo "not_found")
125-
126- if [ "$EXISTS" != "not_found" ] && [ "${{ inputs.force }}" != "true" ]; then
127- echo "::error::Release $VERSION already exists. Use 'force' input to overwrite."
128- exit 1 # Stops the job immediately if it exists and force is false
129- fi
130-
131115 - name : Download All Artifacts
132116 uses : actions/download-artifact@v4
133117 with :
@@ -141,27 +125,13 @@ jobs:
141125 sha256sum awscli-addons-* > checksums.txt
142126 cat checksums.txt
143127
144-
145128 - name : Create Manual Instructions
146129 id : manual_notes
147130 run : |
148- # 1. Handle Versioning (Input vs Tag)
149- if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
150- VERSION="${{ github.event.inputs.version }}"
151- TARGET_COMMIT="${{ github.sha }}"
152- else
153- VERSION="${GITHUB_REF#refs/tags/}"
154- TARGET_COMMIT="${VERSION}"
155- fi
156-
157- FILE_NAME="manual_notes.md"
158-
159- # 2. Get previous tag. If none exists, get the first commit
160- PREV_TAG=$(git describe --tags --abbrev=0 "${VERSION}^" 2>/dev/null || git rev-list --max-parents=0 HEAD)
131+ # Get previous tag. If none exists, get the first commit
132+ PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || git rev-list --max-parents=0 HEAD | tail -n 1)
161133
162- REPO_URL="https://github.com/${{ github.repository }}"
163-
164- cat > ${FILE_NAME} << EOF
134+ cat > manual_notes.md << EOF
165135 # 🚀 Release ${VERSION}
166136
167137 ## 📦 Installation
@@ -175,45 +145,52 @@ jobs:
175145 |----------|--------------|--------|
176146 | Linux | AMD64 | [awscli-addons-linux-amd64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-linux-amd64) |
177147 | Linux | ARM64 | [awscli-addons-linux-arm64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-linux-arm64) |
178- | macOS (Intel) | AMD64 | [awscli-addons-macos -amd64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-macos -amd64) |
179- | macOS (Apple Silicon) | ARM64 | [awscli-addons-macos -arm64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-macos -arm64) |
148+ | macOS (Intel) | AMD64 | [awscli-addons-darwin -amd64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-darwin -amd64) |
149+ | macOS (Apple Silicon) | ARM64 | [awscli-addons-darwin -arm64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-darwin -arm64) |
180150
181151 Download the appropriate binary for your platform and make it executable:
182152
183153 \`\`\`bash
184154 wget ${REPO_URL}/releases/download/${VERSION}/<Binary>
185- #or
186- curl ${REPO_URL}/releases/download/${VERSION}/<Binary>
187-
188155 chmod +x <Binary>
189156 sudo mv <Binary> /usr/local/bin/<Binary>
190157 \`\`\`
191158
192159 ## 🛡️ Verification
193160 \`\`\`bash
161+ # Linux
194162 sha256sum -c checksums.txt
163+
164+ # macOS
165+ shasum -a 256 -c checksums.txt
195166 \`\`\`
196167
197168 ## 📋 What's Changed
198169
199170 EOF
200-
201- # 3. Generate changelog between previous tag and current commit
202- git log ${PREV_TAG}..${TARGET_COMMIT} --oneline --pretty=format:"* %s (%h)" >> ${FILE_NAME}
171+ # Generate changelog between previous tag and current commit
172+ git log ${PREV_TAG}..HEAD --oneline --pretty=format:"* %s (%h)" >> manual_notes.md
173+
174+ - name : Force Update Git Tag
175+ id : update_tag
176+ if : github.event.inputs.force == 'true'
177+ run : |
178+ git config user.name "github-actions[bot]"
179+ git config user.email "github-actions[bot]@users.noreply.github.com"
180+ git tag -f "$VERSION"
181+ git push origin "$VERSION" --force
182+ env :
183+ GITHUB_TOKEN : ${{ secrets.PAT_TOKEN }}
203184
204185 - name : Publish Release
205- uses : softprops/action-gh-release@v1
186+ uses : softprops/action-gh-release@v2
206187 with :
207- tag_name : ${{ github.event.inputs.version || github.ref_name }}
188+ tag_name : ${{ env.VERSION }}
208189 body_path : manual_notes.md
209190 files : ./artifacts/*
210191 append_body : false
192+ overwrite : true
211193 generate_release_notes : true
212-
213- # LOGIC:
214- # 1. If 'force' is true, we don't force 'latest' (prevents old versions jumping to top).
215- # 2. If it's a new tag or a regular manual run, it becomes 'latest'.
216- # 3. 'legacy' tells GitHub to determine 'latest' based on date/semver automatically.
217194 make_latest : ${{ github.event.inputs.force == 'true' && 'legacy' || 'true' }}
218195 env :
219196 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments