From c7c6e55ab96f5f5c5d1428bde2688362031689cb Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 22 Sep 2026 11:26:10 -0700 Subject: [PATCH 1/3] ci: add shared zizmor workflow --- .github/workflows/zizmor.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000000..cc1c90fd27 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,20 @@ +name: Zizmor + +on: + push: + branches: + - main + - release/* + pull_request: + schedule: + - cron: '9 12 * * 4' # weekly at 12:09 UTC on Thursday + workflow_dispatch: + +permissions: {} + +jobs: + zizmor: + permissions: + contents: read # for actions/checkout + security-events: write # for zizmor to upload SARIF results + uses: open-telemetry/shared-workflows/.github/workflows/zizmor.yml@d9b812f9924a121c6a8276ea2f9e6f5b622cdd4d # v0.10.0 From ad25b1b6cd8d7142acc2447ae26d9cf84cf4f75f Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:16:12 -0700 Subject: [PATCH 2/3] ci: remediate zizmor findings in Python workflows Pin and scope workflow dependencies, pass PR metadata through environments, and document the remaining publishing exceptions. Assisted-by: GitHub Copilot --- .github/dependabot.yml | 2 ++ .github/workflows/add-to-project.yml | 2 ++ .github/workflows/backport.yml | 1 + .github/workflows/changelog.yml | 12 ++++++++---- .github/workflows/check-links.yml | 12 ++++++++++-- .github/workflows/ci.yml | 8 ++++---- .github/workflows/prepare-patch-release.yml | 7 +++++-- .github/workflows/prepare-release-branch.yml | 8 ++++++-- .github/workflows/templates/ci.yml.j2 | 8 ++++---- .github/zizmor.yml | 14 ++++++++++++++ 10 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 .github/zizmor.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index be006de9a1..ace03dbb25 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,8 @@ version: 2 updates: - package-ecosystem: github-actions directory: / + cooldown: + default-days: 7 groups: github-actions: patterns: diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml index d0d4b5f98d..353ca676ae 100644 --- a/.github/workflows/add-to-project.yml +++ b/.github/workflows/add-to-project.yml @@ -21,6 +21,8 @@ jobs: with: client-id: ${{ vars.OTELBOT_PYTHON_CLIENT_ID }} private-key: ${{ secrets.OTELBOT_PYTHON_PRIVATE_KEY }} + permission-organization-projects: write + permission-pull-requests: read - uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 with: diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 51b072e9e1..907832fdd7 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -36,6 +36,7 @@ jobs: with: client-id: ${{ vars.OTELBOT_CLIENT_ID }} private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }} + permission-pull-requests: write - name: Create pull request env: diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index f06d3953dd..b013efd27b 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -21,6 +21,8 @@ jobs: github.event_name != 'merge_group' && !contains(github.event.pull_request.labels.*.name, 'Skip Changelog') && github.actor != 'otelbot[bot]' + env: + BASE_REF: ${{ github.base_ref }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -29,7 +31,7 @@ jobs: fetch-depth: 0 - name: Fetch base branch - run: git fetch origin ${{ github.base_ref }} --depth=1 + run: git fetch origin "$BASE_REF" --depth=1 - name: Ensure no direct changes to CHANGELOG.md run: | @@ -47,11 +49,13 @@ jobs: run: pip install towncrier==25.8.0 - name: Check for changelog fragment + env: + PR_NUMBER: ${{ github.event.pull_request.number }} run: | - if ! towncrier check --compare-with origin/${{ github.base_ref }}; then + if ! towncrier check --compare-with "origin/$BASE_REF"; then echo "" echo "No changelog fragment found for this PR." - echo "Add a file named .changelog/${{ github.event.pull_request.number }}." + echo "Add a file named .changelog/$PR_NUMBER." echo "where is one of: added, changed, deprecated, removed, fixed" echo "See CONTRIBUTING.md for details." echo "" @@ -63,7 +67,7 @@ jobs: env: PR_NUMBER: ${{ github.event.pull_request.number }} run: | - fragments=$(git diff --diff-filter=A --name-only origin/${{ github.base_ref }} -- '.changelog/*' | grep -v '/\.gitignore$' || true) + fragments=$(git diff --diff-filter=A --name-only "origin/$BASE_REF" -- '.changelog/*' | grep -v '/\.gitignore$' || true) [ -z "$fragments" ] && exit 0 invalid=() while IFS= read -r f; do diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml index 8fef9f7838..86d1cf9944 100644 --- a/.github/workflows/check-links.yml +++ b/.github/workflows/check-links.yml @@ -50,6 +50,8 @@ jobs: files: | **/*.md **/*.rst + json: true + escape_json: false - name: Install markdown-link-check if: steps.changed-files.outputs.any_changed == 'true' @@ -57,22 +59,28 @@ jobs: - name: Check links on push to main if: steps.changed-files.outputs.any_changed == 'true' && github.event_name == 'push' + env: + CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} run: | + mapfile -t changed_files < <(jq -r '.[]' <<< "$CHANGED_FILES") markdown-link-check \ --verbose \ --config .github/workflows/check_links_config.json \ - ${{ steps.changed-files.outputs.all_changed_files }} \ + "${changed_files[@]}" \ || { echo "Check that anchor links are lowercase"; exit 1; } - name: Check new links only on pull requests and merge groups if: steps.changed-files.outputs.any_changed == 'true' && (github.event_name == 'pull_request' || github.event_name == 'merge_group') + env: + CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} run: | + mapfile -t changed_files < <(jq -r '.[]' <<< "$CHANGED_FILES") # Extract URLs only from added lines in the diff to avoid # rate limiting when checking all links in large files like # CHANGELOG.md. Only new/changed links are checked on PRs; # pushes to main still check all links in changed files. git diff "$DIFF_RANGE" -- \ - ${{ steps.changed-files.outputs.all_changed_files }} \ + "${changed_files[@]}" \ | grep '^+' | grep -v '^+++' \ | grep -oP 'https?://[^\s\)\]\"'"'"'`>]+' \ | sort -u > /tmp/new_links.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e927f4c3f..b0b684816f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,13 +19,13 @@ concurrency: jobs: misc: - uses: ./.github/workflows/misc.yml + uses: $/.github/workflows/misc.yml lint: - uses: ./.github/workflows/lint.yml + uses: $/.github/workflows/lint.yml tests: - uses: ./.github/workflows/test.yml + uses: $/.github/workflows/test.yml contrib: - uses: open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml@main + uses: open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml@94a9acc9b4d2943079eea2076289777e5e0dbc7a with: CORE_REPO_SHA: ${{ github.sha }} CONTRIB_REPO_SHA: ${{ github.event_name == 'pull_request' && ( diff --git a/.github/workflows/prepare-patch-release.yml b/.github/workflows/prepare-patch-release.yml index 8951be98eb..419e4ff0e5 100644 --- a/.github/workflows/prepare-patch-release.yml +++ b/.github/workflows/prepare-patch-release.yml @@ -71,6 +71,7 @@ jobs: with: client-id: ${{ vars.OTELBOT_CLIENT_ID }} private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }} + permission-pull-requests: write - name: Create pull request id: create_pr @@ -93,8 +94,9 @@ jobs: if: steps.create_pr.outputs.pr_url != '' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_URL: ${{ steps.create_pr.outputs.pr_url }} run: | - gh pr edit ${{ steps.create_pr.outputs.pr_url }} --add-label "prepare-release" + gh pr edit "$PR_URL" --add-label "prepare-release" - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -132,5 +134,6 @@ jobs: if: steps.backport_pr.outputs.pr_url != '' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_URL: ${{ steps.backport_pr.outputs.pr_url }} run: | - gh pr edit ${{ steps.backport_pr.outputs.pr_url }} --add-label "Skip Changelog" + gh pr edit "$PR_URL" --add-label "Skip Changelog" diff --git a/.github/workflows/prepare-release-branch.yml b/.github/workflows/prepare-release-branch.yml index 15db54d93c..479efc1176 100644 --- a/.github/workflows/prepare-release-branch.yml +++ b/.github/workflows/prepare-release-branch.yml @@ -99,6 +99,7 @@ jobs: with: client-id: ${{ vars.OTELBOT_CLIENT_ID }} private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }} + permission-pull-requests: write - name: Create pull request against the release branch id: create_release_branch_pr @@ -121,8 +122,9 @@ jobs: if: steps.create_release_branch_pr.outputs.pr_url != '' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_URL: ${{ steps.create_release_branch_pr.outputs.pr_url }} run: | - gh pr edit ${{ steps.create_release_branch_pr.outputs.pr_url }} --add-label "prepare-release" + gh pr edit "$PR_URL" --add-label "prepare-release" create-pull-request-against-main: permissions: @@ -196,6 +198,7 @@ jobs: with: client-id: ${{ vars.OTELBOT_CLIENT_ID }} private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }} + permission-pull-requests: write - name: Create pull request against main id: create_main_pr @@ -219,5 +222,6 @@ jobs: if: steps.create_main_pr.outputs.pr_url != '' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_URL: ${{ steps.create_main_pr.outputs.pr_url }} run: | - gh pr edit ${{ steps.create_main_pr.outputs.pr_url }} --add-label "prepare-release" --add-label "Skip Changelog" + gh pr edit "$PR_URL" --add-label "prepare-release" --add-label "Skip Changelog" diff --git a/.github/workflows/templates/ci.yml.j2 b/.github/workflows/templates/ci.yml.j2 index e89cded620..924088e821 100644 --- a/.github/workflows/templates/ci.yml.j2 +++ b/.github/workflows/templates/ci.yml.j2 @@ -19,13 +19,13 @@ concurrency: jobs: misc: - uses: ./.github/workflows/misc.yml + uses: $/.github/workflows/misc.yml lint: - uses: ./.github/workflows/lint.yml + uses: $/.github/workflows/lint.yml tests: - uses: ./.github/workflows/test.yml + uses: $/.github/workflows/test.yml contrib: - uses: open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml@main + uses: open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml@94a9acc9b4d2943079eea2076289777e5e0dbc7a with: CORE_REPO_SHA: ${% raw %}{{ github.sha }}{% endraw %} CONTRIB_REPO_SHA: {% raw %}${{ github.event_name == 'pull_request' && ( diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000000..bf21a8dbcb --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,14 @@ +rules: + adhoc-packages: + ignore: + # This isolated link-check job pins the CLI to v3.12.2. + - check-links.yml:56 + dangerous-triggers: + ignore: + # The project-board job uses PR metadata but never checks out or runs PR code. + - add-to-project.yml:3 + use-trusted-publishing: + ignore: + # TestPyPI and PyPI publishing use existing tokens until trusted publishers are configured. + - release.yml:97 + - release.yml:104 \ No newline at end of file From c1de8165c95785a3dee929c1792ace4e0fb0abe1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Wed, 30 Sep 2026 16:14:37 -0700 Subject: [PATCH 3/3] ci: keep contrib integration workflow on main Assisted-by: GPT-6.1 Sol Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/templates/ci.yml.j2 | 2 +- .github/zizmor.yml | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0b684816f..a24b593f33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: tests: uses: $/.github/workflows/test.yml contrib: - uses: open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml@94a9acc9b4d2943079eea2076289777e5e0dbc7a + uses: open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml@main with: CORE_REPO_SHA: ${{ github.sha }} CONTRIB_REPO_SHA: ${{ github.event_name == 'pull_request' && ( diff --git a/.github/workflows/templates/ci.yml.j2 b/.github/workflows/templates/ci.yml.j2 index 924088e821..3533eb8821 100644 --- a/.github/workflows/templates/ci.yml.j2 +++ b/.github/workflows/templates/ci.yml.j2 @@ -25,7 +25,7 @@ jobs: tests: uses: $/.github/workflows/test.yml contrib: - uses: open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml@94a9acc9b4d2943079eea2076289777e5e0dbc7a + uses: open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml@main with: CORE_REPO_SHA: ${% raw %}{{ github.sha }}{% endraw %} CONTRIB_REPO_SHA: {% raw %}${{ github.event_name == 'pull_request' && ( diff --git a/.github/zizmor.yml b/.github/zizmor.yml index bf21a8dbcb..d7543d11c5 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -7,6 +7,12 @@ rules: ignore: # The project-board job uses PR metadata but never checks out or runs PR code. - add-to-project.yml:3 + unpinned-uses: + config: + policies: + "*": hash-pin + # Contrib integration tests intentionally follow the current workflow on main. + "open-telemetry/opentelemetry-python-contrib/.github/workflows/core_contrib_test.yml": ref-pin use-trusted-publishing: ignore: # TestPyPI and PyPI publishing use existing tokens until trusted publishers are configured.