diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 73ce5355..ce928721 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,22 +4,32 @@ updates: directory: /canary-release schedule: interval: weekly + cooldown: + default-days: 7 - package-ecosystem: github-actions directory: /check-cla schedule: interval: weekly + cooldown: + default-days: 7 - package-ecosystem: github-actions directory: /read-yaml schedule: interval: weekly + cooldown: + default-days: 7 - package-ecosystem: github-actions directory: /set-commit-status schedule: interval: weekly + cooldown: + default-days: 7 - package-ecosystem: pip directory: / schedule: interval: weekly + cooldown: + default-days: 7 - package-ecosystem: github-actions directory: /.github/workflows schedule: @@ -28,3 +38,5 @@ updates: workflows: patterns: - '*' + cooldown: + default-days: 7 diff --git a/.github/workflows/cla-trigger.yml b/.github/workflows/cla-trigger.yml new file mode 100644 index 00000000..ad459694 --- /dev/null +++ b/.github/workflows/cla-trigger.yml @@ -0,0 +1,35 @@ +name: CLA Trigger + +on: + pull_request_target: + types: + - opened + - synchronize + - reopened + +permissions: + contents: read + +jobs: + save-pr-info: + runs-on: ubuntu-latest + steps: + - name: Save PR metadata + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_AUTHOR: ${{ github.event.pull_request.user.login }} + PR_URL: ${{ github.event.pull_request.html_url }} + PR_SHA: ${{ github.event.pull_request.head.sha }} + run: | + mkdir -p pr-info + echo "${PR_NUMBER}" > pr-info/number + echo "${PR_AUTHOR}" > pr-info/author + echo "${PR_URL}" > pr-info/url + echo "${PR_SHA}" > pr-info/sha + + - name: Upload PR info + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: pr-info + path: pr-info/ + retention-days: 1 diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 2749eb23..d0c26eab 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -1,22 +1,61 @@ name: CLA on: + # Triggered by comment to re-check CLA status issue_comment: types: - created - pull_request_target: + + # Triggered after CLA Trigger workflow completes (safer than pull_request_target) + workflow_run: + workflows: [CLA Trigger] + types: + - completed + +permissions: + contents: read + pull-requests: write + statuses: write + actions: read # Required to download artifacts from workflow_run jobs: check: if: >- !github.event.repository.fork && ( - github.event.issue.pull_request - && github.event.comment.body == '@conda-bot check' - || github.event_name == 'pull_request_target' + ( + github.event_name == 'issue_comment' + && github.event.issue.pull_request + && github.event.comment.body == '@conda-bot check' + ) + || ( + github.event_name == 'workflow_run' + && github.event.workflow_run.conclusion == 'success' + ) ) runs-on: ubuntu-latest steps: + # For workflow_run events, download PR info from artifact + - name: Download PR info + if: github.event_name == 'workflow_run' + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: pr-info + path: pr-info/ + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set PR context from artifact + if: github.event_name == 'workflow_run' + id: pr-context + run: | + { + echo "number=$(cat pr-info/number)" + echo "author=$(cat pr-info/author)" + echo "url=$(cat pr-info/url)" + echo "sha=$(cat pr-info/sha)" + } >> "$GITHUB_OUTPUT" + - name: Check CLA uses: conda/actions/check-cla@f05161c6e6e37a49b17c8e0b436197b53830318a # v25.9.2 with: @@ -33,3 +72,9 @@ jobs: # Token for opening signee PR in the provided `cla_repo` # (`pull_request: write` for fine-grained PAT; `repo` and `workflow` for classic PAT) cla_token: ${{ secrets.CLA_FORK_TOKEN }} + + # PR context from workflow_run artifact (if applicable) + pr_number: ${{ steps.pr-context.outputs.number }} + pr_author: ${{ steps.pr-context.outputs.author }} + pr_url: ${{ steps.pr-context.outputs.url }} + pr_sha: ${{ steps.pr-context.outputs.sha }} diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml index 634bf13e..d3d7c4d2 100644 --- a/.github/workflows/issues.yml +++ b/.github/workflows/issues.yml @@ -6,6 +6,10 @@ on: issue_comment: types: [created] +permissions: + contents: read + issues: write + env: FEEDBACK_LBL: pending::feedback SUPPORT_LBL: pending::support diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index b34a5dad..88e15cd9 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -15,6 +15,9 @@ on: default: false type: boolean +permissions: + contents: read + jobs: sync: if: '!github.event.repository.fork' @@ -24,6 +27,8 @@ jobs: LOCAL: .github/labels.yml steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - id: has_local uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0 diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml index 4eda798e..a73cb03a 100644 --- a/.github/workflows/project.yml +++ b/.github/workflows/project.yml @@ -8,6 +8,9 @@ on: types: - opened +permissions: + contents: read + jobs: add_to_project: if: '!github.event.repository.fork' diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 28c85765..2e2067c6 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -95,4 +95,6 @@ jobs: exempt-assignees: mingwandroid - name: Print outputs - run: echo ${{ join(steps.stale.outputs.*, ',') }} + env: + STALE_OUTPUTS: ${{ toJSON(steps.stale.outputs) }} + run: echo "${STALE_OUTPUTS}" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3bbc0744..7379a670 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,6 +13,9 @@ on: # https://crontab.guru/#15_14_*_*_* - cron: 15 14 * * * +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -23,6 +26,8 @@ jobs: steps: - name: Checkout Source uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - name: Cache Pip uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 @@ -52,6 +57,8 @@ jobs: steps: - name: Checkout Source uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - name: Read Remote JSON id: json @@ -80,15 +87,26 @@ jobs: - name: Run Tests shell: python + env: + JSON_CONTENT: ${{ steps.json.outputs.content }} + YAML_CONTENT: ${{ steps.yaml.outputs.content }} + JSON_FOO: ${{ fromJSON(steps.json.outputs.content)['foo'] }} + YAML_FOO: ${{ fromJSON(steps.yaml.outputs.content)['foo'] }} run: | - assert '''${{ steps.json.outputs.content }}''' == '''${{ steps.yaml.outputs.content }}''' - assert '''${{ fromJSON(steps.json.outputs.content)['foo'] }}''' == '''${{ fromJSON(steps.yaml.outputs.content)['foo'] }}''' + import os + assert os.environ['JSON_CONTENT'] == os.environ['YAML_CONTENT'] + assert os.environ['JSON_FOO'] == os.environ['YAML_FOO'] template-files: runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write steps: - name: Checkout Source uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - name: Template Success id: templates-success @@ -136,6 +154,9 @@ jobs: needs: [pytest, read-file, template-files] if: '!cancelled()' runs-on: ubuntu-latest + permissions: + contents: read + issues: write steps: - name: Determine Success uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2 @@ -146,6 +167,8 @@ jobs: - name: Checkout our source if: always() && github.event_name != 'pull_request' && steps.alls-green.outputs.result == 'failure' uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - name: Report failures if: always() && github.event_name != 'pull_request' && steps.alls-green.outputs.result == 'failure' diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 3ee42ebc..e0b68cba 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -12,6 +12,11 @@ on: types: - created +permissions: + contents: read + pull-requests: write + issues: write + jobs: update: if: >- @@ -41,14 +46,17 @@ jobs: - if: github.event.comment.body == '@conda-bot render' name: Configure git origin run: | - echo REPOSITORY=$(curl --silent ${{ github.event.issue.pull_request.url }} | jq --raw-output '.head.repo.full_name') >> $GITHUB_ENV - echo REF=$(curl --silent ${{ github.event.issue.pull_request.url }} | jq --raw-output '.head.ref') >> $GITHUB_ENV + echo "REPOSITORY=$(curl --silent "${PR_URL}" | jq --raw-output '.head.repo.full_name')" >> "$GITHUB_ENV" + echo "REF=$(curl --silent "${PR_URL}" | jq --raw-output '.head.ref')" >> "$GITHUB_ENV" + env: + PR_URL: ${{ github.event.issue.pull_request.url }} - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: repository: ${{ env.REPOSITORY || github.repository }} ref: ${{ env.REF || '' }} token: ${{ secrets.SYNC_TOKEN }} + persist-credentials: false - name: Configure git user run: | @@ -73,7 +81,7 @@ jobs: - if: github.event.comment.body != '@conda-bot render' name: Create fork # no-op if the repository is already forked - run: echo FORK=$(gh repo fork --clone=false --default-branch-only 2>&1 | awk '{print $1}') >> $GITHUB_ENV + run: echo "FORK=$(gh repo fork --clone=false --default-branch-only 2>&1 | awk '{print $1}')" >> "$GITHUB_ENV" env: GH_TOKEN: ${{ secrets.SYNC_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 135634b5..08143550 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,6 +45,14 @@ repos: files: .*/action.(yml|yaml)$ - id: check-github-workflows - id: check-dependabot + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: v1.20.0 + hooks: + - id: zizmor + - repo: https://github.com/rhysd/actionlint + rev: v1.7.9 + hooks: + - id: actionlint - repo: https://github.com/codespell-project/codespell # see setup.cfg rev: v2.4.1 diff --git a/canary-release/action.yml b/canary-release/action.yml index f253329b..addb4828 100644 --- a/canary-release/action.yml +++ b/canary-release/action.yml @@ -65,6 +65,13 @@ runs: shell: bash -l {0} env: BINSTAR_API_TOKEN: ${{ inputs.anaconda-org-token }} + INPUT_CONDA_BUILD_ARGUMENTS: ${{ inputs.conda-build-arguments }} + INPUT_CONDA_BUILD_PATH: ${{ inputs.conda-build-path }} + INPUT_SUBDIR: ${{ inputs.subdir }} + INPUT_PACKAGE_NAME: ${{ inputs.package-name }} + INPUT_UPLOAD: ${{ inputs.upload }} + INPUT_ANACONDA_ORG_CHANNEL: ${{ inputs.anaconda-org-channel }} + INPUT_ANACONDA_ORG_LABEL: ${{ inputs.anaconda-org-label }} run: | echo "::group::Setting up environment" set -euo pipefail @@ -89,36 +96,36 @@ runs: echo "::endgroup::" echo "::group::Building package" - conda build --croot=./pkgs ${{ inputs.conda-build-arguments }} ${{ inputs.conda-build-path }} + conda build --croot=./pkgs ${INPUT_CONDA_BUILD_ARGUMENTS} ${INPUT_CONDA_BUILD_PATH} echo "::endgroup::" echo "::group::Find packages" PACKAGES=( $( - find "./pkgs/${{ inputs.subdir }}" -type f \ + find "./pkgs/${INPUT_SUBDIR}" -type f \ \( \ - -name "${{ inputs.package-name }}-*.tar.bz2" -o \ - -name "${{ inputs.package-name }}-*.conda" \ + -name "${INPUT_PACKAGE_NAME}-*.tar.bz2" -o \ + -name "${INPUT_PACKAGE_NAME}-*.conda" \ \) ) ) echo "::endgroup::" - if [[ "${{ inputs.upload }}" == "true" ]]; then + if [[ "${INPUT_UPLOAD}" == "true" ]]; then echo "::group::Uploading package" anaconda \ upload \ --force \ --register \ --no-progress \ - --user="${{ inputs.anaconda-org-channel }}" \ - --label="${{ inputs.anaconda-org-label }}" \ + --user="${INPUT_ANACONDA_ORG_CHANNEL}" \ + --label="${INPUT_ANACONDA_ORG_LABEL}" \ "${PACKAGES[@]}" echo "Uploaded the following files:" basename -a "${PACKAGES[@]}" echo "::endgroup::" echo "Use this command to try out the build:" - echo "conda install -c ${{ inputs.anaconda-org-channel }}/label/${{ inputs.anaconda-org-label }} ${{ inputs.package-name }}" + echo "conda install -c ${INPUT_ANACONDA_ORG_CHANNEL}/label/${INPUT_ANACONDA_ORG_LABEL} ${INPUT_PACKAGE_NAME}" else echo "Skipping upload because 'upload != true'." fi diff --git a/check-cla/action.yml b/check-cla/action.yml index 0c153b73..a39c249b 100644 --- a/check-cla/action.yml +++ b/check-cla/action.yml @@ -27,6 +27,19 @@ inputs: cla_author: description: Git-format author/committer to use for pull request commits default: Conda Bot <18747875+conda-bot@users.noreply.github.com> + # Optional inputs for workflow_run trigger (when context.issue is not available) + pr_number: + description: PR number (optional, for workflow_run triggers) + required: false + pr_author: + description: PR author username (optional, for workflow_run triggers) + required: false + pr_url: + description: PR URL (optional, for workflow_run triggers) + required: false + pr_sha: + description: PR head SHA (optional, for workflow_run triggers) + required: false runs: using: composite @@ -53,10 +66,23 @@ runs: - name: Collect PR metadata uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd id: metadata + env: + INPUT_LABEL: ${{ inputs.label }} + INPUT_CLA_REPO: ${{ inputs.cla_repo }} + INPUT_CLA_PATH: ${{ inputs.cla_path }} + INPUT_PR_NUMBER: ${{ inputs.pr_number }} + INPUT_PR_AUTHOR: ${{ inputs.pr_author }} + INPUT_PR_URL: ${{ inputs.pr_url }} with: github-token: ${{ inputs.token }} script: | - const { owner, repo, number } = context.issue; + const { owner, repo } = context.repo; + + // Use provided inputs or fall back to context + const number = process.env.INPUT_PR_NUMBER + ? parseInt(process.env.INPUT_PR_NUMBER, 10) + : context.issue.number; + core.debug(`owner: ${owner}`); core.debug(`repo: ${repo}`); core.setOutput('number', number); @@ -70,27 +96,28 @@ runs: const labels = raw.data.labels.map(label => label.name); core.debug(`labels: ${labels}`); - const has_label = labels.includes('${{ inputs.label }}'); + const has_label = labels.includes(process.env.INPUT_LABEL); core.setOutput('has_label', has_label); core.debug(`has_label: ${has_label}`); - const cla_repo = '${{ inputs.cla_repo }}'.split('/', 2); + const cla_repo = process.env.INPUT_CLA_REPO.split('/', 2); const { content, encoding } = (await github.rest.repos.getContent({ owner: cla_repo[0], repo: cla_repo[1], - path: '${{ inputs.cla_path }}' + path: process.env.INPUT_CLA_PATH })).data; const contributors = JSON.parse( Buffer.from(content, encoding).toString('utf-8') ).contributors; core.debug(`contributors: ${contributors}`); - const payload = context.payload.issue || context.payload.pull_request || context.payload; - const contributor = payload.user.login; + // Use provided author or get from PR data + const contributor = process.env.INPUT_PR_AUTHOR || raw.data.user.login; core.setOutput('contributor', contributor); core.debug(`contributor: ${contributor}`); - const url = payload.html_url; + // Use provided URL or get from PR data + const url = process.env.INPUT_PR_URL || raw.data.html_url; core.setOutput('url', url); core.debug(`url: ${url}`); @@ -120,18 +147,23 @@ runs: if: steps.metadata.outputs.has_signed == 'false' with: repository: ${{ inputs.cla_repo }} + persist-credentials: false # if unsigned, update cla_path - name: Add contributor as a CLA signee shell: python if: steps.metadata.outputs.has_signed == 'false' + env: + INPUT_CLA_PATH: ${{ inputs.cla_path }} + CONTRIBUTOR: ${{ steps.metadata.outputs.contributor }} run: | import json + import os from pathlib import Path - path = Path("${{ inputs.cla_path }}") + path = Path(os.environ["INPUT_CLA_PATH"]) signees = json.loads(path.read_text()) - signees["contributors"].append("${{ steps.metadata.outputs.contributor }}") + signees["contributors"].append(os.environ["CONTRIBUTOR"]) signees["contributors"].sort(key=str.lower) path.write_text(json.dumps(signees, indent=2) + "\n") diff --git a/combine-durations/action.yml b/combine-durations/action.yml index d01d9f86..9198284b 100644 --- a/combine-durations/action.yml +++ b/combine-durations/action.yml @@ -38,20 +38,24 @@ runs: shell: bash run: > gh run list - --repo ${{ inputs.repository }} - --branch ${{ inputs.branch }} - --workflow ${{ inputs.workflow }} + --repo "${INPUT_REPOSITORY}" + --branch "${INPUT_BRANCH}" + --workflow "${INPUT_WORKFLOW}" --limit 10 --json databaseId --jq '.[].databaseId' | xargs -n 1 gh run download - --repo ${{ inputs.repository }} + --repo "${INPUT_REPOSITORY}" --dir ${{ runner.temp }}/artifacts/ - --pattern '${{ inputs.pattern }}' + --pattern "${INPUT_PATTERN}" || true env: GITHUB_TOKEN: ${{ github.token }} + INPUT_REPOSITORY: ${{ inputs.repository }} + INPUT_BRANCH: ${{ inputs.branch }} + INPUT_WORKFLOW: ${{ inputs.workflow }} + INPUT_PATTERN: ${{ inputs.pattern }} # `hashFiles` only works on files within the working directory, since `requirements.txt` # is not in the working directory we need to manually compute the SHA256 hash @@ -84,5 +88,7 @@ runs: shell: bash run: > python ${{ github.action_path }}/combine_durations.py - --durations-dir=${{ inputs.durations-dir }} + --durations-dir="${INPUT_DURATIONS_DIR}" --artifacts-dir=${{ runner.temp }}/artifacts/ + env: + INPUT_DURATIONS_DIR: ${{ inputs.durations-dir }} diff --git a/create-fork/action.yml b/create-fork/action.yml index 98f96896..7d7a64c3 100644 --- a/create-fork/action.yml +++ b/create-fork/action.yml @@ -33,7 +33,7 @@ runs: RESPONSE=$(gh api \ -X POST \ -H "Accept: application/vnd.github+json" \ - "/repos/${{ inputs.repository }}/forks" \ + "/repos/${INPUT_REPOSITORY}/forks" \ -f default_branch_only=true) # extract values with jq @@ -43,9 +43,11 @@ runs: # wait a minute to ensure the fork is ready TIMESTAMP="$(date -d "${CREATED_AT}" +%s)" CURRENT="$(date +%s)" - [ $((CURRENT - TIMESTAMP)) -gt 60 ] || sleep ${{ inputs.timeout }} + [ $((CURRENT - TIMESTAMP)) -gt 60 ] || sleep "${INPUT_TIMEOUT}" # store values for subsequent usage echo fork="${FULL_NAME}" >> $GITHUB_OUTPUT env: GH_TOKEN: ${{ inputs.token }} + INPUT_REPOSITORY: ${{ inputs.repository }} + INPUT_TIMEOUT: ${{ inputs.timeout }} diff --git a/read-file/action.yml b/read-file/action.yml index 53989093..f0ea2554 100644 --- a/read-file/action.yml +++ b/read-file/action.yml @@ -52,8 +52,11 @@ runs: shell: bash run: > python ${{ github.action_path }}/read_file.py - ${{ inputs.path }} - ${{ inputs.parser && format('"--parser={0}"', inputs.parser) || '' }} - ${{ inputs.default && format('"--default={0}"', inputs.default) || '' }} + "${INPUT_PATH}" + ${INPUT_PARSER:+"--parser=${INPUT_PARSER}"} + ${INPUT_DEFAULT:+"--default=${INPUT_DEFAULT}"} env: GITHUB_TOKEN: ${{ github.token }} + INPUT_PATH: ${{ inputs.path }} + INPUT_PARSER: ${{ inputs.parser }} + INPUT_DEFAULT: ${{ inputs.default }} diff --git a/read-yaml/action.yml b/read-yaml/action.yml index edb953be..3f1c9947 100644 --- a/read-yaml/action.yml +++ b/read-yaml/action.yml @@ -22,6 +22,9 @@ runs: shell: bash -l {0} - id: read_yaml uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd + env: + INPUT_PATH: ${{ inputs.path }} + INPUT_KEY: ${{ inputs.key }} with: script: | const yaml = require('js-yaml'); @@ -90,8 +93,8 @@ runs: } async function main() { - const path = "${{ inputs.path }}"; - const key = `${{ inputs.key }}`.trim(); + const path = process.env.INPUT_PATH; + const key = (process.env.INPUT_KEY || '').trim(); let value = await readYaml(path); if (key) { diff --git a/set-commit-status/action.yml b/set-commit-status/action.yml index 4b1e5613..6c41ccc8 100644 --- a/set-commit-status/action.yml +++ b/set-commit-status/action.yml @@ -25,6 +25,11 @@ runs: using: composite steps: - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd + env: + INPUT_CONTEXT: ${{ inputs.context }} + INPUT_DESCRIPTION: ${{ inputs.description }} + INPUT_STATE: ${{ inputs.state }} + INPUT_TARGET_URL: ${{ inputs.target_url }} with: github-token: ${{ inputs.token }} script: | @@ -39,12 +44,12 @@ runs: core.debug(`sha: ${sha}`); const { context: name, state } = (await github.rest.repos.createCommitStatus({ - context: '${{ inputs.context }}', - description: '${{ inputs.description }}', + context: process.env.INPUT_CONTEXT, + description: process.env.INPUT_DESCRIPTION, owner: owner, repo: repo, sha: sha, - state: '${{ inputs.state }}', - target_url: '${{ inputs.target_url }}' + state: process.env.INPUT_STATE, + target_url: process.env.INPUT_TARGET_URL })).data; core.info(`${name} is ${state}`); diff --git a/template-files/action.yml b/template-files/action.yml index 73ca89a3..4b716021 100644 --- a/template-files/action.yml +++ b/template-files/action.yml @@ -56,7 +56,9 @@ runs: shell: bash run: > python ${{ github.action_path }}/template_files.py - --config ${{ inputs.config }} - --stubs ${{ inputs.stubs }} + --config "${INPUT_CONFIG}" + --stubs "${INPUT_STUBS}" env: GITHUB_TOKEN: ${{ github.token }} + INPUT_CONFIG: ${{ inputs.config }} + INPUT_STUBS: ${{ inputs.stubs }} diff --git a/zizmor.yml b/zizmor.yml new file mode 100644 index 00000000..922d8f24 --- /dev/null +++ b/zizmor.yml @@ -0,0 +1,23 @@ +# zizmor configuration file +# https://docs.zizmor.sh/configuration/ + +rules: + dangerous-triggers: + ignore: + # cla-trigger.yml uses pull_request_target but is safe because: + # - It does NOT checkout any code from the PR + # - It only saves PR metadata (number, author, url, sha) to artifacts + # - No secrets are used in this workflow + - cla-trigger.yml + + # cla.yml uses workflow_run which is the SAFE alternative to pull_request_target + # - Secrets are only accessed after the trigger workflow completes + # - PR context is passed via artifacts, not from untrusted event payload + # - No code from the PR is ever checked out or executed + - cla.yml + + # project.yml uses pull_request_target but is safe because: + # - It does NOT checkout any code from the PR + # - It only adds PRs to a GitHub project using actions/add-to-project + # - The only dynamic value used is github.event_name which cannot be spoofed + - project.yml