From ac1f049417033bae52bfe0ba2020ff9a031bf6bd Mon Sep 17 00:00:00 2001 From: "dependjinbot[bot]" <71271483+dependjinbot[bot]@users.noreply.github.com> Date: Tue, 11 Oct 2022 14:13:07 +0000 Subject: [PATCH] Bump Endjin.PRAutoflow from 0.0.0 to 0.1.6 in .github/workflows (#2) Bumps 'Endjin.PRAutoflow' from 0.0.0 to 0.1.6 --- .github/config/pr-autoflow.json | 4 + .github/dependabot.yml | 8 + .github/workflows/auto_merge.yml | 68 ++++++ .github/workflows/auto_release.yml | 212 ++++++++++++++++++ .../dependabot_approve_and_label.yml | 126 +++++++++++ 5 files changed, 418 insertions(+) create mode 100644 .github/config/pr-autoflow.json create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/auto_merge.yml create mode 100644 .github/workflows/auto_release.yml create mode 100644 .github/workflows/dependabot_approve_and_label.yml diff --git a/.github/config/pr-autoflow.json b/.github/config/pr-autoflow.json new file mode 100644 index 0000000..1ba0419 --- /dev/null +++ b/.github/config/pr-autoflow.json @@ -0,0 +1,4 @@ +{ + "AUTO_MERGE_PACKAGE_WILDCARD_EXPRESSIONS": "[\"Endjin.*\",\"Corvus.*\"]", + "AUTO_RELEASE_PACKAGE_WILDCARD_EXPRESSIONS": "[\"Corvus.AzureFunctionsKeepAlive\",\"Corvus.Configuration\",\"Corvus.ContentHandling\",\"Corvus.Deployment\",\"Corvus.DotLiquidAsync\",\"Corvus.EventStore\",\"Corvus.Extensions\",\"Corvus.Extensions.CosmosDb\",\"Corvus.Extensions.Newtonsoft.Json\",\"Corvus.Extensions.System.Text.Json\",\"Corvus.Identity\",\"Corvus.JsonSchema\",\"Corvus.Leasing\",\"Corvus.Monitoring\",\"Corvus.Retry\",\"Corvus.Storage\",\"Corvus.Tenancy\"]" +} diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..530a8fb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: +- package-ecosystem: nuget + directory: /Solutions + schedule: + interval: daily + open-pull-requests-limit: 10 + diff --git a/.github/workflows/auto_merge.yml b/.github/workflows/auto_merge.yml new file mode 100644 index 0000000..9ef00ec --- /dev/null +++ b/.github/workflows/auto_merge.yml @@ -0,0 +1,68 @@ +name: auto_merge +on: + check_run: + types: + # Check runs completing successfully can unblock the + # corresponding pull requests and make them mergeable. + - completed + pull_request: + types: + # A closed pull request makes the checks on the other + # pull request on the same base outdated. + - closed + # Adding the autosquash label to a pull request can + # trigger an update or a merge. + - labeled + - synchronize + pull_request_review: + types: + # Review approvals can unblock the pull request and + # make it mergeable. + - submitted + # Success statuses can unblock the corresponding + # pull requests and make them mergeable. + status: {} + workflow_run: + workflows: [approve_and_label] + types: + - completed + +permissions: + contents: write + pull-requests: write + issues: write + checks: read + +jobs: + + auto_merge: + name: Auto-squash the PR + runs-on: ubuntu-18.04 + steps: + # This may not be strictly required, but should keep unmerged, closed PRs cleaner + - name: Remove 'autosquash' label from closed PRs + id: remove_autosquash_label_from_closed_prs + uses: actions/github-script@v2 + with: + github-token: '${{ secrets.GITHUB_TOKEN }}' + script: | + const pulls = await github.search.issuesAndPullRequests({ + q: 'is:pr is:closed label:autosquash', + }); + core.info(`pulls: ${pulls.data.items}`) + const repoUrl = `https://api.github.com/repos/${context.payload.repository.owner.login}/${context.payload.repository.name}` + const prs_to_unlabel = pulls.data.items. + filter(function (x) { return x.repository_url == repoUrl; }). + map(p=>p.number); + for (const i of prs_to_unlabel) { + core.info(`Removing label 'autosquash' from issue #${i}`) + github.issues.removeLabel({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + issue_number: i, + name: 'autosquash' + }); + } + - uses: endjin/autosquash@v2.4 + with: + github_token: '${{ secrets.GITHUB_TOKEN }}' \ No newline at end of file diff --git a/.github/workflows/auto_release.yml b/.github/workflows/auto_release.yml new file mode 100644 index 0000000..0add2f7 --- /dev/null +++ b/.github/workflows/auto_release.yml @@ -0,0 +1,212 @@ +name: auto_release +on: + pull_request: + types: [closed] + +jobs: + lookup_default_branch: + runs-on: ubuntu-latest + outputs: + branch_name: ${{ steps.lookup_default_branch.outputs.result }} + head_commit: ${{ steps.lookup_default_branch_head.outputs.result }} + steps: + - name: Lookup default branch name + id: lookup_default_branch + uses: actions/github-script@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + result-encoding: string + script: | + const repo = await github.repos.get({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name + }); + return repo.data.default_branch + - name: Display default_branch_name + run: | + echo "default_branch_name : ${{ steps.lookup_default_branch.outputs.result }}" + + - name: Lookup HEAD commit on default branch + id: lookup_default_branch_head + uses: actions/github-script@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + result-encoding: string + script: | + const branch = await github.repos.getBranch({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + branch: '${{ steps.lookup_default_branch.outputs.result }}' + }); + return branch.data.commit.sha + - name: Display default_branch_name_head + run: | + echo "default_branch_head_commit : ${{ steps.lookup_default_branch_head.outputs.result }}" + + check_for_norelease_label: + runs-on: ubuntu-latest + outputs: + no_release: ${{ steps.check_for_norelease_label.outputs.result }} + steps: + - name: Check for 'no_release' label on PR + id: check_for_norelease_label + uses: actions/github-script@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const labels = await github.issues.listLabelsOnIssue({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + issue_number: context.payload.number + }); + core.info("labels: " + JSON.stringify(labels.data)) + if ( labels.data.map(l => l.name).includes("no_release") ) { + core.info("Label found") + return true + } + return false + - name: Display 'no_release' status + run: | + echo "no_release: ${{ steps.check_for_norelease_label.outputs.result }}" + + check_ready_to_release: + runs-on: ubuntu-latest + needs: [check_for_norelease_label,lookup_default_branch] + if: | + needs.check_for_norelease_label.outputs.no_release == 'false' + outputs: + no_open_prs: ${{ steps.watch_dependabot_prs.outputs.is_complete }} + pending_release_pr_list: ${{ steps.get_release_pending_pr_list.outputs.result }} + ready_to_release: ${{ steps.watch_dependabot_prs.outputs.is_complete == 'True' && steps.get_release_pending_pr_list.outputs.is_release_pending }} + steps: + - name: Get Open PRs + id: get_open_pr_list + uses: actions/github-script@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + # find all open PRs that are targetting the default branch (i.e. main/master) + # return their titles, so they can parsed later to determine if they are + # Dependabot PRs and whether we should wait for them to be auto-merged before + # allowing a release event. + script: | + const pulls = await github.pulls.list({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + state: 'open', + base: '${{ needs.lookup_default_branch.outputs.branch_name }}' + }); + return JSON.stringify(pulls.data.map(p=>p.title)) + result-encoding: string + - name: Display open_pr_list + run: | + echo "open_pr_list : ${{ steps.get_open_pr_list.outputs.result }}" + + - name: Get 'pending_release' PRs + id: get_release_pending_pr_list + uses: actions/github-script@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const pulls = await github.search.issuesAndPullRequests({ + q: 'is:pr is:merged label:pending_release', + }); + core.info(`pulls: ${pulls.data.items}`) + const repoUrl = `https://api.github.com/repos/${context.payload.repository.owner.login}/${context.payload.repository.name}` + const release_pending_prs = pulls.data.items. + filter(function (x) { return x.repository_url == repoUrl; }). + map(p=>p.number); + core.info(`release_pending_prs: ${release_pending_prs}`) + core.setOutput('is_release_pending', (release_pending_prs.length > 0)) + return JSON.stringify(release_pending_prs) + result-encoding: string + - name: Display release_pending_pr_list + run: | + echo "release_pending_pr_list : ${{ steps.get_release_pending_pr_list.outputs.result }}" + echo "is_release_pending : ${{ steps.get_release_pending_pr_list.outputs.is_release_pending }}" + + - uses: actions/checkout@v2 + - name: Read pr-autoflow configuration + id: get_pr_autoflow_config + uses: endjin/pr-autoflow/actions/read-configuration@v1 + with: + config_file: .github/config/pr-autoflow.json + + - name: Watch Dependabot PRs + id: watch_dependabot_prs + uses: endjin/pr-autoflow/actions/dependabot-pr-watcher@v1 + with: + pr_titles: ${{ steps.get_open_pr_list.outputs.result }} + package_wildcard_expressions: ${{ steps.get_pr_autoflow_config.outputs.AUTO_MERGE_PACKAGE_WILDCARD_EXPRESSIONS }} + max_semver_increment: minor + verbose_mode: 'False' + + - name: Display job outputs + run: | + echo "no_open_prs: ${{ steps.watch_dependabot_prs.outputs.is_complete }}" + echo "pending_release_pr_list: ${{ steps.get_release_pending_pr_list.outputs.result }}" + echo "ready_to_release : ${{ steps.watch_dependabot_prs.outputs.is_complete == 'True' && steps.get_release_pending_pr_list.outputs.is_release_pending }}" + + tag_for_release: + runs-on: ubuntu-latest + needs: [check_ready_to_release,lookup_default_branch] + if: | + needs.check_ready_to_release.outputs.ready_to_release == 'true' + steps: + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: '3.1.x' + + - uses: actions/checkout@v2 + with: + # ensure we are creating the release tag on the default branch + ref: ${{ needs.lookup_default_branch.outputs.branch_name }} + fetch-depth: 0 + + - name: Install GitVersion + run: | + dotnet tool install -g GitVersion.Tool --version 5.6.6 + echo "/github/home/.dotnet/tools" >> $GITHUB_PATH + - name: Run GitVersion + id: run_gitversion + run: | + pwsh -noprofile -c 'dotnet-gitversion /diag' + pwsh -noprofile -c '(dotnet-gitversion | ConvertFrom-Json).psobject.properties | % { echo ("::set-output name={0}::{1}" -f $_.name, $_.value) }' + + - name: Generate token + id: generate_token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.ENDJIN_BOT_APP_ID }} + private_key: ${{ secrets.ENDJIN_BOT_PRIVATE_KEY }} + + - name: Create SemVer tag + uses: actions/github-script@v2 + with: + github-token: ${{ steps.generate_token.outputs.token }} + script: | + const uri_path = '/repos/' + context.payload.repository.owner.login + '/' + context.payload.repository.name + '/git/refs' + const tag = await github.request(('POST ' + uri_path), { + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + ref: 'refs/tags/${{ steps.run_gitversion.outputs.MajorMinorPatch }}', + sha: '${{ needs.lookup_default_branch.outputs.head_commit }}' + }) + + - name: Remove 'release_pending' label from PRs + id: remove_pending_release_labels + uses: actions/github-script@v2 + with: + github-token: '${{ steps.generate_token.outputs.token }}' + script: | + core.info('PRs to unlabel: ${{ needs.check_ready_to_release.outputs.pending_release_pr_list }}') + const pr_list = JSON.parse('${{ needs.check_ready_to_release.outputs.pending_release_pr_list }}') + core.info(`pr_list: ${pr_list}`) + for (const i of pr_list) { + core.info(`Removing label 'pending_release' from issue #${i}`) + github.issues.removeLabel({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + issue_number: i, + name: 'pending_release' + }); + } diff --git a/.github/workflows/dependabot_approve_and_label.yml b/.github/workflows/dependabot_approve_and_label.yml new file mode 100644 index 0000000..68d81f1 --- /dev/null +++ b/.github/workflows/dependabot_approve_and_label.yml @@ -0,0 +1,126 @@ +name: approve_and_label +on: + pull_request: + types: [opened, reopened] + +permissions: + contents: read + issues: write + pull-requests: write + +jobs: + evaluate_dependabot_pr: + runs-on: ubuntu-latest + name: Parse Dependabot PR title + # Don't process PRs from forked repos + if: + github.event.pull_request.head.repo.full_name == github.repository + outputs: + dependency_name: ${{ steps.parse_dependabot_pr_automerge.outputs.dependency_name }} + version_from: ${{ steps.parse_dependabot_pr_automerge.outputs.version_from }} + version_to: ${{ steps.parse_dependabot_pr_automerge.outputs.version_to }} + is_auto_merge_candidate: ${{ steps.parse_dependabot_pr_automerge.outputs.is_interesting_package }} + is_auto_release_candidate: ${{ steps.parse_dependabot_pr_autorelease.outputs.is_interesting_package }} + semver_increment: ${{ steps.parse_dependabot_pr_automerge.outputs.semver_increment }} + steps: + - uses: actions/checkout@v2 + - name: Read pr-autoflow configuration + id: get_pr_autoflow_config + uses: endjin/pr-autoflow/actions/read-configuration@v1 + with: + config_file: .github/config/pr-autoflow.json + - name: Dependabot PR - AutoMerge Candidate + id: parse_dependabot_pr_automerge + uses: endjin/pr-autoflow/actions/dependabot-pr-parser@v1 + with: + pr_title: ${{ github.event.pull_request.title }} + package_wildcard_expressions: ${{ steps.get_pr_autoflow_config.outputs.AUTO_MERGE_PACKAGE_WILDCARD_EXPRESSIONS }} + - name: Dependabot PR - AutoRelease Candidate + id: parse_dependabot_pr_autorelease + uses: endjin/pr-autoflow/actions/dependabot-pr-parser@v1 + with: + pr_title: ${{ github.event.pull_request.title }} + package_wildcard_expressions: ${{ steps.get_pr_autoflow_config.outputs.AUTO_RELEASE_PACKAGE_WILDCARD_EXPRESSIONS }} + - name: debug + run: | + echo "dependency_name : ${{ steps.parse_dependabot_pr_automerge.outputs.dependency_name }}" + echo "is_interesting_package (merge) : ${{ steps.parse_dependabot_pr_automerge.outputs.is_interesting_package }}" + echo "is_interesting_package (release) : ${{ steps.parse_dependabot_pr_autorelease.outputs.is_interesting_package }}" + echo "semver_increment : ${{ steps.parse_dependabot_pr_automerge.outputs.semver_increment }}" + + approve: + runs-on: ubuntu-latest + needs: evaluate_dependabot_pr + name: Approve auto-mergeable dependabot PRs + if: | + (github.actor == 'dependabot[bot]' || github.actor == 'dependjinbot[bot]' || github.actor == 'nektos/act') && + needs.evaluate_dependabot_pr.outputs.is_auto_merge_candidate == 'True' + steps: + - name: Show PR Details + run: | + echo "<------------------------------------------------>" + echo "dependency_name : ${{needs.evaluate_dependabot_pr.outputs.dependency_name}}" + echo "semver_increment : ${{needs.evaluate_dependabot_pr.outputs.semver_increment}}" + echo "auto_merge : ${{needs.evaluate_dependabot_pr.outputs.is_auto_merge_candidate}}" + echo "auto_release : ${{needs.evaluate_dependabot_pr.outputs.is_auto_release_candidate}}" + echo "from_version : ${{needs.evaluate_dependabot_pr.outputs.version_from}}" + echo "to_version : ${{needs.evaluate_dependabot_pr.outputs.version_to}}" + echo "<------------------------------------------------>" + shell: bash + - name: Approve pull request + if: | + needs.evaluate_dependabot_pr.outputs.is_auto_merge_candidate == 'True' && + (needs.evaluate_dependabot_pr.outputs.semver_increment == 'minor' || needs.evaluate_dependabot_pr.outputs.semver_increment == 'patch') + uses: andrewmusgrave/automatic-pull-request-review@0.0.2 + with: + repo-token: '${{ secrets.GITHUB_TOKEN }}' + event: APPROVE + body: 'Thank you dependabot 🎊' + - name: 'Update PR body' + if: | + needs.evaluate_dependabot_pr.outputs.is_auto_merge_candidate == 'True' && + (needs.evaluate_dependabot_pr.outputs.semver_increment == 'minor' || needs.evaluate_dependabot_pr.outputs.semver_increment == 'patch') + uses: actions/github-script@v2 + with: + github-token: '${{ secrets.GITHUB_TOKEN }}' + script: | + await github.pulls.update({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + pull_number: context.payload.pull_request.number, + body: "Bumps '${{needs.evaluate_dependabot_pr.outputs.dependency_name}}' from ${{needs.evaluate_dependabot_pr.outputs.version_from}} to ${{needs.evaluate_dependabot_pr.outputs.version_to}}" + }) + label: + runs-on: ubuntu-latest + needs: evaluate_dependabot_pr + name: Label + steps: + - name: 'Label auto-mergeable dependabot PRs with "autosquash"' + if: | + (github.actor == 'dependabot[bot]' || github.actor == 'dependjinbot[bot]' || github.actor == 'nektos/act') && + needs.evaluate_dependabot_pr.outputs.is_auto_merge_candidate == 'True' && + (needs.evaluate_dependabot_pr.outputs.semver_increment == 'minor' || needs.evaluate_dependabot_pr.outputs.semver_increment == 'patch') + uses: actions/github-script@v2 + with: + github-token: '${{ secrets.GITHUB_TOKEN }}' + script: | + await github.issues.addLabels({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + issue_number: context.payload.pull_request.number, + labels: ['autosquash'] + }) + - name: 'Label non-dependabot PRs and auto-releasable dependabot PRs with "pending_release"' + if: | + (github.actor != 'dependabot[bot]' && github.actor != 'dependjinbot[bot]') || + needs.evaluate_dependabot_pr.outputs.is_auto_release_candidate == 'True' + uses: actions/github-script@v2 + with: + github-token: '${{ secrets.GITHUB_TOKEN }}' + script: | + await github.issues.addLabels({ + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + issue_number: context.payload.pull_request.number, + labels: ['pending_release'] + })