Build & Release AWSCLI-Addons v3.1.3 by @MaksymLeus #18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build & Release AWSCLI-Addons | |
| run-name: "Build & Release AWSCLI-Addons v${{ inputs.version || github.ref_name }} by @${{ github.actor }}" | |
| on: | |
| push: | |
| tags: ['v*'] | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Release version (e.g., v1.2.3)' | |
| required: true | |
| type: string | |
| force: | |
| description: 'Force update existing release' | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: write | |
| packages: write | |
| actions: read | |
| jobs: | |
| check_version: | |
| name: "Check if Release Exists" | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_run: ${{ steps.check.outputs.should_run }} | |
| steps: | |
| - name: Checkout (minimal) | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check version availability | |
| id: check | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${{ inputs.version || github.ref_name }}" | |
| # Check if release exists | |
| if gh release view "$VERSION" >/dev/null 2>&1; then | |
| if [ "${{ inputs.force }}" = "true" ]; then | |
| echo "Release $VERSION exists but 'force' is true. Proceeding..." | |
| echo "should_run=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "::error::Release $VERSION already exists. Stopping to save build minutes." | |
| echo "should_run=false" >> $GITHUB_OUTPUT | |
| exit 1 # This stops the whole workflow immediately | |
| fi | |
| else | |
| echo "should_run=true" >> $GITHUB_OUTPUT | |
| fi | |
| build: | |
| name: Build (${{ matrix.os }}) | |
| needs: [check_version] | |
| if: needs.check_version.outputs.should_run == 'true' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| cache: 'pip' | |
| - name: Detect OS and ARCH | |
| id: info | |
| shell: bash | |
| run: | | |
| # Detect OS (linux, darwin) | |
| OS=$(uname -s | tr '[:upper:]' '[:lower:]') | |
| # Detect Arch (amd64, arm64) | |
| ARCH=$(uname -m) | |
| [ "$ARCH" == "x86_64" ] && ARCH="amd64" | |
| [ "$ARCH" == "aarch64" ] && ARCH="arm64" | |
| # Set the output variable | |
| echo "artifact_name=awscli-addons-${OS}-${ARCH}" >> $GITHUB_OUTPUT | |
| - name: Run Build Script | |
| shell: bash | |
| run: | | |
| VERSION="${{ github.event.inputs.version }}" | |
| ./tools/build.sh quick "${VERSION}" | |
| # Move the binary to the unique name defined above | |
| mv dist/awscli-addons "dist/${{ steps.info.outputs.artifact_name }}" | |
| - name: Upload Artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ steps.info.outputs.artifact_name }} | |
| path: dist/${{ steps.info.outputs.artifact_name }} | |
| release: | |
| name: Create Release | |
| needs: [build] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check if Release Exists | |
| id: check_release | |
| shell: bash | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| VERSION="${{ inputs.version || github.ref_name }}" | |
| # Check via GitHub CLI | |
| EXISTS=$(gh release view "$VERSION" --json tagName --jq '.tagName' 2>/dev/null || echo "not_found") | |
| if [ "$EXISTS" != "not_found" ] && [ "${{ inputs.force }}" != "true" ]; then | |
| echo "::error::Release $VERSION already exists. Use 'force' input to overwrite." | |
| exit 1 # Stops the job immediately if it exists and force is false | |
| fi | |
| - name: Download All Artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: ./artifacts | |
| pattern: awscli-addons-* | |
| merge-multiple: true | |
| - name: Generate checksums | |
| run: | | |
| cd artifacts | |
| sha256sum awscli-addons-* > checksums.txt | |
| cat checksums.txt | |
| - name: Create Manual Instructions | |
| id: manual_notes | |
| run: | | |
| # 1. Handle Versioning (Input vs Tag) | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| VERSION="${{ github.event.inputs.version }}" | |
| TARGET_COMMIT="${{ github.sha }}" | |
| else | |
| VERSION="${GITHUB_REF#refs/tags/}" | |
| TARGET_COMMIT="${VERSION}" | |
| fi | |
| FILE_NAME="manual_notes.md" | |
| # 2. Get previous tag. If none exists, get the first commit | |
| PREV_TAG=$(git describe --tags --abbrev=0 "${VERSION}^" 2>/dev/null || git rev-list --max-parents=0 HEAD) | |
| REPO_URL="https://github.com/${{ github.repository }}" | |
| cat > ${FILE_NAME} << EOF | |
| # 🚀 Release ${VERSION} | |
| ## 📦 Installation | |
| Install the latest binary for your system instantly: | |
| \`\`\`bash | |
| curl -sSL https://raw.githubusercontent.com/${{ github.repository }}/main/tools/installer.sh | bash | |
| \`\`\` | |
| ## 🏗️ Available Binaries | |
| | Platform | Architecture | Binary | | |
| |----------|--------------|--------| | |
| | Linux | AMD64 | [awscli-addons-linux-amd64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-linux-amd64) | | |
| | Linux | ARM64 | [awscli-addons-linux-arm64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-linux-arm64) | | |
| | macOS (Intel) | AMD64 | [awscli-addons-macos-amd64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-macos-amd64) | | |
| | macOS (Apple Silicon) | ARM64 | [awscli-addons-macos-arm64](${REPO_URL}/releases/download/${VERSION}/awscli-addons-macos-arm64) | | |
| Download the appropriate binary for your platform and make it executable: | |
| \`\`\`bash | |
| wget ${REPO_URL}/releases/download/${VERSION}/<Binary> | |
| #or | |
| curl ${REPO_URL}/releases/download/${VERSION}/<Binary> | |
| chmod +x <Binary> | |
| sudo mv <Binary> /usr/local/bin/<Binary> | |
| \`\`\` | |
| ## 🛡️ Verification | |
| \`\`\`bash | |
| sha256sum -c checksums.txt | |
| \`\`\` | |
| ## 📋 What's Changed | |
| EOF | |
| # 3. Generate changelog between previous tag and current commit | |
| git log ${PREV_TAG}..${TARGET_COMMIT} --oneline --pretty=format:"* %s (%h)" >> ${FILE_NAME} | |
| - name: Publish Release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.event.inputs.version || github.ref_name }} | |
| body_path: manual_notes.md | |
| files: ./artifacts/* | |
| append_body: false | |
| generate_release_notes: true | |
| # LOGIC: | |
| # 1. If 'force' is true, we don't force 'latest' (prevents old versions jumping to top). | |
| # 2. If it's a new tag or a regular manual run, it becomes 'latest'. | |
| # 3. 'legacy' tells GitHub to determine 'latest' based on date/semver automatically. | |
| make_latest: ${{ github.event.inputs.force == 'true' && 'legacy' || 'true' }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |