fix: pin GitHub Actions to full SHA (CLOUDEVOPS-4942) (#234) #214
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: Release | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| packages: write | |
| id-token: write | |
| pull-requests: write # Needed to create PRs | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: '20' | |
| registry-url: 'https://registry.npmjs.org' | |
| - run: npm install | |
| # Check if package-lock.json has changed | |
| - name: Check for package-lock.json changes | |
| id: check_lockfile | |
| run: | | |
| git diff --exit-code package-lock.json || echo "lockfile_changed=true" >> $GITHUB_OUTPUT | |
| # Create PR for lockfile if changed | |
| - name: Create PR for lockfile updates | |
| if: steps.check_lockfile.outputs.lockfile_changed == 'true' | |
| run: | | |
| # Configure Git | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| # Create a new branch | |
| BRANCH_NAME="lockfile-update-$(date +%Y%m%d%H%M%S)" | |
| git checkout -b $BRANCH_NAME | |
| # Commit changes | |
| git add package-lock.json | |
| git commit -m "chore: update package-lock.json" | |
| # Push the branch | |
| git push --set-upstream origin $BRANCH_NAME | |
| # Create PR | |
| gh pr create --title "Update package-lock.json" \ | |
| --body "This PR updates the package-lock.json file to resolve dependency conflicts. Please merge this before publishing." \ | |
| --label "dependencies" | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build all packages | |
| if: steps.check_lockfile.outputs.lockfile_changed != 'true' | |
| run: npm run build:all | |
| # NEW: Build MCPB packages after NPM packages are built | |
| - name: Build MCPB packages | |
| if: steps.check_lockfile.outputs.lockfile_changed != 'true' | |
| run: | | |
| echo "ποΈ Building MCPB packages..." | |
| # Build MCPB packages (MCPB CLI should be installed as dev dependency) | |
| npm run build:mcpb || echo "β οΈ MCPB build failed, continuing with NPM publishing" | |
| # List what was built | |
| if [ -d "mcpb-builds" ]; then | |
| echo "π¦ Built MCPB packages:" | |
| find mcpb-builds -name "*.mcpb" -type f | while read mcpb_file; do | |
| echo " $(basename "$mcpb_file")" | |
| done | |
| else | |
| echo "β οΈ No MCPB packages were built" | |
| fi | |
| - name: Create Release Pull Request or Publish | |
| if: steps.check_lockfile.outputs.lockfile_changed != 'true' | |
| id: changesets | |
| uses: changesets/action@6a0a831ff30acef54f2c6aa1cbbc1096b066edaf # v1 | |
| with: | |
| # This script runs ONLY when publishing (Phase 2) | |
| publish: npm run release | |
| createGithubReleases: true | |
| # This script runs ONLY when creating version PR (Phase 1) | |
| version: npm run version | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| NPM_CONFIG_PROVENANCE: true | |
| # NEW: Create MCPB Release (only when packages are actually published) | |
| - name: Create MCPB Release | |
| if: steps.check_lockfile.outputs.lockfile_changed != 'true' && steps.changesets.outputs.published == 'true' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Check if we have MCPB packages to release | |
| if [ ! -d "mcpb-builds" ] || [ -z "$(find mcpb-builds -name "*.mcpb" -type f)" ]; then | |
| echo "β οΈ No MCPB packages found to release" | |
| exit 0 | |
| fi | |
| # Generate version tag based on timestamp and commit | |
| VERSION_TAG="mcpb-$(date +'%Y.%m.%d-%H%M')-$(git rev-parse --short HEAD)" | |
| echo "π·οΈ Creating release: $VERSION_TAG" | |
| # Prepare release assets | |
| mkdir -p release-assets | |
| find mcpb-builds -name "*.mcpb" -type f | while read mcpb_file; do | |
| filename=$(basename "$mcpb_file") | |
| # Copy the MCPB file | |
| cp "$mcpb_file" "release-assets/$filename" | |
| echo "β Prepared: $filename" | |
| done | |
| # Create release notes | |
| echo "# MCPB Packages Release" > release-notes.md | |
| echo "" >> release-notes.md | |
| echo "## π¦ Claude Desktop Extensions (MCPB)" >> release-notes.md | |
| echo "" >> release-notes.md | |
| echo "Built from public release workflow." >> release-notes.md | |
| echo "" >> release-notes.md | |
| # Add package list to release notes | |
| for mcpb_file in release-assets/*.mcpb; do | |
| if [ -f "$mcpb_file" ]; then | |
| filename=$(basename "$mcpb_file") | |
| package_name=$(echo "$filename" | sed 's/\.mcpb$//') | |
| echo "- **${package_name}**: \`${filename}\`" >> release-notes.md | |
| fi | |
| done | |
| # Add stable URLs section | |
| echo "" >> release-notes.md | |
| echo "### π₯ Stable URLs" >> release-notes.md | |
| echo "" >> release-notes.md | |
| echo "For consistent download links that always point to the newest version:" >> release-notes.md | |
| echo "" >> release-notes.md | |
| # Add stable download links | |
| for mcpb_file in release-assets/*.mcpb; do | |
| if [ -f "$mcpb_file" ]; then | |
| filename=$(basename "$mcpb_file") | |
| package_name=$(echo "$filename" | sed 's/\.mcpb$//') | |
| latest_url="https://github.com/${{ github.repository }}/releases/latest/download/$filename" | |
| echo "- **${package_name}**: [\`${filename}\`]($latest_url)" >> release-notes.md | |
| fi | |
| done | |
| # Add installation and build info | |
| echo "" >> release-notes.md | |
| echo "## Installation" >> release-notes.md | |
| echo "" >> release-notes.md | |
| echo "1. Download the \`.mcpb\` file for the package you want to install" >> release-notes.md | |
| echo "2. Open Claude Desktop" >> release-notes.md | |
| echo "3. Go to Extensions/Plugins" >> release-notes.md | |
| echo "4. Install the downloaded \`.mcpb\` file" >> release-notes.md | |
| echo "" >> release-notes.md | |
| echo "## Build Info" >> release-notes.md | |
| echo "" >> release-notes.md | |
| echo "- **Commit**: \`${{ github.sha }}\`" >> release-notes.md | |
| echo "- **Branch**: \`${{ github.ref_name }}\`" >> release-notes.md | |
| echo "- **Timestamp**: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> release-notes.md | |
| echo "- **Workflow**: Public Release" >> release-notes.md | |
| # Create the release (mark as latest only if on main branch) | |
| if [ "${{ github.ref_name }}" = "main" ]; then | |
| echo "π― Creating stable release (main branch)" | |
| gh release create "$VERSION_TAG" \ | |
| --title "MCPB Packages - $VERSION_TAG" \ | |
| --notes-file release-notes.md \ | |
| --latest | |
| else | |
| echo "π§ Creating prerelease (branch: ${{ github.ref_name }})" | |
| gh release create "$VERSION_TAG" \ | |
| --title "MCPB Packages - $VERSION_TAG (Branch: ${{ github.ref_name }})" \ | |
| --notes-file release-notes.md \ | |
| --prerelease | |
| fi | |
| # Upload MCPB files individually | |
| for mcpb_file in release-assets/*.mcpb; do | |
| if [ -f "$mcpb_file" ]; then | |
| filename=$(basename "$mcpb_file") | |
| echo "π Uploading: $filename" | |
| gh release upload "$VERSION_TAG" "$mcpb_file" --clobber | |
| echo "β Uploaded: $filename" | |
| fi | |
| done | |
| # Verify latest URLs work (only for main branch releases) | |
| if [ "${{ github.ref_name }}" = "main" ]; then | |
| echo "π Verifying latest download URLs..." | |
| sleep 10 # Give GitHub a moment to process the release | |
| for mcpb_file in release-assets/*.mcpb; do | |
| if [ -f "$mcpb_file" ]; then | |
| filename=$(basename "$mcpb_file") | |
| latest_url="https://github.com/${{ github.repository }}/releases/latest/download/$filename" | |
| echo "π Testing URL: $latest_url" | |
| if curl -I "$latest_url" 2>/dev/null | grep -q "200 OK"; then | |
| echo "β Latest URL works: $filename" | |
| else | |
| echo "β οΈ Latest URL not ready yet: $filename (this may be normal immediately after release creation)" | |
| fi | |
| fi | |
| done | |
| fi | |
| # Add to summary | |
| echo "## π¦ MCPB Release Created" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Release**: [$VERSION_TAG](${{ github.server_url }}/${{ github.repository }}/releases/tag/$VERSION_TAG)" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Show release type info | |
| if [ "${{ github.ref_name }}" = "main" ]; then | |
| echo "π― **Release Type**: Latest (stable URLs available)" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "π§ **Release Type**: Prerelease (branch: ${{ github.ref_name }}, no stable URLs)" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Available Packages:" >> $GITHUB_STEP_SUMMARY | |
| # Show latest URLs (only for main branch) | |
| if [ "${{ github.ref_name }}" = "main" ]; then | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "#### π₯ Stable URLs (always latest version):" >> $GITHUB_STEP_SUMMARY | |
| for mcpb_file in release-assets/*.mcpb; do | |
| if [ -f "$mcpb_file" ]; then | |
| filename=$(basename "$mcpb_file") | |
| package_name=$(echo "$filename" | sed 's/\.mcpb$//') | |
| latest_url="${{ github.server_url }}/${{ github.repository }}/releases/latest/download/$filename" | |
| echo "- π **${package_name}**: [\`$filename\`]($latest_url)" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| done | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "#### π¦ Versioned Downloads:" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Show all files | |
| for mcpb_file in release-assets/*.mcpb; do | |
| if [ -f "$mcpb_file" ]; then | |
| filename=$(basename "$mcpb_file") | |
| download_url="${{ github.server_url }}/${{ github.repository }}/releases/download/$VERSION_TAG/$filename" | |
| echo "- π¦ [\`$filename\`]($download_url)" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| done | |
| # NEW: Generate Final Summary | |
| - name: Generate Final Summary | |
| if: always() | |
| run: | | |
| echo "## π Public Release Workflow Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Branch: **${{ github.ref_name }}**" >> $GITHUB_STEP_SUMMARY | |
| echo "Lockfile Changed: **$([ "${{ steps.check_lockfile.outputs.lockfile_changed }}" == "true" ] && echo "Yes" || echo "No")**" >> $GITHUB_STEP_SUMMARY | |
| echo "NPM Published: **$([ "${{ steps.changesets.outputs.published }}" == "true" ] && echo "Yes" || echo "No")**" >> $GITHUB_STEP_SUMMARY | |
| # Show MCPB info if packages were built | |
| if [ -d "mcpb-builds" ] && [ -n "$(find mcpb-builds -name "*.mcpb" -type f 2>/dev/null)" ]; then | |
| MCPB_COUNT=$(find mcpb-builds -name "*.mcpb" -type f | wc -l | tr -d ' ') | |
| echo "MCPB Packages: **$MCPB_COUNT**" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "MCPB Packages: **0**" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Workflow Complete: **$(date '+%Y-%m-%d %H:%M:%S')**" >> $GITHUB_STEP_SUMMARY |