From ee9d811c391e293659d20ad017c9f3ded0c610cc Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Mon, 3 Apr 2023 16:01:25 -0500 Subject: [PATCH 01/30] Update check-cla to customize which CLA repo --- check-cla/action.yml | 48 +++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 8ca76699..c77b08fa 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -5,16 +5,26 @@ inputs: token: description: Token for commenting and labeling on contributor's PR required: true - infrastructure_token: - description: Token for opening singee PR in conda/infrastructure - required: true label: description: Label to apply to contributor's PR once CLA is singed required: true + cla_repo: + description: Upstream repository in which to create PR + default: conda/infrastructure + cla_fork: + description: Fork of cla_repo in which to create branch + default: conda-bot/infrastructure + cla_token: + description: Token for opening singee PR in the provided `cla_repo` + required: true + cla_path: + description: Path to the CLA signees file within the provided `cla_repo` + default: .clabot runs: using: composite steps: + # sha, labels, hasLabel - name: Get PR metadata id: pr uses: actions/github-script@v6 @@ -27,6 +37,7 @@ runs: pull_number: number, }); console.log(pullRequest); + const sha = pullRequest.data.head.sha; console.log(sha); core.setOutput('sha', sha); @@ -48,6 +59,7 @@ runs: state: pending sha: ${{ steps.pr.outputs.sha || github.sha }} + # contributors, hasSigned - name: Check if current actor has signed uses: actions/github-script@v6 id: contributors @@ -55,13 +67,14 @@ runs: github-token: ${{ inputs.token }} script: | console.log(context); + const [owner, repo] = '${{ inputs.cla_repo }}'.split("/", 1); const getContributors = async () => { try { const results = ( await github.rest.repos.getContent({ - owner: 'conda', - repo: 'infrastructure', - path: '.clabot' + owner: owner, + repo: repo, + path: '${{ inputs.cla_path }}' }) ); return JSON.parse(Buffer.from(results.data.content, results.data.encoding).toString('utf-8')).contributors; @@ -72,12 +85,14 @@ runs: } const contributors = await getContributors(); console.log(contributors); + core.setOutput('contributors', contributors); + const pull_request = (context.payload.issue || context.payload.pull_request || context.payload); const creator = pull_request.user.login; console.log(creator); + const hasSigned = contributors.includes(creator); console.log(hasSigned); - core.setOutput('contributors', contributors); core.setOutput('hasSigned', hasSigned); # add [cla-signed] label if actor has already signed @@ -96,31 +111,32 @@ runs: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} - # checkout conda/infrastructure to update .clabot + # checkout cla_repo to update cla_path - uses: actions/checkout@v3 if: steps.contributors.outputs.hasSigned == 'false' with: - repository: conda/infrastructure + repository: ${{ inputs.cla_repo }} - # update .clabot + # update cla_path - shell: python if: steps.contributors.outputs.hasSigned == 'false' run: | import json from pathlib import Path - path = Path(".clabot") - clabot = json.loads(path.read_text()) - clabot["contributors"].append("${{ github.actor }}") - clabot["contributors"].sort() - path.write_text(json.dumps(clabot)) + path = Path("${{ inputs.cla_path }}") + signees = json.loads(path.read_text()) + signees["contributors"].append("${{ github.actor }}") + signees["contributors"].sort() + path.write_text(json.dumps(signees)) # create PR - uses: peter-evans/create-pull-request@v4 id: cla-pr if: steps.contributors.outputs.hasSigned == 'false' with: - token: ${{ inputs.infrastructure_token }} + push-to-fork: ${{ inputs.cla_fork }} + token: ${{ inputs.cla_token }} branch: cla-${{ github.actor }} commit-message: Adding CLA singee ${{ github.actor }} title: Adding CLA singee ${{ github.actor }} From ec9f0b42f629417f2d864aa774ce60f65f21c838 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 13:33:17 -0500 Subject: [PATCH 02/30] Adds set-commit-status action --- check-cla/action.yml | 27 +++++++++--------- set-commit-status/README.md | 39 +++++++++++++++++++++++++ set-commit-status/action.yml | 55 ++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 13 deletions(-) create mode 100644 set-commit-status/README.md create mode 100644 set-commit-status/action.yml diff --git a/check-cla/action.yml b/check-cla/action.yml index c77b08fa..223a8b98 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -3,7 +3,8 @@ name: CLA check description: Reacts to new PRs and check if the contributor has previously signed the conda contributor license agreement (CLA). inputs: token: - description: Token for commenting and labeling on contributor's PR + description: The GitHub token (`statuses: write` and `pull_request: write`) used to create an authenticated client + default: ${{ github.token }} required: true label: description: Label to apply to contributor's PR once CLA is singed @@ -50,14 +51,14 @@ runs: console.log(hasLabel); core.setOutput('hasLabel', hasLabel); + # commit status → pending - name: Set commit status with pending - uses: dholth/github-status-action@runs-using-node16 + uses: conda/actions/set-commit-status@customize-cla-repo with: - authToken: ${{ inputs.token }} + token: ${{ inputs.token }} context: CLA check - description: Checking conda CLA... state: pending - sha: ${{ steps.pr.outputs.sha || github.sha }} + description: Checking conda CLA... # contributors, hasSigned - name: Check if current actor has signed @@ -157,23 +158,23 @@ runs: In order for us to review and merge your code, please e-sign the [Contributor License Agreement PDF](https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement). We then need to manually verify your signature, merge the PR (${{ steps.cla-pr.outputs.pull-request-url }}), and ping the bot to refresh the PR. GITHUB_TOKEN: ${{ inputs.token }} + # commit status → error - name: Set commit status to error if: steps.contributors.outputs.hasSigned == 'false' - uses: dholth/github-status-action@runs-using-node16 + uses: conda/actions/set-commit-status@customize-cla-repo with: - authToken: ${{ inputs.token }} + token: ${{ inputs.token }} context: CLA check - description: Please follow the details link to sign the conda CLA. → state: error - sha: ${{ steps.pr.outputs.sha || github.sha }} + description: Please follow the details link to sign the conda CLA. → target_url: https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement + # commit status → success - name: Set commit status to success if: steps.contributors.outputs.hasSigned == 'true' - uses: dholth/github-status-action@runs-using-node16 + uses: conda/actions/set-commit-status@customize-cla-repo with: - authToken: ${{ inputs.token }} + token: ${{ inputs.token }} context: CLA check - description: CLA signed, thank you! state: success - sha: ${{ steps.pr.outputs.sha || github.sha }} + description: CLA signed, thank you! diff --git a/set-commit-status/README.md b/set-commit-status/README.md new file mode 100644 index 00000000..8138c84d --- /dev/null +++ b/set-commit-status/README.md @@ -0,0 +1,39 @@ +# Set Commit Status + +A custom GitHub action to be used in the conda GitHub organization to set a commit +status. + +## GitHub Action Usage + +In your GitHub repository include the action in your workflows: + +```yaml +name: Set commit status + +on: pull_request_target + +jobs: + pending: + # need write access for statuses to succeed + permissions: + statuses: write + + steps: + - uses: conda/actions/set-commit-status + with: + # [required] + # The GitHub token (`statuses: write`) used to create an authenticated client + # (default: secrets.GITHUB_TOKEN) + token: + # [required] + # The name of the commit status + context: + # [required] + # The commit status to set, either success, error, failure, or pending + state: + # A short text explaining the commit status + # (default: '') + description: + # URL/URI linking to further details + target_url: +``` diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml new file mode 100644 index 00000000..9b47c0a4 --- /dev/null +++ b/set-commit-status/action.yml @@ -0,0 +1,55 @@ +name: Set Commit Status +description: Modifies the commit status of the most recent commit. +inputs: + token: + description: "The GitHub token (`statuses: write`) used to create an authenticated client" + default: ${{ github.token }} + required: true + context: + description: The name of the commit status + required: true + state: + description: The commit status to set, either success, error, failure, or pending + required: true + description: + description: A short text explaining the commit status + default: '' + required: false + target_url: + description: URL/URI linking to further details + required: false + +runs: + using: composite + steps: + - uses: actions/github-script@v6 + with: + script: | + try { + const octokit = getOctokit('${{ inputs.token }}'); + core.debug("Successfully authenticated Octokit"); + } catch (error) { + throw new Error(`error while authenticating Octokit: ${(error as Error).message}`); + } + + try { + core.debug(`owner: ${{ github.repository }}`); + const [owner, repo] = '${{ github.repository }}'.split("/", 1); + core.debug(`owner: ${owner}`); + core.debug(`repo: ${repo}`); + core.debug(`sha: ${{ github.sha }}`); + + await octokit.rest.repos.createCommitStatus({ + context: '${{ inputs.context }}', + description: '${{ inputs.description }}', + owner: owner, + repo: repo, + sha: '${{ github.sha }}', + state: '${{ inputs.state }}', + target_url: '${{ inputs.target_url }}' + }); + core.info(`Updated build status: ${{ inputs.state }}`); + } catch (error) { + throw new Error(`error while setting commit status: ${(error as Error).message}`); + } + From a3dded40c97ca84de95fe33ef3a62afc2fcfa14a Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 15:15:02 -0500 Subject: [PATCH 03/30] Update READMEs and descriptions --- check-cla/README.md | 41 ++++++++++++++++++++++-------------- check-cla/action.yml | 10 ++++----- set-commit-status/README.md | 9 +++++--- set-commit-status/action.yml | 4 ++-- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/check-cla/README.md b/check-cla/README.md index 54b013f6..7d4f1da9 100644 --- a/check-cla/README.md +++ b/check-cla/README.md @@ -1,43 +1,52 @@ # Check CLA (Contributor License Agreement) -This is a custom GitHub action to be used in the conda GitHub organization -for checking the conda contributor license agreement. +A custom GitHub action to be used in the conda GitHub organization for checking the +conda contributor license agreement. ## GitHub Action Usage In your GitHub repository include the action in your workflows: ```yaml -name: Contributor license agreement (CLA) +name: Check CLA on: issue_comment: types: - created pull_request_target: - types: - - reopened - - opened - - synchronize jobs: check: if: >- - !github.event.repository.fork - && ( + ( github.event.comment.body == '@conda-bot check' && github.event.issue.pull_request || github.event_name == 'pull_request_target' ) - runs-on: ubuntu-latest steps: - - name: Check CLA - uses: conda/actions/check-cla + - uses: conda/actions/check-cla with: # [required] - # label to add when actor has signed the CLA - label: cla-signed + # A token with ability to comment, label, and modify the commit status + # (`pull_request: write` and `statuses: write`) + # (default: secrets.GITHUB_TOKEN) + token: + # [required] + # Label to apply to contributor's PR once CLA is singed + label: + + # Upstream repository in which to create PR + # (default: conda/infrastructure) + cla_repo: + # Path to the CLA signees file within the provided `cla_repo` + # (default: .clabot) + cla_path: + + # Fork of cla_repo in which to create branch + # (default: conda-bot/infrastructure) + cla_fork: # [required] - # the GitHub Personal Access Token to comment and label with - token: ${{ secrets.CLA_ACTION_TOKEN }} + # Token for opening singee PR in the provided `cla_repo` + cla_token: ``` diff --git a/check-cla/action.yml b/check-cla/action.yml index 223a8b98..b5a7721c 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -3,7 +3,7 @@ name: CLA check description: Reacts to new PRs and check if the contributor has previously signed the conda contributor license agreement (CLA). inputs: token: - description: The GitHub token (`statuses: write` and `pull_request: write`) used to create an authenticated client + description: 'A token with ability to comment, label, and modify the commit status (`pull_request: write` and `statuses: write`)' default: ${{ github.token }} required: true label: @@ -12,15 +12,15 @@ inputs: cla_repo: description: Upstream repository in which to create PR default: conda/infrastructure + cla_path: + description: Path to the CLA signees file within the provided `cla_repo` + default: .clabot cla_fork: description: Fork of cla_repo in which to create branch default: conda-bot/infrastructure cla_token: - description: Token for opening singee PR in the provided `cla_repo` + description: Token for opening singee PR in `cla_fork` required: true - cla_path: - description: Path to the CLA signees file within the provided `cla_repo` - default: .clabot runs: using: composite diff --git a/set-commit-status/README.md b/set-commit-status/README.md index 8138c84d..f2502b2c 100644 --- a/set-commit-status/README.md +++ b/set-commit-status/README.md @@ -8,7 +8,7 @@ status. In your GitHub repository include the action in your workflows: ```yaml -name: Set commit status +name: Set Commit Status on: pull_request_target @@ -22,15 +22,18 @@ jobs: - uses: conda/actions/set-commit-status with: # [required] - # The GitHub token (`statuses: write`) used to create an authenticated client + # A token with the ability to modify the commit status + # (`statuses: write`) # (default: secrets.GITHUB_TOKEN) token: + # [required] # The name of the commit status context: # [required] - # The commit status to set, either success, error, failure, or pending + # The commit status to set; either success, error, failure, or pending state: + # A short text explaining the commit status # (default: '') description: diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 9b47c0a4..5467476a 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -1,8 +1,9 @@ +--- name: Set Commit Status description: Modifies the commit status of the most recent commit. inputs: token: - description: "The GitHub token (`statuses: write`) used to create an authenticated client" + description: 'The GitHub token (`statuses: write`) used to create an authenticated client' default: ${{ github.token }} required: true context: @@ -52,4 +53,3 @@ runs: } catch (error) { throw new Error(`error while setting commit status: ${(error as Error).message}`); } - From 6c83eccf63bd4e0dc97f777c7bc6173aeb5a0686 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 15:27:06 -0500 Subject: [PATCH 04/30] Use JavaScript, not TypeScript --- set-commit-status/action.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 5467476a..651d20ff 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -28,17 +28,17 @@ runs: script: | try { const octokit = getOctokit('${{ inputs.token }}'); - core.debug("Successfully authenticated Octokit"); + core.debug('Successfully authenticated Octokit'); } catch (error) { - throw new Error(`error while authenticating Octokit: ${(error as Error).message}`); + throw new Error(`error while authenticating Octokit: ${error}`); } try { - core.debug(`owner: ${{ github.repository }}`); - const [owner, repo] = '${{ github.repository }}'.split("/", 1); + core.debug('owner: ${{ github.repository }}'); + const [owner, repo] = '${{ github.repository }}'.split('/', 1); core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); - core.debug(`sha: ${{ github.sha }}`); + core.debug('sha: ${{ github.sha }}'); await octokit.rest.repos.createCommitStatus({ context: '${{ inputs.context }}', @@ -49,7 +49,7 @@ runs: state: '${{ inputs.state }}', target_url: '${{ inputs.target_url }}' }); - core.info(`Updated build status: ${{ inputs.state }}`); + core.info('Updated build status: ${{ inputs.state }}'); } catch (error) { - throw new Error(`error while setting commit status: ${(error as Error).message}`); + throw new Error(`error while setting commit status: ${error}`); } From 2b2d732efbe2a163182dfbdb27933ebfc6105cd0 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 15:32:21 -0500 Subject: [PATCH 05/30] Don't need to authenticate Octokit object --- set-commit-status/action.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 651d20ff..12f81475 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -26,13 +26,6 @@ runs: - uses: actions/github-script@v6 with: script: | - try { - const octokit = getOctokit('${{ inputs.token }}'); - core.debug('Successfully authenticated Octokit'); - } catch (error) { - throw new Error(`error while authenticating Octokit: ${error}`); - } - try { core.debug('owner: ${{ github.repository }}'); const [owner, repo] = '${{ github.repository }}'.split('/', 1); @@ -40,7 +33,7 @@ runs: core.debug(`repo: ${repo}`); core.debug('sha: ${{ github.sha }}'); - await octokit.rest.repos.createCommitStatus({ + await github.rest.repos.createCommitStatus({ context: '${{ inputs.context }}', description: '${{ inputs.description }}', owner: owner, From 536110212c43d5970129bb863dbd2a98b79658e5 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 15:35:34 -0500 Subject: [PATCH 06/30] Remove redundant debug statements --- set-commit-status/action.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 12f81475..99cc62a6 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -27,11 +27,9 @@ runs: with: script: | try { - core.debug('owner: ${{ github.repository }}'); const [owner, repo] = '${{ github.repository }}'.split('/', 1); core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); - core.debug('sha: ${{ github.sha }}'); await github.rest.repos.createCommitStatus({ context: '${{ inputs.context }}', From 528c212c8befb57559556c4add50c1f7710b7287 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 15:40:15 -0500 Subject: [PATCH 07/30] Dumb JS split --- set-commit-status/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 99cc62a6..f177b292 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -27,7 +27,7 @@ runs: with: script: | try { - const [owner, repo] = '${{ github.repository }}'.split('/', 1); + const [owner, repo] = '${{ github.repository }}'.split('/', 2); core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); From 83dab520825b7541ee67b6471439e969b9e1e566 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 16:29:25 -0500 Subject: [PATCH 08/30] Flatten await and keep try-catch simple --- check-cla/action.yml | 108 +++++++++++++++++++---------------- set-commit-status/action.yml | 12 ++-- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index b5a7721c..a01e685a 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -25,31 +25,38 @@ inputs: runs: using: composite steps: - # sha, labels, hasLabel + # sha, labels, has_label - name: Get PR metadata id: pr uses: actions/github-script@v6 with: script: | const { owner, repo, number } = context.issue; - const pullRequest = await github.rest.pulls.get({ - owner, - repo, - pull_number: number, - }); - console.log(pullRequest); - - const sha = pullRequest.data.head.sha; - console.log(sha); + core.debug(`owner: ${owner}`); + core.debug(`repo: ${repo}`); + core.debug(`number: ${number}`); + + try { + var raw = await github.rest.pulls.get({ + owner: owner, + repo: repo, + pull_number: number + }); + } catch (error) { + throw new Error(`error retrieving PR: ${error}`); + } + + const sha = raw.data.head.sha; core.setOutput('sha', sha); + core.debug(`sha: ${sha}`); - const labels = pullRequest.data.labels.map(label => label.name) - console.log(labels); + const labels = raw.data.labels.map(label => label.name) core.setOutput('labels', labels); + core.debug(`labels: ${labels}`); - const hasLabel = labels.includes('${{ inputs.label }}') - console.log(hasLabel); - core.setOutput('hasLabel', hasLabel); + const has_label = labels.includes('${{ inputs.label }}') + core.setOutput('has_label', has_label); + core.debug(`has_label: ${has_label}`); # commit status → pending - name: Set commit status with pending @@ -60,46 +67,51 @@ runs: state: pending description: Checking conda CLA... - # contributors, hasSigned + # contributors, has_signed - name: Check if current actor has signed uses: actions/github-script@v6 id: contributors with: github-token: ${{ inputs.token }} script: | - console.log(context); - const [owner, repo] = '${{ inputs.cla_repo }}'.split("/", 1); - const getContributors = async () => { - try { - const results = ( - await github.rest.repos.getContent({ - owner: owner, - repo: repo, - path: '${{ inputs.cla_path }}' - }) - ); - return JSON.parse(Buffer.from(results.data.content, results.data.encoding).toString('utf-8')).contributors; - } catch (err) { - core.error(`Could not retrieve contributors, returning undefined. Reason: ${err}`) - return undefined; - } + const [owner, repo] = '${{ inputs.cla_repo }}'.split('/'); + core.debug(`owner: ${owner}`); + core.debug(`repo: ${repo}`); + + try { + var raw = await github.rest.repos.getContent({ + owner: owner, + repo: repo, + path: '${{ inputs.cla_path }}' + }); + } catch (error) { + throw new Error(`error retrieving contributors: ${error}`) } - const contributors = await getContributors(); - console.log(contributors); + + const contributors = JSON.parse( + Buffer.from( + raw.data.content, + raw.data.encoding + ).toString('utf-8') + ).contributors; core.setOutput('contributors', contributors); + core.debug(`contributors: ${contributors}`); - const pull_request = (context.payload.issue || context.payload.pull_request || context.payload); - const creator = pull_request.user.login; - console.log(creator); + const creator = ( + context.payload.issue + || context.payload.pull_request + || context.payload + ).user.login; + core.debug(`creator: ${creator}`); - const hasSigned = contributors.includes(creator); - console.log(hasSigned); - core.setOutput('hasSigned', hasSigned); + const has_signed = contributors.includes(creator); + core.setOutput('has_signed', has_signed); + core.debug(`has_signed: ${has_signed}`); # add [cla-signed] label if actor has already signed - name: Add label uses: actions-ecosystem/action-add-labels@v1.1.0 - if: steps.contributors.outputs.hasSigned == 'true' && steps.pr.outputs.hasLabel == 'false' + if: steps.contributors.outputs.has_signed == 'true' && steps.pr.outputs.has_label == 'false' with: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} @@ -107,20 +119,20 @@ runs: # remove [cla-signed] label if actor has not signed yet - name: Remove label uses: actions-ecosystem/action-remove-labels@v1.3.0 - if: steps.contributors.outputs.hasSigned == 'false' && steps.pr.outputs.hasLabel == 'true' + if: steps.contributors.outputs.has_signed == 'false' && steps.pr.outputs.has_label == 'true' with: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} # checkout cla_repo to update cla_path - uses: actions/checkout@v3 - if: steps.contributors.outputs.hasSigned == 'false' + if: steps.contributors.outputs.has_signed == 'false' with: repository: ${{ inputs.cla_repo }} # update cla_path - shell: python - if: steps.contributors.outputs.hasSigned == 'false' + if: steps.contributors.outputs.has_signed == 'false' run: | import json from pathlib import Path @@ -134,7 +146,7 @@ runs: # create PR - uses: peter-evans/create-pull-request@v4 id: cla-pr - if: steps.contributors.outputs.hasSigned == 'false' + if: steps.contributors.outputs.has_signed == 'false' with: push-to-fork: ${{ inputs.cla_fork }} token: ${{ inputs.cla_token }} @@ -149,7 +161,7 @@ runs: # create sticky comment if not signed - name: Create comment uses: marocchino/sticky-pull-request-comment@v2 - if: steps.contributors.outputs.hasSigned == 'false' + if: steps.contributors.outputs.has_signed == 'false' with: number: context.issue.number message: | @@ -160,7 +172,7 @@ runs: # commit status → error - name: Set commit status to error - if: steps.contributors.outputs.hasSigned == 'false' + if: steps.contributors.outputs.has_signed == 'false' uses: conda/actions/set-commit-status@customize-cla-repo with: token: ${{ inputs.token }} @@ -171,7 +183,7 @@ runs: # commit status → success - name: Set commit status to success - if: steps.contributors.outputs.hasSigned == 'true' + if: steps.contributors.outputs.has_signed == 'true' uses: conda/actions/set-commit-status@customize-cla-repo with: token: ${{ inputs.token }} diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index f177b292..25f609e1 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -26,12 +26,12 @@ runs: - uses: actions/github-script@v6 with: script: | - try { - const [owner, repo] = '${{ github.repository }}'.split('/', 2); - core.debug(`owner: ${owner}`); - core.debug(`repo: ${repo}`); + const [owner, repo] = '${{ github.repository }}'.split('/'); + core.debug(`owner: ${owner}`); + core.debug(`repo: ${repo}`); - await github.rest.repos.createCommitStatus({ + try { + var raw = await github.rest.repos.createCommitStatus({ context: '${{ inputs.context }}', description: '${{ inputs.description }}', owner: owner, @@ -40,7 +40,7 @@ runs: state: '${{ inputs.state }}', target_url: '${{ inputs.target_url }}' }); - core.info('Updated build status: ${{ inputs.state }}'); } catch (error) { throw new Error(`error while setting commit status: ${error}`); } + core.info(`${raw.data.context} is ${raw.data.state}`); From b3b99400d872d50839beccf5dfb4fc5515df3926 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 17:27:54 -0500 Subject: [PATCH 09/30] Set author/committer and delete branch on merge --- check-cla/action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/check-cla/action.yml b/check-cla/action.yml index a01e685a..2c28d4c5 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -151,7 +151,10 @@ runs: push-to-fork: ${{ inputs.cla_fork }} token: ${{ inputs.cla_token }} branch: cla-${{ github.actor }} + delete-branch: true commit-message: Adding CLA singee ${{ github.actor }} + author: Conda Bot <18747875+conda-bot@users.noreply.github.com> + committer: Conda Bot <18747875+conda-bot@users.noreply.github.com> title: Adding CLA singee ${{ github.actor }} body: | Adding CLA signee @${{ github.actor }} From 1542cb430f5863bca7d92ddd3e863bc875496491 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Tue, 4 Apr 2023 17:43:03 -0500 Subject: [PATCH 10/30] debugging --- check-cla/action.yml | 35 +++++++++++++---------------------- set-commit-status/action.yml | 25 ++++++++++++------------- 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 2c28d4c5..4ccf620e 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -16,7 +16,7 @@ inputs: description: Path to the CLA signees file within the provided `cla_repo` default: .clabot cla_fork: - description: Fork of cla_repo in which to create branch + description: Fork of `cla_repo` in which to create branch default: conda-bot/infrastructure cla_token: description: Token for opening singee PR in `cla_fork` @@ -36,15 +36,11 @@ runs: core.debug(`repo: ${repo}`); core.debug(`number: ${number}`); - try { - var raw = await github.rest.pulls.get({ - owner: owner, - repo: repo, - pull_number: number - }); - } catch (error) { - throw new Error(`error retrieving PR: ${error}`); - } + const raw = await github.rest.pulls.get({ + owner: owner, + repo: repo, + pull_number: number + }); const sha = raw.data.head.sha; core.setOutput('sha', sha); @@ -78,16 +74,11 @@ runs: core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); - try { - var raw = await github.rest.repos.getContent({ - owner: owner, - repo: repo, - path: '${{ inputs.cla_path }}' - }); - } catch (error) { - throw new Error(`error retrieving contributors: ${error}`) - } - + const raw = await github.rest.repos.getContent({ + owner: owner, + repo: repo, + path: '${{ inputs.cla_path }}' + }); const contributors = JSON.parse( Buffer.from( raw.data.content, @@ -113,7 +104,7 @@ runs: uses: actions-ecosystem/action-add-labels@v1.1.0 if: steps.contributors.outputs.has_signed == 'true' && steps.pr.outputs.has_label == 'false' with: - github_token: ${{ inputs.token }} + github-token: ${{ inputs.token }} labels: ${{ inputs.label }} # remove [cla-signed] label if actor has not signed yet @@ -121,7 +112,7 @@ runs: uses: actions-ecosystem/action-remove-labels@v1.3.0 if: steps.contributors.outputs.has_signed == 'false' && steps.pr.outputs.has_label == 'true' with: - github_token: ${{ inputs.token }} + github-token: ${{ inputs.token }} labels: ${{ inputs.label }} # checkout cla_repo to update cla_path diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 25f609e1..d5950a6c 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -25,22 +25,21 @@ runs: steps: - uses: actions/github-script@v6 with: + github-token: ${{ inputs.token }} script: | const [owner, repo] = '${{ github.repository }}'.split('/'); + const sha = context.payload?.pull_request?.head?.sha; core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); + core.debug(`sha: ${sha}`); - try { - var raw = await github.rest.repos.createCommitStatus({ - context: '${{ inputs.context }}', - description: '${{ inputs.description }}', - owner: owner, - repo: repo, - sha: '${{ github.sha }}', - state: '${{ inputs.state }}', - target_url: '${{ inputs.target_url }}' - }); - } catch (error) { - throw new Error(`error while setting commit status: ${error}`); - } + const raw = await github.rest.repos.createCommitStatus({ + context: '${{ inputs.context }}', + description: '${{ inputs.description }}', + owner: owner, + repo: repo, + sha: sha, + state: '${{ inputs.state }}', + target_url: '${{ inputs.target_url }}' + }); core.info(`${raw.data.context} is ${raw.data.state}`); From 261fc099b996c03174e85632f44f3b9adf61dd51 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 00:18:31 -0500 Subject: [PATCH 11/30] Remove unused sha and labels --- check-cla/action.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 4ccf620e..60dda220 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -25,12 +25,14 @@ inputs: runs: using: composite steps: - # sha, labels, has_label - - name: Get PR metadata + # has_label + - name: Get PR labels id: pr uses: actions/github-script@v6 with: script: | + console.log(context.payload); + const { owner, repo, number } = context.issue; core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); @@ -42,12 +44,7 @@ runs: pull_number: number }); - const sha = raw.data.head.sha; - core.setOutput('sha', sha); - core.debug(`sha: ${sha}`); - const labels = raw.data.labels.map(label => label.name) - core.setOutput('labels', labels); core.debug(`labels: ${labels}`); const has_label = labels.includes('${{ inputs.label }}') From 192862654ef7cc3273d0e68af2d115784bfa1866 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 00:26:17 -0500 Subject: [PATCH 12/30] Update ids --- check-cla/action.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 60dda220..38f601a9 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -27,12 +27,10 @@ runs: steps: # has_label - name: Get PR labels - id: pr + id: labels uses: actions/github-script@v6 with: script: | - console.log(context.payload); - const { owner, repo, number } = context.issue; core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); @@ -43,7 +41,6 @@ runs: repo: repo, pull_number: number }); - const labels = raw.data.labels.map(label => label.name) core.debug(`labels: ${labels}`); @@ -60,7 +57,7 @@ runs: state: pending description: Checking conda CLA... - # contributors, has_signed + # has_signed - name: Check if current actor has signed uses: actions/github-script@v6 id: contributors @@ -82,7 +79,6 @@ runs: raw.data.encoding ).toString('utf-8') ).contributors; - core.setOutput('contributors', contributors); core.debug(`contributors: ${contributors}`); const creator = ( @@ -99,7 +95,7 @@ runs: # add [cla-signed] label if actor has already signed - name: Add label uses: actions-ecosystem/action-add-labels@v1.1.0 - if: steps.contributors.outputs.has_signed == 'true' && steps.pr.outputs.has_label == 'false' + if: steps.contributors.outputs.has_signed == 'true' && steps.labels.outputs.has_label == 'false' with: github-token: ${{ inputs.token }} labels: ${{ inputs.label }} @@ -107,7 +103,7 @@ runs: # remove [cla-signed] label if actor has not signed yet - name: Remove label uses: actions-ecosystem/action-remove-labels@v1.3.0 - if: steps.contributors.outputs.has_signed == 'false' && steps.pr.outputs.has_label == 'true' + if: steps.contributors.outputs.has_signed == 'false' && steps.labels.outputs.has_label == 'true' with: github-token: ${{ inputs.token }} labels: ${{ inputs.label }} @@ -133,7 +129,7 @@ runs: # create PR - uses: peter-evans/create-pull-request@v4 - id: cla-pr + id: pull if: steps.contributors.outputs.has_signed == 'false' with: push-to-fork: ${{ inputs.cla_fork }} @@ -158,7 +154,7 @@ runs: message: | We require contributors to sign our [Contributor License Agreement](https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement) and we don't have one on file for @${{ github.event.pull_request.user.login }}. - In order for us to review and merge your code, please e-sign the [Contributor License Agreement PDF](https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement). We then need to manually verify your signature, merge the PR (${{ steps.cla-pr.outputs.pull-request-url }}), and ping the bot to refresh the PR. + In order for us to review and merge your code, please e-sign the [Contributor License Agreement PDF](https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement). We then need to manually verify your signature, merge the PR (${{ steps.pull.outputs.pull-request-url }}), and ping the bot to refresh the PR. GITHUB_TOKEN: ${{ inputs.token }} # commit status → error From 00ae91fe0c8f386a9d64877261d5bf734748522b Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 00:34:20 -0500 Subject: [PATCH 13/30] Allow custom author/committer --- check-cla/README.md | 3 +++ check-cla/action.yml | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/check-cla/README.md b/check-cla/README.md index 7d4f1da9..6fe19cd3 100644 --- a/check-cla/README.md +++ b/check-cla/README.md @@ -49,4 +49,7 @@ jobs: # [required] # Token for opening singee PR in the provided `cla_repo` cla_token: + # Git-format author/committer to use for pull request commits + # (default: Conda Bot <18747875+conda-bot@users.noreply.github.com>) + cla_author: ``` diff --git a/check-cla/action.yml b/check-cla/action.yml index 38f601a9..969e5d04 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -21,6 +21,9 @@ inputs: cla_token: description: Token for opening singee PR in `cla_fork` required: true + cla_author: + description: Git-format author/committer to use for pull request commits + default: Conda Bot <18747875+conda-bot@users.noreply.github.com> runs: using: composite @@ -137,8 +140,8 @@ runs: branch: cla-${{ github.actor }} delete-branch: true commit-message: Adding CLA singee ${{ github.actor }} - author: Conda Bot <18747875+conda-bot@users.noreply.github.com> - committer: Conda Bot <18747875+conda-bot@users.noreply.github.com> + author: ${{ inputs.cla_author }} + committer: ${{ inputs.cla_author }} title: Adding CLA singee ${{ github.actor }} body: | Adding CLA signee @${{ github.actor }} From 8eee82ebc337a48d12bd550be7f76e348a8b325d Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 00:46:27 -0500 Subject: [PATCH 14/30] Fix json formatting, update PR url --- check-cla/action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 969e5d04..5393266f 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -67,7 +67,7 @@ runs: with: github-token: ${{ inputs.token }} script: | - const [owner, repo] = '${{ inputs.cla_repo }}'.split('/'); + const { owner, repo } = context.issue; core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); @@ -128,7 +128,7 @@ runs: signees = json.loads(path.read_text()) signees["contributors"].append("${{ github.actor }}") signees["contributors"].sort() - path.write_text(json.dumps(signees)) + path.write_text(json.dumps(signees, indent=2)) # create PR - uses: peter-evans/create-pull-request@v4 @@ -146,7 +146,7 @@ runs: body: | Adding CLA signee @${{ github.actor }} - Xref ${{ github.event.pull_request.url }} + Xref ${{ github.event.pull_request.html_url }} # create sticky comment if not signed - name: Create comment From 4729d1705f5ca4dc57bc1373cd927a56b9984737 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 00:54:11 -0500 Subject: [PATCH 15/30] Fix inputs --- check-cla/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 5393266f..36db44a4 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -100,7 +100,7 @@ runs: uses: actions-ecosystem/action-add-labels@v1.1.0 if: steps.contributors.outputs.has_signed == 'true' && steps.labels.outputs.has_label == 'false' with: - github-token: ${{ inputs.token }} + github_token: ${{ inputs.token }} labels: ${{ inputs.label }} # remove [cla-signed] label if actor has not signed yet @@ -108,7 +108,7 @@ runs: uses: actions-ecosystem/action-remove-labels@v1.3.0 if: steps.contributors.outputs.has_signed == 'false' && steps.labels.outputs.has_label == 'true' with: - github-token: ${{ inputs.token }} + github_token: ${{ inputs.token }} labels: ${{ inputs.label }} # checkout cla_repo to update cla_path From b2db3230e23ccd09accef27ffae628a1c6dd4517 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 01:02:15 -0500 Subject: [PATCH 16/30] Fallback sha --- set-commit-status/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index d5950a6c..3bb0d082 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -28,7 +28,7 @@ runs: github-token: ${{ inputs.token }} script: | const [owner, repo] = '${{ github.repository }}'.split('/'); - const sha = context.payload?.pull_request?.head?.sha; + const sha = context.payload?.pull_request?.head?.sha || '${{ github.sha }}'; core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); core.debug(`sha: ${sha}`); From 9bdcc51f2520cfbb526265a8ecd627e2ae356b41 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 01:07:34 -0500 Subject: [PATCH 17/30] debugging comment payload --- set-commit-status/action.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 3bb0d082..58ae165a 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -27,8 +27,13 @@ runs: with: github-token: ${{ inputs.token }} script: | - const [owner, repo] = '${{ github.repository }}'.split('/'); - const sha = context.payload?.pull_request?.head?.sha || '${{ github.sha }}'; + const { owner, repo, number } = context.issue; + const raw = await github.rest.pulls.get({ + owner: owner, + repo: repo, + pull_number: number, + }); + const sha = raw.data.head.sha; core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); core.debug(`sha: ${sha}`); From 43ec963678094e15bee50c51e10ee4364014929c Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 01:18:18 -0500 Subject: [PATCH 18/30] Remove temporary raw const --- check-cla/action.yml | 9 +++------ set-commit-status/action.yml | 11 +++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 36db44a4..08df180b 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -71,16 +71,13 @@ runs: core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); - const raw = await github.rest.repos.getContent({ + const { content, encoding } = (await github.rest.repos.getContent({ owner: owner, repo: repo, path: '${{ inputs.cla_path }}' - }); + })).data; const contributors = JSON.parse( - Buffer.from( - raw.data.content, - raw.data.encoding - ).toString('utf-8') + Buffer.from(content, encoding).toString('utf-8') ).contributors; core.debug(`contributors: ${contributors}`); diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 58ae165a..75f63e57 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -28,17 +28,16 @@ runs: github-token: ${{ inputs.token }} script: | const { owner, repo, number } = context.issue; - const raw = await github.rest.pulls.get({ + const sha = (await github.rest.pulls.get({ owner: owner, repo: repo, pull_number: number, - }); - const sha = raw.data.head.sha; + })).data.head.sha; core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); core.debug(`sha: ${sha}`); - const raw = await github.rest.repos.createCommitStatus({ + const { context: name, state } = (await github.rest.repos.createCommitStatus({ context: '${{ inputs.context }}', description: '${{ inputs.description }}', owner: owner, @@ -46,5 +45,5 @@ runs: sha: sha, state: '${{ inputs.state }}', target_url: '${{ inputs.target_url }}' - }); - core.info(`${raw.data.context} is ${raw.data.state}`); + })).data; + core.info(`${name} is ${state}`); From d8454ec3bc3a6d839b723dbf3c3997145c542231 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 11:52:29 -0500 Subject: [PATCH 19/30] Optional react to comment --- check-cla/action.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/check-cla/action.yml b/check-cla/action.yml index 08df180b..bac90cf3 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -28,6 +28,14 @@ inputs: runs: using: composite steps: + # if triggered by a comment, leave a reaction + - name: Comment Reaction + uses: peter-evans/create-or-update-comment@v3.0.0 + if: github.event_name == 'issue_comment' + with: + comment-id: ${{ github.event.comment.id }} + reactions: rocket + # has_label - name: Get PR labels id: labels From 8ee0ba0d8475f6c01ed2da36307b86dafcfbc3c3 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 12:03:42 -0500 Subject: [PATCH 20/30] Add token to reaction --- check-cla/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/check-cla/action.yml b/check-cla/action.yml index bac90cf3..9f206cc9 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -33,6 +33,7 @@ runs: uses: peter-evans/create-or-update-comment@v3.0.0 if: github.event_name == 'issue_comment' with: + token: ${{ inputs.token }} comment-id: ${{ github.event.comment.id }} reactions: rocket From 5ab536906ceb0d81a860b19c524ba5b45ca9544f Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 12:09:31 -0500 Subject: [PATCH 21/30] Replace rocket with eyes --- check-cla/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 9f206cc9..db152525 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -35,7 +35,7 @@ runs: with: token: ${{ inputs.token }} comment-id: ${{ github.event.comment.id }} - reactions: rocket + reactions: eyes # has_label - name: Get PR labels From ebb06e5927361f1a4b7520512b787ff433603fd7 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 12:22:02 -0500 Subject: [PATCH 22/30] Reduce noise --- check-cla/README.md | 3 +-- check-cla/action.yml | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/check-cla/README.md b/check-cla/README.md index 6fe19cd3..83fcd5f4 100644 --- a/check-cla/README.md +++ b/check-cla/README.md @@ -12,8 +12,7 @@ name: Check CLA on: issue_comment: - types: - - created + types: [created] pull_request_target: jobs: diff --git a/check-cla/action.yml b/check-cla/action.yml index db152525..0ef6e0ef 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -66,8 +66,8 @@ runs: with: token: ${{ inputs.token }} context: CLA check - state: pending description: Checking conda CLA... + state: pending # has_signed - name: Check if current actor has signed @@ -173,8 +173,8 @@ runs: with: token: ${{ inputs.token }} context: CLA check - state: error description: Please follow the details link to sign the conda CLA. → + state: error target_url: https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement # commit status → success @@ -184,5 +184,5 @@ runs: with: token: ${{ inputs.token }} context: CLA check - state: success description: CLA signed, thank you! + state: success From a4ac617eb68332390dc3caea5ed383354cfa5160 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 13:54:36 -0500 Subject: [PATCH 23/30] Include classic PAT instructions --- check-cla/README.md | 3 ++- check-cla/action.yml | 14 ++++++++++---- set-commit-status/README.md | 2 +- set-commit-status/action.yml | 4 +++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/check-cla/README.md b/check-cla/README.md index 83fcd5f4..2c53510a 100644 --- a/check-cla/README.md +++ b/check-cla/README.md @@ -28,7 +28,7 @@ jobs: with: # [required] # A token with ability to comment, label, and modify the commit status - # (`pull_request: write` and `statuses: write`) + # (`pull_request: write` and `statuses: write` for fine-grained PAT; `repo` for classic PAT) # (default: secrets.GITHUB_TOKEN) token: # [required] @@ -47,6 +47,7 @@ jobs: cla_fork: # [required] # Token for opening singee PR in the provided `cla_repo` + # (`pull_request: write` for fine-grained PAT; `repo` and `workflow` for classic PAT) cla_token: # Git-format author/committer to use for pull request commits # (default: Conda Bot <18747875+conda-bot@users.noreply.github.com>) diff --git a/check-cla/action.yml b/check-cla/action.yml index 0ef6e0ef..a1759c78 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -3,7 +3,9 @@ name: CLA check description: Reacts to new PRs and check if the contributor has previously signed the conda contributor license agreement (CLA). inputs: token: - description: 'A token with ability to comment, label, and modify the commit status (`pull_request: write` and `statuses: write`)' + description: >- + A token with ability to comment, label, and modify the commit status + (`pull_request: write` and `statuses: write` for fine-grained PAT; `repo` for classic PAT) default: ${{ github.token }} required: true label: @@ -19,7 +21,9 @@ inputs: description: Fork of `cla_repo` in which to create branch default: conda-bot/infrastructure cla_token: - description: Token for opening singee PR in `cla_fork` + description: >- + Token for opening singee PR in `cla_fork` + (`pull_request: write` for fine-grained PAT; `repo` and `workflow` for classic PAT) required: true cla_author: description: Git-format author/committer to use for pull request commits @@ -161,9 +165,11 @@ runs: with: number: context.issue.number message: | - We require contributors to sign our [Contributor License Agreement](https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement) and we don't have one on file for @${{ github.event.pull_request.user.login }}. + [cla]: https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement + We require contributors to sign our [Contributor License Agreement][cla] and we don't have one on file for @${{ github.event.pull_request.user.login }}. - In order for us to review and merge your code, please e-sign the [Contributor License Agreement PDF](https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement). We then need to manually verify your signature, merge the PR (${{ steps.pull.outputs.pull-request-url }}), and ping the bot to refresh the PR. + In order for us to review and merge your code, please e-sign the [Contributor License Agreement PDF](cla). + We then need to manually verify your signature, merge the PR (${{ steps.pull.outputs.pull-request-url }}), and ping the bot to refresh the PR. GITHUB_TOKEN: ${{ inputs.token }} # commit status → error diff --git a/set-commit-status/README.md b/set-commit-status/README.md index f2502b2c..67cabd50 100644 --- a/set-commit-status/README.md +++ b/set-commit-status/README.md @@ -23,7 +23,7 @@ jobs: with: # [required] # A token with the ability to modify the commit status - # (`statuses: write`) + # (`statuses: write` for fine-grained PAT; `repo` for classic PAT) # (default: secrets.GITHUB_TOKEN) token: diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 75f63e57..4e0a453f 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -3,7 +3,9 @@ name: Set Commit Status description: Modifies the commit status of the most recent commit. inputs: token: - description: 'The GitHub token (`statuses: write`) used to create an authenticated client' + description: >- + A token with the ability to modify the commit status + (`statuses: write` for fine-grained PAT; `repo` for classic PAT) default: ${{ github.token }} required: true context: From 4f67ffb678c60201c97eb339a726e9bc2c8d308f Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 14:31:28 -0500 Subject: [PATCH 24/30] GFM --- check-cla/action.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index a1759c78..7f482032 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -164,12 +164,20 @@ runs: if: steps.contributors.outputs.has_signed == 'false' with: number: context.issue.number - message: | + # GitHub flavored markdown reinvents how paragraphs work, adjoined lines of text are not + # concatenated so instead we rely on YAML multi-line + extra newlines + message: >- [cla]: https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement - We require contributors to sign our [Contributor License Agreement][cla] and we don't have one on file for @${{ github.event.pull_request.user.login }}. - In order for us to review and merge your code, please e-sign the [Contributor License Agreement PDF](cla). - We then need to manually verify your signature, merge the PR (${{ steps.pull.outputs.pull-request-url }}), and ping the bot to refresh the PR. + + We require contributors to sign our [Contributor License Agreement][cla] and we don't + have one on file for @${{ github.event.pull_request.user.login }}. + + + In order for us to review and merge your code, please e-sign the + [Contributor License Agreement PDF][cla]. We then need to manually verify your + signature, merge the PR (${{ steps.pull.outputs.pull-request-url }}), and ping the bot + to refresh the PR. GITHUB_TOKEN: ${{ inputs.token }} # commit status → error From d66d4eb9b1108dbfd315e2d13c584d8942c165b1 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 14:50:29 -0500 Subject: [PATCH 25/30] Extract PR number for sticky comment --- check-cla/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 7f482032..1a778edf 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -163,7 +163,7 @@ runs: uses: marocchino/sticky-pull-request-comment@v2 if: steps.contributors.outputs.has_signed == 'false' with: - number: context.issue.number + number: ${{ (github.event.issue || github.event.pull_request || github.event).number }} # GitHub flavored markdown reinvents how paragraphs work, adjoined lines of text are not # concatenated so instead we rely on YAML multi-line + extra newlines message: >- From 71c4f5592276322ae42395c11c3ce7b39ebf750b Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 14:53:13 -0500 Subject: [PATCH 26/30] Support both PRs and "issues" --- check-cla/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 1a778edf..b1f88ac2 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -156,7 +156,7 @@ runs: body: | Adding CLA signee @${{ github.actor }} - Xref ${{ github.event.pull_request.html_url }} + Xref ${{ (github.event.issue || github.event.pull_request || github.event).html_url }} # create sticky comment if not signed - name: Create comment @@ -171,7 +171,7 @@ runs: We require contributors to sign our [Contributor License Agreement][cla] and we don't - have one on file for @${{ github.event.pull_request.user.login }}. + have one on file for @${{ (github.event.issue || github.event.pull_request || github.event).user.login }}. In order for us to review and merge your code, please e-sign the From 61466991cdd56c4bd919e339234153b0d1f0dd71 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 15:08:09 -0500 Subject: [PATCH 27/30] Extract metadata whether triggered as a PR or "issue" comment --- check-cla/action.yml | 58 +++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index b1f88ac2..c7588bc9 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -73,16 +73,18 @@ runs: description: Checking conda CLA... state: pending - # has_signed - - name: Check if current actor has signed + # number, contributor, url, has_signed + - name: Collect PR metadata uses: actions/github-script@v6 - id: contributors + id: metadata with: github-token: ${{ inputs.token }} script: | - const { owner, repo } = context.issue; + const { owner, repo, number } = context.issue; core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); + core.setOutput('number', number); + core.debug(`number: ${number}`); const { content, encoding } = (await github.rest.repos.getContent({ owner: owner, @@ -94,21 +96,23 @@ runs: ).contributors; core.debug(`contributors: ${contributors}`); - const creator = ( - context.payload.issue - || context.payload.pull_request - || context.payload - ).user.login; - core.debug(`creator: ${creator}`); + const payload = context.payload.issue || context.payload.pull_request || context.payload; + const contributor = payload.user.login; + core.setOutput('contributor', contributor); + core.debug(`contributor: ${contributor}`); + + const url = payload.user.html_url; + core.setOutput('url', url); + core.debug(`url: ${url}`); - const has_signed = contributors.includes(creator); + const has_signed = contributors.includes(contributor); core.setOutput('has_signed', has_signed); core.debug(`has_signed: ${has_signed}`); # add [cla-signed] label if actor has already signed - name: Add label uses: actions-ecosystem/action-add-labels@v1.1.0 - if: steps.contributors.outputs.has_signed == 'true' && steps.labels.outputs.has_label == 'false' + if: steps.metadata.outputs.has_signed == 'true' && steps.labels.outputs.has_label == 'false' with: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} @@ -116,54 +120,54 @@ runs: # remove [cla-signed] label if actor has not signed yet - name: Remove label uses: actions-ecosystem/action-remove-labels@v1.3.0 - if: steps.contributors.outputs.has_signed == 'false' && steps.labels.outputs.has_label == 'true' + if: steps.metadata.outputs.has_signed == 'false' && steps.labels.outputs.has_label == 'true' with: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} # checkout cla_repo to update cla_path - uses: actions/checkout@v3 - if: steps.contributors.outputs.has_signed == 'false' + if: steps.metadata.outputs.has_signed == 'false' with: repository: ${{ inputs.cla_repo }} # update cla_path - shell: python - if: steps.contributors.outputs.has_signed == 'false' + if: steps.metadata.outputs.has_signed == 'false' run: | import json from pathlib import Path path = Path("${{ inputs.cla_path }}") signees = json.loads(path.read_text()) - signees["contributors"].append("${{ github.actor }}") + signees["contributors"].append("${{ steps.metadata.outputs.contributor }}") signees["contributors"].sort() path.write_text(json.dumps(signees, indent=2)) # create PR - uses: peter-evans/create-pull-request@v4 id: pull - if: steps.contributors.outputs.has_signed == 'false' + if: steps.metadata.outputs.has_signed == 'false' with: push-to-fork: ${{ inputs.cla_fork }} token: ${{ inputs.cla_token }} - branch: cla-${{ github.actor }} + branch: cla-${{ steps.metadata.outputs.contributor }} delete-branch: true - commit-message: Adding CLA singee ${{ github.actor }} + commit-message: Adding CLA singee ${{ steps.metadata.outputs.contributor }} author: ${{ inputs.cla_author }} committer: ${{ inputs.cla_author }} - title: Adding CLA singee ${{ github.actor }} + title: Adding CLA singee ${{ steps.metadata.outputs.contributor }} body: | - Adding CLA signee @${{ github.actor }} + Adding CLA signee @${{ steps.metadata.outputs.contributor }} - Xref ${{ (github.event.issue || github.event.pull_request || github.event).html_url }} + Xref ${{ steps.metadata.outputs.url }} # create sticky comment if not signed - name: Create comment uses: marocchino/sticky-pull-request-comment@v2 - if: steps.contributors.outputs.has_signed == 'false' + if: steps.metadata.outputs.has_signed == 'false' with: - number: ${{ (github.event.issue || github.event.pull_request || github.event).number }} + number: ${{ steps.metadata.outputs.number }} # GitHub flavored markdown reinvents how paragraphs work, adjoined lines of text are not # concatenated so instead we rely on YAML multi-line + extra newlines message: >- @@ -171,7 +175,7 @@ runs: We require contributors to sign our [Contributor License Agreement][cla] and we don't - have one on file for @${{ (github.event.issue || github.event.pull_request || github.event).user.login }}. + have one on file for @${{ steps.metadata.outputs.contributor }}. In order for us to review and merge your code, please e-sign the @@ -182,7 +186,7 @@ runs: # commit status → error - name: Set commit status to error - if: steps.contributors.outputs.has_signed == 'false' + if: steps.metadata.outputs.has_signed == 'false' uses: conda/actions/set-commit-status@customize-cla-repo with: token: ${{ inputs.token }} @@ -193,7 +197,7 @@ runs: # commit status → success - name: Set commit status to success - if: steps.contributors.outputs.has_signed == 'true' + if: steps.metadata.outputs.has_signed == 'true' uses: conda/actions/set-commit-status@customize-cla-repo with: token: ${{ inputs.token }} From 5616a98135ce6ec210d44ace17f14a5a7474df65 Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 15:17:02 -0500 Subject: [PATCH 28/30] Group metadata steps --- check-cla/action.yml | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index c7588bc9..ec3171ef 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -41,29 +41,6 @@ runs: comment-id: ${{ github.event.comment.id }} reactions: eyes - # has_label - - name: Get PR labels - id: labels - uses: actions/github-script@v6 - with: - script: | - const { owner, repo, number } = context.issue; - core.debug(`owner: ${owner}`); - core.debug(`repo: ${repo}`); - core.debug(`number: ${number}`); - - const raw = await github.rest.pulls.get({ - owner: owner, - repo: repo, - pull_number: number - }); - const labels = raw.data.labels.map(label => label.name) - core.debug(`labels: ${labels}`); - - const has_label = labels.includes('${{ inputs.label }}') - core.setOutput('has_label', has_label); - core.debug(`has_label: ${has_label}`); - # commit status → pending - name: Set commit status with pending uses: conda/actions/set-commit-status@customize-cla-repo @@ -73,7 +50,7 @@ runs: description: Checking conda CLA... state: pending - # number, contributor, url, has_signed + # has_label, number, contributor, url, has_signed - name: Collect PR metadata uses: actions/github-script@v6 id: metadata @@ -86,6 +63,18 @@ runs: core.setOutput('number', number); core.debug(`number: ${number}`); + const raw = await github.rest.pulls.get({ + owner: owner, + repo: repo, + pull_number: number + }); + const labels = raw.data.labels.map(label => label.name); + core.debug(`labels: ${labels}`); + + const has_label = labels.includes('${{ inputs.label }}'); + core.setOutput('has_label', has_label); + core.debug(`has_label: ${has_label}`); + const { content, encoding } = (await github.rest.repos.getContent({ owner: owner, repo: repo, @@ -112,7 +101,7 @@ runs: # add [cla-signed] label if actor has already signed - name: Add label uses: actions-ecosystem/action-add-labels@v1.1.0 - if: steps.metadata.outputs.has_signed == 'true' && steps.labels.outputs.has_label == 'false' + if: steps.metadata.outputs.has_signed == 'true' && steps.metadata.outputs.has_label == 'false' with: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} @@ -120,7 +109,7 @@ runs: # remove [cla-signed] label if actor has not signed yet - name: Remove label uses: actions-ecosystem/action-remove-labels@v1.3.0 - if: steps.metadata.outputs.has_signed == 'false' && steps.labels.outputs.has_label == 'true' + if: steps.metadata.outputs.has_signed == 'false' && steps.metadata.outputs.has_label == 'true' with: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} From 3c9f7412ddb7cbae8e5c67199ab6edaa2991f1fa Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 15:21:23 -0500 Subject: [PATCH 29/30] Update comments and step names --- check-cla/action.yml | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index ec3171ef..25b93ecb 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -33,7 +33,7 @@ runs: using: composite steps: # if triggered by a comment, leave a reaction - - name: Comment Reaction + - name: React to comment uses: peter-evans/create-or-update-comment@v3.0.0 if: github.event_name == 'issue_comment' with: @@ -98,30 +98,32 @@ runs: core.setOutput('has_signed', has_signed); core.debug(`has_signed: ${has_signed}`); - # add [cla-signed] label if actor has already signed - - name: Add label + # if contributor has already signed, add [cla-signed] label + - name: Add label to PR uses: actions-ecosystem/action-add-labels@v1.1.0 if: steps.metadata.outputs.has_signed == 'true' && steps.metadata.outputs.has_label == 'false' with: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} - # remove [cla-signed] label if actor has not signed yet - - name: Remove label + # if contributor has not signed yet, remove [cla-signed] label + - name: Remove label to PR uses: actions-ecosystem/action-remove-labels@v1.3.0 if: steps.metadata.outputs.has_signed == 'false' && steps.metadata.outputs.has_label == 'true' with: github_token: ${{ inputs.token }} labels: ${{ inputs.label }} - # checkout cla_repo to update cla_path - - uses: actions/checkout@v3 + # if unsigned, checkout cla_repo + - name: Clone CLA singee repo + uses: actions/checkout@v3 if: steps.metadata.outputs.has_signed == 'false' with: repository: ${{ inputs.cla_repo }} - # update cla_path - - shell: python + # if unsigned, update cla_path + - name: Add contributor as a CLA signee + shell: python if: steps.metadata.outputs.has_signed == 'false' run: | import json @@ -133,8 +135,9 @@ runs: signees["contributors"].sort() path.write_text(json.dumps(signees, indent=2)) - # create PR - - uses: peter-evans/create-pull-request@v4 + # if unsigned, create PR + - name: Create PR with new CLA signee + uses: peter-evans/create-pull-request@v4 id: pull if: steps.metadata.outputs.has_signed == 'false' with: @@ -151,8 +154,8 @@ runs: Xref ${{ steps.metadata.outputs.url }} - # create sticky comment if not signed - - name: Create comment + # if unsigned, create sticky comment + - name: Create comment regarding missing CLA signature uses: marocchino/sticky-pull-request-comment@v2 if: steps.metadata.outputs.has_signed == 'false' with: From ae8e19e87de42d826a0c553a229e55ecc7505b9f Mon Sep 17 00:00:00 2001 From: Ken Odegard Date: Wed, 5 Apr 2023 15:23:20 -0500 Subject: [PATCH 30/30] Use correct url --- check-cla/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-cla/action.yml b/check-cla/action.yml index 25b93ecb..953d2f2e 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -90,7 +90,7 @@ runs: core.setOutput('contributor', contributor); core.debug(`contributor: ${contributor}`); - const url = payload.user.html_url; + const url = payload.html_url; core.setOutput('url', url); core.debug(`url: ${url}`);