diff --git a/.github/ISSUE_TEMPLATE/0_bug.yml b/.github/ISSUE_TEMPLATE/0_bug.yml new file mode 100644 index 00000000..82274155 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/0_bug.yml @@ -0,0 +1,77 @@ +name: Bug Report +description: Create a bug report. +labels: + - type::bug +body: + - type: markdown + attributes: + value: | + Because processing new bug reports is time-consuming, we would like to ask you to fill out the following form to the best of your ability and as completely as possible. + + > **Note** + > Bug reports that are incomplete or missing information may be closed as inactionable. + + Since there are already a lot of open issues, please also take a moment to search existing ones to see if your bug has already been reported. If you find something related, please upvote that issue and provide additional details as necessary. + + 💐 Thank you for helping to make Conda better. We would be unable to improve Conda without our community! + - type: checkboxes + id: checks + attributes: + label: Checklist + description: Please confirm and check all of the following options. + options: + - label: I added a descriptive title + required: true + - label: I searched open reports and couldn't find a duplicate + required: true + - type: textarea + id: what + attributes: + label: What happened? + description: What should have happened instead? Please provide as many details as possible. The more information provided, the more likely we are able to replicate your problem and offer a solution. + validations: + required: true + - type: textarea + id: info + attributes: + label: Conda Info + description: | + Let's collect some basic information about your conda install. + + Please run the following command from your command line and paste the output below. + + ```bash + conda info + ``` + render: shell + - type: textarea + id: config + attributes: + label: Conda Config + description: | + Let's collect any customizations you may have for your conda install. + + Please run the following command from your command line and paste the output below. + + ```bash + conda config --show-sources + ``` + render: shell + - type: textarea + id: list + attributes: + label: Conda list + description: | + The packages installed into your environment can offer clues as to the problem you are facing. + + Please activate the environment within which you are encountering this bug, run the following command from your command line, and paste the output below. + + ```bash + conda list --show-channel-urls + ``` + render: shell + - type: textarea + id: context + attributes: + label: Additional Context + description: Include any additional information (or screenshots) that you think would be valuable. diff --git a/.github/ISSUE_TEMPLATE/1_feature.yml b/.github/ISSUE_TEMPLATE/1_feature.yml new file mode 100644 index 00000000..0759aac1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1_feature.yml @@ -0,0 +1,48 @@ +name: Feature Request +description: Create a feature request. +labels: + - type::feature +body: + - type: markdown + attributes: + value: | + Because processing new feature requests is time-consuming, we would like to ask you to fill out the following form to the best of your ability and as completely as possible. + + > **Note** + > Feature requests that are incomplete or missing information may be closed as inactionable. + + Since there are already a lot of open issues, please also take a moment to search existing ones to see if your feature request has already been submitted. If you find something related, please upvote that issue and provide additional details as necessary. + + 💐 Thank you for helping to make Conda better. We would be unable to improve Conda without our community! + - type: checkboxes + id: checks + attributes: + label: Checklist + description: Please confirm and check all of the following options. + options: + - label: I added a descriptive title + required: true + - label: I searched open requests and couldn't find a duplicate + required: true + - type: textarea + id: idea + attributes: + label: What is the idea? + description: Describe what the feature is and the desired state. + validations: + required: true + - type: textarea + id: why + attributes: + label: Why is this needed? + description: Who would benefit from this feature? Why would this add value to them? What problem does this solve? + - type: textarea + id: what + attributes: + label: What should happen? + description: What should be the user experience with the feature? Describe from a user perpective what they would do and see. + - type: textarea + id: context + attributes: + label: Additional Context + description: Include any additional information that you think would be valuable. diff --git a/.github/ISSUE_TEMPLATE/epic.yml b/.github/ISSUE_TEMPLATE/epic.yml new file mode 100644 index 00000000..77dfc7ec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/epic.yml @@ -0,0 +1,46 @@ +name: Epic +description: A collection of related tickets. +labels: + - epic +body: + - type: markdown + attributes: + value: | + This form is intended for grouping and collecting together related tickets to better gauge the scope of a problem/feature. + + If you are attempting to report a bug, propose a new feature, or some other code change please use one of the other forms available. + + > **Note** + > Epics that are incomplete or missing information may be closed as inactionable. + + Since there are already a lot of open issues, please also take a moment to search existing ones to see if a similar epic has already been opened. If you find something related, please upvote that issue and provide additional details as necessary. + + 💐 Thank you for helping to make Conda better. We would be unable to improve Conda without our community! + - type: checkboxes + id: checks + attributes: + label: Checklist + description: Please confirm and check all of the following options. + options: + - label: I added a descriptive title + required: true + - label: I searched open reports and couldn't find a duplicate + required: true + - type: textarea + id: summary + attributes: + label: Summary + description: >- + Define the highlevel objectives to be accomplished in this epic. Include the + bigger picture of what is changing and/or the user story for why the + changes are desired/necessary. + validations: + required: true + - type: textarea + attributes: + label: Linked Issues & PRs + description: List all issues related to this epic. + value: | + - [ ] # + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..7e05692b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,35 @@ + + +### Description + + + +### Checklist - did you ... + + + +- [ ] Add a file to the `news` directory ([using the template](../blob/main/news/TEMPLATE)) for the next release's release notes? + +- [ ] Add / update necessary tests? +- [ ] Add / update outdated documentation? + + diff --git a/.github/workflows/boards.yml b/.github/workflows/boards.yml deleted file mode 100644 index ea9abeaf..00000000 --- a/.github/workflows/boards.yml +++ /dev/null @@ -1,211 +0,0 @@ -name: Automate Boards - -on: - issues: - types: [opened, labeled, unlabeled] - -env: - BACKLOG_LBL: backlog - SPRINT_LBL: sprint - # these variables cannot be used in if expressions - # see https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability - TRIAGING_ID: 4 - TRIAGING_URL: https://api.github.com/projects/13697310 - BACKLOG_ID: 5 - BACKLOG_URL: https://api.github.com/projects/13697370 - SPRINT_ID: 8 - SPRINT_URL: https://api.github.com/projects/13829490 - -jobs: - # new -> Triaging[New] - to_triaging: - # if new issue (or old issue marked as [stale::recovered]) and not [backlog] or [sprint] - if: >- - !github.event.repository.fork - && github.event_name == 'issues' - && ( - ( - github.event.sender.login != 'conda-bot' - && github.event.action == 'opened' - ) - || ( - github.event.action == 'labeled' - && github.event.label.name == 'stale::recovered' - ) - ) - && !contains(github.event.issue.labels.*.name, 'backlog') - && !contains(github.event.issue.labels.*.name, 'sprint') - runs-on: ubuntu-latest - steps: - # add to Triaging board - - uses: alex-page/github-project-automation-plus@v0.8.1 - with: - action: add # if not present - project: Triaging - column: New - repo-token: ${{ secrets.PROJECT_TOKEN }} - - # new -> Backlog[Unplanned] - # Triaging[Ready] -> Backlog[Unplanned] - # Sprint[To Do] -> Backlog[Do Next] - to_backlog: - # if new issue with [backlog] - # if labeled [backlog] - # if added to Backlog board - # if unlabeled [sprint] - # if removed from Sprint board - if: >- - !github.event.repository.fork - && github.event.sender.login != 'conda-bot' - && github.event.issue.state == 'open' - && ( - ( - github.event_name == 'issues' - && github.event.action == 'opened' - && contains(github.event.issue.labels.*.name, 'backlog') - && !contains(github.event.issue.labels.*.name, 'sprint') - ) - || ( - github.event_name == 'issues' - && github.event.action == 'labeled' - && github.event.label.name == 'backlog' - ) - || ( - github.event_name == 'issues' - && github.event.action == 'unlabeled' - && github.event.label.name == 'sprint' - ) - ) - runs-on: ubuntu-latest - steps: - # (helper) access private GitHub Action - - uses: actions/checkout@v2 - # (helper) detect if attached to triaging board - - id: on_triaging - uses: conda/actions/issue-in-project@v1.1 - with: - org: conda - project: ${{ env.TRIAGING_ID }} - issue: ${{ github.event.issue.id }} - github_token: ${{ secrets.PROJECT_TOKEN }} - # (helper) detect if attached to sprint board - - id: on_sprint - uses: conda/actions/issue-in-project@v1.1 - with: - org: conda - project: ${{ env.SPRINT_ID }} - issue: ${{ github.event.issue.id }} - github_token: ${{ secrets.PROJECT_TOKEN }} - # (fail-safe) remove from Triaging board - - uses: alex-page/github-project-automation-plus@v0.8.1 - with: - action: delete # if present - project: Triaging - column: Ready # unused - repo-token: ${{ secrets.PROJECT_TOKEN }} - # add [backlog] label - - uses: actions-ecosystem/action-add-labels@v1.1.0 - with: - labels: ${{ env.BACKLOG_LBL }} - number: ${{ github.event.issue.number }} - github_token: ${{ secrets.PROJECT_TOKEN }} - # add to Backlog board (from Triaging board) - - uses: alex-page/github-project-automation-plus@v0.8.1 - if: >- - fromJSON(steps.on_triaging.outputs.contains) - && !contains(github.event.issue.labels.*.name, 'sprint') - && !fromJSON(steps.on_sprint.outputs.contains) - with: - action: add # if not present - project: Backlog - column: Unplanned - repo-token: ${{ secrets.PROJECT_TOKEN }} - # add to Backlog board (from Sprint board) - - uses: alex-page/github-project-automation-plus@v0.8.1 - if: >- - !fromJSON(steps.on_triaging.outputs.contains) - || contains(github.event.issue.labels.*.name, 'sprint') - || fromJSON(steps.on_sprint.outputs.contains) - with: - action: add # if not present - project: Backlog - column: Do Next - repo-token: ${{ secrets.PROJECT_TOKEN }} - # remove [sprint] label - - uses: actions-ecosystem/action-remove-labels@v1.3.0 - with: - labels: ${{ env.SPRINT_LBL }} - number: ${{ github.event.issue.number }} - github_token: ${{ secrets.PROJECT_TOKEN }} - # remove from Sprint board - - uses: alex-page/github-project-automation-plus@v0.8.1 - with: - action: delete # if present - project: Sprint - column: To Do # unused - repo-token: ${{ secrets.PROJECT_TOKEN }} - - # new -> Sprint[To Do] - # Backlog[Do Next] -> Sprint[To Do] - to_sprint: - # if new issue with [sprint] - # if unlabeled [backlog] - # if removed from Backlog board - # if labeled [sprint] - # if added to Sprint board - if: >- - !github.event.repository.fork - && github.event.sender.login != 'conda-bot' - && github.event.issue.state == 'open' - && ( - ( - github.event_name == 'issues' - && github.event.action == 'opened' - && contains(github.event.issue.labels.*.name, 'sprint') - ) - || ( - github.event_name == 'issues' - && github.event.action == 'unlabeled' - && github.event.label.name == 'backlog' - ) - || ( - github.event_name == 'issues' - && github.event.action == 'labeled' - && github.event.label.name == 'sprint' - ) - ) - runs-on: ubuntu-latest - steps: - # (fail-safe) remove from Triaging board - - uses: alex-page/github-project-automation-plus@v0.8.1 - with: - action: delete # if present - project: Triaging - column: Ready # unused - repo-token: ${{ secrets.PROJECT_TOKEN }} - # remove [backlog] label - - uses: actions-ecosystem/action-remove-labels@v1.3.0 - with: - labels: ${{ env.BACKLOG_LBL }} - number: ${{ github.event.issue.number }} - github_token: ${{ secrets.PROJECT_TOKEN }} - # remove from Backlog board - - uses: alex-page/github-project-automation-plus@v0.8.1 - with: - action: delete # if present - project: Backlog - column: Do Next # unused - repo-token: ${{ secrets.PROJECT_TOKEN }} - # add [sprint] label - - uses: actions-ecosystem/action-add-labels@v1.1.0 - with: - labels: ${{ env.SPRINT_LBL }} - number: ${{ github.event.issue.number }} - github_token: ${{ secrets.PROJECT_TOKEN }} - # add to Sprint board - - uses: alex-page/github-project-automation-plus@v0.8.1 - with: - action: add # if not present - project: Sprint - column: To Do - repo-token: ${{ secrets.PROJECT_TOKEN }} diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 00000000..70eabfb4 --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,31 @@ +name: 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_name == 'pull_request_target' + ) + runs-on: ubuntu-latest + steps: + - name: Check CLA + uses: conda/actions/check-cla@v22.6.0 + with: + # [required] + # label to add when actor has signed the CLA + label: cla-signed + # [required] + # the GitHub Personal Access Token to comment and label with + token: "${{ secrets.CLA_ACTION_TOKEN }}" diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml index 6a89556a..6c4eea15 100644 --- a/.github/workflows/issues.yml +++ b/.github/workflows/issues.yml @@ -1,23 +1,25 @@ name: Automate Issues on: + # NOTE: github.event is issue_comment payload: + # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#issue_comment issue_comment: types: [created] env: - # labels FEEDBACK_LBL: pending::feedback SUPPORT_LBL: pending::support jobs: # NOTE: doesn't catch cases where multiple users act as the author/reporter, # this is just an effort to catch the majority of support cases - # TODO: create conda-triaging team and modify this to toggle label based on - # whether a non-triaging engineer commented + # TODO: create conda-issue-sorting team and modify this to toggle label based on + # whether a non-issue-sorting engineer commented pending_support: # if [pending::feedback] and the author responds if: >- - github.event_name == 'issue_comment' + !github.event.repository.fork + && github.event_name == 'issue_comment' && github.event.action == 'created' && !github.event.issue.pull_request && contains(github.event.issue.labels.*.name, 'pending::feedback') diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 8e9376e7..1c5d49c1 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -1,15 +1,19 @@ name: Sync Labels on: + # NOTE: github.event is workflow_dispatch payload: + # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#workflow_dispatch workflow_dispatch: inputs: dryrun: description: "dryrun: Preview changes to labels without editing them (true|false)" required: true - default: "true" + type: boolean + default: true jobs: sync: + if: '!github.event.repository.fork' runs-on: ubuntu-latest env: GLOBAL: https://raw.githubusercontent.com/conda/infra/main/.github/global.yml diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml new file mode 100644 index 00000000..d4693465 --- /dev/null +++ b/.github/workflows/lock.yml @@ -0,0 +1,59 @@ +name: Lock + +on: + # NOTE: github.event is workflow_dispatch payload: + # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#workflow_dispatch + workflow_dispatch: + # inputs: + # dryrun: + # description: "dryrun: Preview locking issues/prs without marking them (true|false)" + # required: true + # type: boolean + # default: true + + schedule: + - cron: 0 6 * * * + +permissions: + issues: write + pull-requests: write + +jobs: + lock: + if: '!github.event.repository.fork' + runs-on: ubuntu-latest + steps: + # - id: read_yaml + # uses: conda/actions/read-yaml@v22.2.1 + # with: + # path: https://raw.githubusercontent.com/conda/infra/main/.github/messages.yml + - uses: dessant/lock-threads@v2 + with: + # Number of days of inactivity before a closed issue is locked + issue-lock-inactive-days: 365 + # Do not lock issues created before a given timestamp, value must follow ISO 8601 + issue-exclude-created-before: '' + # Do not lock issues with these labels, value must be a comma separated list of labels or '' + issue-exclude-labels: '' + # Labels to add before locking an issue, value must be a comma separated list of labels or '' + issue-lock-labels: 'locked' + # Comment to post before locking an issue + # issue-lock-comment: ${{ fromJSON(steps.read_yaml.outputs.value)['lock-issue'] }} + # Reason for locking an issue, value must be one of resolved, off-topic, too heated, spam or '' + issue-lock-reason: 'resolved' + + # Number of days of inactivity before a closed pull request is locked + pr-lock-inactive-days: 365 + # Do not lock pull requests created before a given timestamp, value must follow ISO 8601 + pr-exclude-created-before: '' + # Do not lock pull requests with these labels, value must be a comma separated list of labels or '' + pr-exclude-labels: '' + # Labels to add before locking a pull request, value must be a comma separated list of labels or '' + pr-lock-labels: 'locked' + # Comment to post before locking a pull request + # pr-lock-comment: ${{ fromJSON(steps.read_yaml.outputs.value)['lock-pr'] }} + # Reason for locking a pull request, value must be one of resolved, off-topic, too heated, spam or '' + pr-lock-reason: 'resolved' + + # Limit locking to only issues or pull requests, value must be one of issues, prs or '' + process-only: '' diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml new file mode 100644 index 00000000..7943d6d7 --- /dev/null +++ b/.github/workflows/project.yml @@ -0,0 +1,19 @@ +name: Add to Project + +on: + issues: + types: + - opened + pull_request_target: + types: + - opened + +jobs: + add_to_project: + if: '!github.event.repository.fork' + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@v0.0.3 + with: + project-url: https://github.com/orgs/conda/projects/2 + github-token: ${{ secrets.PROJECT_TOKEN }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..358b83e0 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,89 @@ +name: Stale + +on: + # NOTE: github.event is workflow_dispatch payload: + # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#workflow_dispatch + workflow_dispatch: + inputs: + dryrun: + description: "dryrun: Preview stale issues/prs without marking them (true|false)" + required: true + type: boolean + default: true + + schedule: + - cron: 0 4 * * * + +jobs: + stale: + if: '!github.event.repository.fork' + runs-on: ubuntu-latest + strategy: + matrix: + # The issues labeled "support" have a more aggressive stale/close timeline from the rest + only-issue-labels: ['type::support', ''] + steps: + - id: read_yaml + uses: conda/actions/read-yaml@v22.2.1 + with: + path: https://raw.githubusercontent.com/conda/infra/main/.github/messages.yml + - uses: actions/stale@v4 + id: stale + with: + # Idle number of days before marking issues stale (default: 60) + days-before-issue-stale: ${{ matrix.only-issue-labels && 21 || 365 }} + # Idle number of days before closing stale issues/PRs (default: 7) + days-before-issue-close: ${{ matrix.only-issue-labels && 7 || 30 }} + # Idle number of days before marking PRs stale (default: 60) + days-before-pr-stale: 365 + # Idle number of days before closing stale PRs (default: 7) + days-before-pr-close: 30 + + # Comment on the staled issues + stale-issue-message: ${{ fromJSON(steps.read_yaml.outputs.value)['stale-issue'] }} + # Comment on the staled issues while closed + # close-issue-message: ${{ fromJSON(steps.read_yaml.outputs.value)['close-issue'] }} + # Comment on the staled PRs + stale-pr-message: ${{ fromJSON(steps.read_yaml.outputs.value)['stale-pr'] }} + # Comment on the staled PRs while closed + # close-pr-message: ${{ fromJSON(steps.read_yaml.outputs.value)['close-pr'] }} + # Label to apply on staled issues + stale-issue-label: 'stale' + # Label to apply on closed issues + close-issue-label: 'stale::closed' + # Label to apply on staled PRs + stale-pr-label: 'stale' + # Label to apply on closed PRs + close-pr-label: 'stale::closed' + + # Issues with these labels will never be considered stale + exempt-issue-labels: 'stale::recovered,epic' + # Issues with these labels will never be considered stale + exempt-pr-labels: 'stale::recovered,epic' + # Only issues with these labels are checked whether they are stale + only-issue-labels: ${{ matrix.only-issue-labels }} + + # Max number of operations per run + operations-per-run: ${{ secrets.STALE_OPERATIONS_PER_RUN || 100 }} + # Remove stale label from issues/PRs on updates/comments + remove-stale-when-updated: true + + # Add specified labels to issues/PRs when they become unstale + labels-to-add-when-unstale: 'stale::recovered' + labels-to-remove-when-unstale: 'stale,stale::closed' + + # Dry-run (default: false) + debug-only: ${{ github.event.inputs.dryrun || false }} + # Order to get issues/PRs (default: false) + ascending: true + # Delete branch after closing a stale PR (default: false) + delete-branch: false + + # Exempt all issues/PRs with milestones from stale + exempt-all-milestones: true + + # Assignees on issues/PRs exempted from stale + exempt-assignees: mingwandroid + + - name: Print outputs + run: echo ${{ join(steps.stale.outputs.*, ',') }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3a8de09e..2ba56431 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ exclude: | )/ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: # standard end of line/end of file cleanup - id: mixed-line-ending @@ -17,7 +17,7 @@ repos: # catch git merge/rebase problems - id: check-merge-conflict - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.5.1 + rev: v3.0.0-alpha.0 hooks: - id: prettier types: [ts] diff --git a/canary-release/action.yml b/canary-release/action.yml index 9539b344..c92e2a7e 100644 --- a/canary-release/action.yml +++ b/canary-release/action.yml @@ -26,6 +26,10 @@ inputs: conda-build-arguments: description: 'Command line arguments for conda-build, inserted before recipe path with no processing.' required: false + conda-build-path: + description: 'The path to the conda recipe passed to conda-build.' + required: false + default: recipe runs: using: "composite" steps: @@ -62,7 +66,11 @@ runs: set -euo pipefail conda activate conda update --yes --quiet conda - conda install --yes --quiet conda-build anaconda-client git + conda install --yes --quiet conda-build anaconda-client + # git needs to be installed after conda-build + # see https://github.com/conda/conda/issues/11758 + # see https://github.com/conda/actions/pull/47 + conda install --yes --quiet git echo "::endgroup::" echo "::group::Debugging information" @@ -72,7 +80,7 @@ runs: echo "::endgroup::" echo "::group::Building package" - conda build --croot=./pkgs ${{ inputs.conda-build-arguments }} conda.recipe + conda build --croot=./pkgs ${{ inputs.conda-build-arguments }} ${{ inputs.conda-build-path }} echo "::endgroup::" echo "::group::Uploading package" diff --git a/check-cla/README.md b/check-cla/README.md new file mode 100644 index 00000000..54b013f6 --- /dev/null +++ b/check-cla/README.md @@ -0,0 +1,43 @@ +# 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. + +## GitHub Action Usage + +In your GitHub repository include the action in your workflows: + +```yaml +name: Contributor license agreement (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 + with: + # [required] + # label to add when actor has signed the CLA + label: cla-signed + # [required] + # the GitHub Personal Access Token to comment and label with + token: ${{ secrets.CLA_ACTION_TOKEN }} +``` diff --git a/check-cla/action.yml b/check-cla/action.yml new file mode 100644 index 00000000..bf89d32a --- /dev/null +++ b/check-cla/action.yml @@ -0,0 +1,136 @@ +name: 'CLA check' +description: 'This action can be used to react to new pull requests and checks if the actor has previously signed the conda contributor license agreement.' +inputs: + token: + description: 'Token for commenting and labelling' + required: true + label: + description: 'Label to use' + required: true + +runs: + using: "composite" + steps: + - 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.setOutput('sha', sha); + + const labels = pullRequest.data.labels.map(label => label.name) + console.log(labels); + core.setOutput('labels', labels); + + const hasLabel = labels.includes('${{ inputs.label }}') + console.log(hasLabel); + core.setOutput('hasLabel', hasLabel); + + - name: Set commit status with pending + uses: Sibz/github-status-action@v1 + with: + authToken: ${{ inputs.token }} + context: "CLA check" + description: Checking conda CLA... + state: "pending" + sha: ${{ steps.pr.outputs.sha || github.sha }} + + - name: Check if current actor has signed + uses: actions/github-script@v6 + id: contributors + with: + github-token: ${{ inputs.token }} + script: | + console.log(context); + const getContributors = async () => { + try { + const results = ( + await github.rest.repos.getContent({ + owner: 'conda', + repo: 'infra', + path: '.clabot' + }) + ); + 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 contributors = await getContributors(); + console.log(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 + - name: Add label + uses: actions/github-script@v6 + if: steps.contributors.outputs.hasSigned == 'true' && steps.pr.outputs.hasLabel == 'false' + with: + github-token: ${{ inputs.token }} + script: | + await github.rest.issues.addLabels({ + ...context.repo, + issue_number: context.issue.number, + labels: ['${{ inputs.label }}'] + }) + + # remove cla-signed label if actor has not signed yet + - name: Remove label + uses: actions/github-script@v6 + if: steps.contributors.outputs.hasSigned == 'false' && steps.pr.outputs.hasLabel == 'true' + with: + github-token: ${{ inputs.token }} + script: | + await github.rest.issues.removeLabel({ + ...context.repo, + issue_number: context.issue.number, + name: '${{ inputs.label }}' + }) + + # create sticky comment if not signed + - name: Create comment + uses: marocchino/sticky-pull-request-comment@v2 + if: steps.contributors.outputs.hasSigned == 'false' + 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 }}. + + 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. We will ping the bot to refresh the PR status when we have confirmed your signature. + GITHUB_TOKEN: ${{ inputs.token }} + + - name: Set commit status to error + if: steps.contributors.outputs.hasSigned == 'false' + uses: Sibz/github-status-action@v1 + with: + authToken: ${{ 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 }} + target_url: https://conda.io/en/latest/contributing.html#conda-contributor-license-agreement + + - name: Set commit status to success + if: steps.contributors.outputs.hasSigned == 'true' + uses: Sibz/github-status-action@v1 + with: + authToken: ${{ inputs.token }} + context: CLA check + description: CLA signed, thank you! + state: success + sha: ${{ steps.pr.outputs.sha || github.sha }} diff --git a/issue-in-project/README.md b/issue-in-project/README.md index 2014a35e..7a819ebe 100644 --- a/issue-in-project/README.md +++ b/issue-in-project/README.md @@ -25,6 +25,10 @@ In your GitHub repository include this action in your workflows: # if not provided return list of issues for the project issue: ${{ github.event.issue.id }} + # [required] + # the github token with read:org access + github_token: ${{ secrets.PROJECT_TOKEN }} + # if issue was provided we get a boolean - if: steps.in_project.outputs.contains == 'true' ... diff --git a/read-yaml/README.md b/read-yaml/README.md index cfb99a70..9c35fb5d 100644 --- a/read-yaml/README.md +++ b/read-yaml/README.md @@ -16,11 +16,12 @@ In your GitHub repository include this action in your workflows: path: https://raw.githubusercontent.com/owner/repo/ref/path/to/yaml.yml # [optional] - # the keys/indices scope to extract - scopes: | - value1: foo.bar.2.baz - value2: foo.bar.5.qux + # the keys to the valye to extract + key: foo.bar.2.baz -- run: echo ${{ steps.read_yaml.outputs.value1 }} -- run: echo ${{ steps.read_yaml.outputs.value2 }} +# if key provided get the value itself +- run: echo ${{ steps.read_yaml.outputs.value }} + +# if no key provided get the entire YAML +- run: echo ${{ fromJSON(steps.read_yaml.outputs.value)['key'] }} ``` diff --git a/user-in-team/README.md b/user-in-team/README.md index 9261b68d..9f701a1f 100644 --- a/user-in-team/README.md +++ b/user-in-team/README.md @@ -23,6 +23,10 @@ In your GitHub repository include this action in your workflows: # if not provided return list of user in team user: conda-bot + # [required] + # the github token with read:org access + github_token: ${{ secrets.PROJECT_TOKEN }} + # if user was provided we get a boolean - if: steps.in_team.outputs.contains == 'true' ...