chore(deps): bump actions/checkout from 5 to 6 #781
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: Monorepo CI | |
| concurrency: #avoid concurrent runs on label events, might cause issues on super fast commits ¯\_(ツ)_/¯ | |
| group: ${{ github.head_ref }} | |
| cancel-in-progress: true | |
| on: | |
| pull_request: | |
| types: [opened, closed, synchronize, reopened, labeled, unlabeled] | |
| permissions: | |
| pull-requests: read | |
| jobs: | |
| detect: | |
| runs-on: ubuntu-latest | |
| name: 'Detect pull request context' | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| repository-projects: read | |
| outputs: | |
| directories: ${{ steps.condense.outputs.result }} | |
| release-type: ${{ steps.check_pr_label.outputs.release-type}} | |
| is-merge-event: >- | |
| ${{ github.event_name == 'pull_request' | |
| && github.event.action == 'closed' | |
| && github.event.pull_request.merged == true }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| persist-credentials: true | |
| fetch-depth: 0 | |
| - name: Autolabel PR | |
| if: github.event.pull_request.merged != true | |
| env: | |
| PR_URL: ${{github.event.pull_request.html_url}} | |
| PR_ID: ${{ github.event.pull_request.number }} | |
| PR_BRANCH: ${{ github.head_ref || github.ref_name }} | |
| GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} | |
| run: | | |
| git checkout "$PR_BRANCH" | |
| LABELS=$(gh pr view $PR_URL --json labels --jq '.labels[] | select((.name=="minor") or (.name=="major") or (.name=="patch") or (.name=="no-release")) |.name') | |
| NUMBER_OF_LABELS=$(echo "$LABELS" | wc -w) | |
| if [ "$NUMBER_OF_LABELS" -eq "1" ] ; then | |
| echo "Found: $LABELS" | |
| elif [ "$NUMBER_OF_LABELS" -gt "1" ] ; then | |
| echo "::error ::Too many release type labels: $( echo $LABELS | tr '\n' ' ' )" | |
| exit 1 | |
| else | |
| echo "::warn ::No release type labels found(patch/minor/major/no-release)" | |
| echo "Checking commit messages for semantic labels" | |
| # fetch all commits | |
| PR_COMMITS=`gh pr view $PR_ID --json commits | jq '.commits | length'` | |
| git fetch --no-tags --prune --progress --no-recurse-submodules --deepen=$PR_COMMITS | |
| # retrive the commit messages of the PR | |
| COMMIT_MESSAGES="$(gh pr view $PR_ID --json commits --jq '.[].[].messageHeadline')" | |
| # Check all commits in PR for conventional commit messages - add appropriate label if found | |
| # Follows https://www.conventionalcommits.org/en/v1.0.0/ | |
| # If there's conflicting messages take the largest semver change | |
| if echo "$COMMIT_MESSAGES" | grep --quiet --ignore-case 'breaking change.*:\|.*!:'; then | |
| LABEL="major" | |
| elif echo "$COMMIT_MESSAGES" | grep --quiet --ignore-case 'feat.*:' ; then | |
| LABEL="minor" | |
| elif echo "$COMMIT_MESSAGES" | grep --quiet --ignore-case 'fix.*:' ; then | |
| LABEL="patch" | |
| else | |
| echo "::error No release label found, and no conventional commit messages found. Label your PR with major/minor/patch" | |
| exit 2 | |
| fi | |
| gh pr edit "$PR_ID" --add-label "$LABEL" | |
| fi | |
| - name: Check PR labels for semver | |
| id: check_pr_label | |
| env: | |
| PR_URL: ${{github.event.pull_request.html_url}} | |
| PR_ID: ${{ github.event.pull_request.number }} | |
| GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} | |
| run: | | |
| LABELS=$(gh pr view $PR_URL --json labels --jq '.labels[] | select((.name=="minor") or (.name=="major") or (.name=="patch") or (.name=="no-release")) |.name') | |
| NUMBER_OF_LABELS=$(echo "$LABELS" | wc -w) | |
| if [ "$NUMBER_OF_LABELS" -eq "1" ] ; then | |
| echo "Found: $LABELS" | |
| echo "release-type=$LABELS" >> "$GITHUB_OUTPUT" | |
| elif [ "$NUMBER_OF_LABELS" -gt "1" ] ; then | |
| echo "::error ::Too many release type labels: $( echo $LABELS | tr '\n' ' ' )" | |
| exit 1 | |
| fi | |
| - name: Get changed files | |
| uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 | |
| id: raw-files | |
| with: | |
| json: "true" | |
| escape_json: "false" | |
| - name: Condense to directory list | |
| uses: actions/github-script@v8 | |
| id: condense | |
| env: | |
| RAW_FILES: ${{ steps.raw-files.outputs.all_changed_files }} | |
| with: | |
| script: | | |
| const raw = JSON.parse(process.env.RAW_FILES); | |
| const directories = Array.from(new Set(raw | |
| .filter(x => !x.startsWith('.')) | |
| .filter(x => x.includes('/')) | |
| .map(x => x.split('/')[0]) | |
| )); | |
| if (directories.length < 1) return {}; | |
| return { | |
| include: directories.map(directory => ({ directory })), | |
| }; | |
| plan: | |
| needs: detect | |
| name: 'Release plan & docs for module: ${{ matrix.directory }}' | |
| if: needs.detect.outputs.directories != '{}' && needs.detect.outputs.release-type != 'no-release' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| new-version: ${{ steps.new-version.outputs.result }} | |
| permissions: | |
| contents: write | |
| pull-requests: read | |
| strategy: | |
| matrix: "${{ fromJson(needs.detect.outputs.directories) }}" | |
| fail-fast: false | |
| # Do serially so git operations don't collide | |
| max-parallel: 1 | |
| steps: | |
| - name: Checkout repository to use composite action | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: main # Only use composite action from main to prevent malicious PRs | |
| persist-credentials: false | |
| # Do the per-module steps in a composite action because matrixes can't handle dynamic outputs | |
| - name: Version bump | |
| uses: mozilla/terraform-modules/.github/actions/versions@e5fc38a939be3df68dca237d2b4ed4d535addd59 | |
| with: | |
| package-name: ${{ matrix.directory }} | |
| release-type: ${{ needs.detect.outputs.release-type }} | |
| - name: Generate docs | |
| if: needs.detect.outputs.is-merge-event == 'false' && needs.detect.outputs.release-type != 'no-release' | |
| uses: mozilla/terraform-modules/.github/actions/docs@e5fc38a939be3df68dca237d2b4ed4d535addd59 | |
| with: | |
| package-name: ${{ matrix.directory }} | |
| comment: | |
| needs: [detect, plan] | |
| if: needs.detect.outputs.is-merge-event == 'false' && needs.detect.outputs.release-type != 'no-release' | |
| runs-on: ubuntu-latest | |
| name: 'Comment on PR with release plan' | |
| permissions: | |
| issues: write | |
| pull-requests: write | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v4.3.0 | |
| with: | |
| path: outputs | |
| - name: Display structure of downloaded files | |
| run: ls -R | |
| working-directory: outputs | |
| - uses: actions/github-script@v8 | |
| id: comment | |
| with: | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const { number: issue_number } = context.issue; | |
| const { readdir, readFile } = require('fs').promises; | |
| const utf8 = { encoding: 'utf-8' }; | |
| const lines = [ | |
| '# Release plan', '', | |
| '| Directory | Previous version | New version |', | |
| '|--|--|--|', | |
| ]; | |
| const sections = []; | |
| for (const folder of await readdir('outputs', { withFileTypes: true })) { | |
| if (!folder.isDirectory()) continue; | |
| const readText = (name) => readFile(name, utf8).then(x => x.trim()); | |
| lines.push('| '+[ | |
| `\`${folder.name}\``, | |
| `${await readText(`outputs/${folder.name}/previous-version.txt`)}`, | |
| `**${await readText(`outputs/${folder.name}/new-version.txt`)}**`, | |
| ].join(' | ')+' |'); | |
| } | |
| const finalBody = [lines.join('\n'), ...sections].join('\n\n'); | |
| const {data: allComments} = await github.rest.issues.listComments({ issue_number, owner, repo }); | |
| const ourComments = allComments | |
| .filter(comment => comment.user.login === 'github-actions[bot]') | |
| .filter(comment => comment.body.startsWith(lines[0]+'\n')); | |
| const latestComment = ourComments.slice(-1)[0]; | |
| if (latestComment && latestComment.body === finalBody) { | |
| console.log('Existing comment is already up to date.'); | |
| return; | |
| } | |
| const {data: newComment} = await github.rest.issues.createComment({ issue_number, owner, repo, body: finalBody }); | |
| console.log('Posted comment', newComment.id, '@', newComment.html_url); | |
| // Delete all our previous comments | |
| for (const comment of ourComments) { | |
| if (comment.id === newComment.id) continue; | |
| console.log('Deleting previous PR comment from', comment.created_at); | |
| await github.rest.issues.deleteComment({ comment_id: comment.id, owner, repo }); | |
| } | |
| trigger-release: | |
| needs: [plan] | |
| if: needs.detect.outputs.is-merge-event == 'true' && needs.detect.outputs.release-type != 'no-release' | |
| runs-on: ubuntu-latest | |
| name: 'Dispatch release event' | |
| permissions: | |
| actions: write | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v4.3.0 | |
| with: | |
| path: outputs | |
| - name: Combine version information | |
| id: extract-releases | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const { readdir, readFile } = require('fs').promises; | |
| const utf8 = { encoding: 'utf-8' }; | |
| const readText = (name) => readFile(name, utf8).then(x => x.trim()); | |
| const directories = await readdir('outputs', { withFileTypes: true }); | |
| return await Promise.all(directories | |
| .filter(x => x.isDirectory()) | |
| .map(async folder => ({ | |
| module: folder.name, | |
| prevVersion: await readText(`outputs/${folder.name}/previous-version.txt`), | |
| newVersion: await readText(`outputs/${folder.name}/new-version.txt`), | |
| }))); | |
| - name: Dispatch monorepo_release event | |
| uses: actions/github-script@v8 | |
| env: | |
| RELEASE_LIST: ${{ steps.extract-releases.outputs.result }} | |
| with: | |
| script: | | |
| const payload = { | |
| run_id: "${{ github.run_id }}", | |
| sha: context.sha, | |
| releases: JSON.parse(process.env.RELEASE_LIST), | |
| }; | |
| console.log('Event payload:', JSON.stringify(payload, null, 2)); | |
| const { owner, repo } = context.repo; | |
| await github.rest.repos.createDispatchEvent({ | |
| owner, repo, | |
| event_type: 'monorepo_release', | |
| client_payload: payload, | |
| }); |