Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 0 additions & 126 deletions .github/workflows/add-pr-to-project.yml

This file was deleted.

46 changes: 46 additions & 0 deletions .github/workflows/pr-checks-complete.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: PR Checks Complete Sync

# Relays a gating GitHub Actions workflow's completion to the board, so a PR is
# moved to Snagged when its checks fail (and recovered when they pass) in real
# time rather than waiting for the nightly sweep. Copy to
# `.github/workflows/pr-checks-complete.yml`.
#
# Why this is needed: GitHub deliberately does NOT deliver check_suite/check_run
# events for suites created by GitHub Actions (recursion prevention), so a
# check_suite trigger never fires for Actions-based CI. workflow_run IS delivered
# for Actions runs, so it is the event that carries "a gating workflow finished".
#
# IMPORTANT -- customize the `workflows:` list below for THIS repo. workflow_run
# can only reference workflows in the same repo, by their `name:`. List your
# repo's gating workflows: at least the heavyweight CI workflow (usually the last
# to finish, so the whole check rollup has settled when it completes), plus any
# lighter required checks you want reflected the moment they finish rather than
# when CI does. The reusable workflow always recomputes from the WHOLE check
# rollup, so listing a workflow only changes WHEN the recompute runs, not which
# checks it reads.
#
# Do NOT list the board-sync's own callers ("PR Maintenance", "PR Review Fork
# Bridge", "PR Review Fork Apply", "PR Commit Status Sync", and this one) -- a
# workflow_run keyed on them would trigger this caller in a loop.
#
# No conclusion guard: react to every completion (failure -> Snagged, success ->
# recovery); the recompute is idempotent. (workflow_run only fires for workflow
# files on the default branch.)

on:
workflow_run:
workflows:
# slangpy gating Actions workflows (their `name:` fields, not filenames).
# Listing one only affects WHEN board Status is recomputed; the reusable
# workflow always reads the whole check rollup.
- "ci"
- "checks"
types: [completed]

permissions: {}

jobs:
board-sync:
uses: shader-slang/slang/.github/workflows/pr-board-sync.yml@master
secrets:
SLANG_PR_BOT_TOKEN: ${{ secrets.SLANG_PR_BOT_TOKEN }}
Comment thread
jhelferty-nv marked this conversation as resolved.
30 changes: 30 additions & 0 deletions .github/workflows/pr-commit-status.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: PR Commit Status Sync

# Relays external commit statuses (e.g. "SlangPy Tests", "license/cla",
# "CodeRabbit") to the board. Copy to `.github/workflows/pr-commit-status.yml`.
#
# Some PR checks are not GitHub Actions check runs but external commit statuses;
# the reusable workflow folds those into its check rollup (a failing status -> the
# PR is Snagged), but only the `status` event carries them -- check_suite and
# workflow_run cover only Actions suites. Unlike check_suite for Actions CI, the
# `status` event IS delivered here, because these statuses are posted by external
# apps/PATs, not the recursion-suppressed GITHUB_TOKEN.
#
# Generic -- copy verbatim, no per-repo customization needed. Note: `status` is
# repo-wide (it fires for any commit, including non-PR pushes); for a non-PR
# commit the reusable workflow resolves zero open PRs and no-ops.

on:
status: {}

permissions: {}

jobs:
board-sync:
# Skip the initial "pending" each external check posts; only a settled status
# (success -> recovery, failure/error -> Snagged) changes the outcome, and the
# recompute is idempotent regardless.
if: ${{ github.event.state != 'pending' }}
uses: shader-slang/slang/.github/workflows/pr-board-sync.yml@master
secrets:
SLANG_PR_BOT_TOKEN: ${{ secrets.SLANG_PR_BOT_TOKEN }}
57 changes: 57 additions & 0 deletions .github/workflows/pr-maintenance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: PR Maintenance

# Thin caller for the shared PR board-sync reusable workflow. Copy this file to
# `.github/workflows/pr-maintenance.yml` in the consuming repo. It declares the
# PR lifecycle / review triggers and delegates all logic to the central reusable
# workflow in shader-slang/slang. All board IDs default to the shared
# "Slang PR Tracking" board, so no `with:` block is needed -- map only the one
# org-level secret (SLANG_PR_BOT_TOKEN).
#
# Pair this with the other example callers in this directory for full coverage:
# - example-pr-checks-complete.yml CI / gating-check results -> board
# - example-pr-commit-status.yml external commit statuses -> board
# - example-pr-review-fork-bridge.yml + example-pr-review-fork-apply.yml
# real-time fork-PR review handling
#
# Why these triggers: pull_request_target and check_suite receive the secret even
# for fork PRs, so they run here directly. pull_request_review only receives the
# secret for ORIGIN PRs, so the job below skips it for forks; fork reviews go
# through the fork-review relay (the two extra files above). CI completion is NOT
# handled here -- GitHub does not deliver check_suite for GitHub Actions-created
# suites (recursion prevention), so Actions-based CI results come via
# example-pr-checks-complete.yml (workflow_run). The check_suite trigger is kept
# only for any non-Actions, GitHub-App-created check suites.

on:
pull_request_target:
types:
[
opened,
reopened,
edited,
synchronize,
closed,
ready_for_review,
converted_to_draft,
enqueued,
dequeued,
]
pull_request_review:
# dismissed matters too: dismissing a CHANGES_REQUESTED review (with no new
# commit) should move the PR out of Revising, and only this event signals it.
types: [submitted, dismissed]
check_suite:
types: [completed]

permissions: {}

jobs:
board-sync:
# Run directly for everything except a fork PR's review (no secret there);
# fork reviews go through the workflow_run relay instead.
if: >-
github.event_name != 'pull_request_review' ||
github.event.pull_request.head.repo.fork == false
uses: shader-slang/slang/.github/workflows/pr-board-sync.yml@master
secrets:
SLANG_PR_BOT_TOKEN: ${{ secrets.SLANG_PR_BOT_TOKEN }}
Comment thread
jhelferty-nv marked this conversation as resolved.
30 changes: 30 additions & 0 deletions .github/workflows/pr-review-fork-apply.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: PR Review Fork Apply

# Stage 2 of the fork-review relay (optional, pairs with
# example-pr-review-fork-bridge.yml). Copy to
# `.github/workflows/pr-review-fork-apply.yml`.
#
# Triggered by the completion of "PR Review Fork Bridge". A workflow_run workflow
# runs in the base repo's PRIVILEGED context with secrets even when the upstream
# run was a fork PR's review -- the only way to update the board for fork-PR
# reviews on a public repo. The reusable workflow resolves the PR from the
# upstream run's head SHA and reconciles; it does NO checkout (metadata only), so
# running it in this privileged context is not a pwn-request vector.
#
# (workflow_run only fires for workflow files on the default branch.)

on:
workflow_run:
workflows: ["PR Review Fork Bridge"]
types: [completed]

permissions: {}

jobs:
board-sync:
# Only when the bridge completed successfully (it always should; this guards
# against a cancelled/failed relay run).
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: shader-slang/slang/.github/workflows/pr-board-sync.yml@master
secrets:
SLANG_PR_BOT_TOKEN: ${{ secrets.SLANG_PR_BOT_TOKEN }}
30 changes: 30 additions & 0 deletions .github/workflows/pr-review-fork-bridge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: PR Review Fork Bridge

# Stage 1 of the fork-review relay (optional, for fully real-time fork-PR review
# handling). Copy to `.github/workflows/pr-review-fork-bridge.yml`.
#
# On a PUBLIC repo, a pull_request_review on a PR from a FORK runs the fork's head
# with no secrets, so it cannot update the board directly. This unprivileged
# workflow does nothing but complete successfully for fork-PR reviews, which lets
# the privileged workflow_run workflow (example-pr-review-fork-apply.yml) fire and
# do the board update with secrets. It runs NO board logic and checks out NO code.
# Origin-PR reviews are handled directly by pr-maintenance.yml, so this is gated
# to forks.

on:
pull_request_review:
# Relay both submitted and dismissed: dismissing a fork PR's CHANGES_REQUESTED
# review should recompute its Status, same as a new review.
types: [submitted, dismissed]

permissions: {}

jobs:
bridge:
if: ${{ github.event.pull_request.head.repo.fork == true }}
runs-on: ubuntu-latest
steps:
- name: Relay fork PR review to the privileged apply workflow
run: |
echo "Fork PR #${{ github.event.pull_request.number }} review event."
echo "Completing so pr-review-fork-apply.yml (workflow_run) can reconcile with secrets."
31 changes: 31 additions & 0 deletions .github/workflows/pr-sweep-nightly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: PR Board Sweep (nightly)

# Scheduled cadence caller for the reusable board-sync workflow in "sweep" mode.
# Copy to `.github/workflows/pr-sweep-nightly.yml`.
#
# Reconciles every open PR in THIS repo onto the shared "Slang PR Tracking"
# board. It is the periodic backstop for what the per-event path
# (pr-maintenance.yml and the other callers) cannot see -- missed webhooks or
# failed runs, an issue assigned/linked after the fact, board drift -- and
# shares all per-PR logic with them (only the enumeration differs).
#
# Cross-repo safe: the reusable workflow reads `context.repo` of the CALLER, so
# this schedule in slangpy / slang-rhi / etc. sweeps that repo's open PRs, not
# slang's. No per-repo customization needed beyond copying the file.
#
# Generic -- copy verbatim. (workflow_dispatch allows on-demand runs.)

on:
schedule:
- cron: "0 7 * * *" # nightly ~07:00 UTC (GitHub may delay under load)
workflow_dispatch: {}

permissions: {}

jobs:
board-sweep:
uses: shader-slang/slang/.github/workflows/pr-board-sync.yml@master

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow file =="
cat -n .github/workflows/pr-sweep-nightly.yml

echo
echo "== references to SLANG_PR_BOT_TOKEN and reusable workflows =="
rg -n "SLANG_PR_BOT_TOKEN|pr-board-sync|workflow_dispatch|security|permissions:" .github/workflows -S

Repository: shader-slang/slangpy

Length of output: 4684


🌐 Web query:

GitHub Actions reusable workflows secret sharing SLANG_PR_BOT_TOKEN organization Projects read/write pull request issue write scopes commit SHA immutable ref

💡 Result:

When using GitHub Actions reusable workflows, secret sharing and permission management require specific configurations to ensure security and functionality [1][2][3][4]. Reusable Workflow Secret Sharing Secrets are not automatically passed to reusable workflows unless explicitly mapped or inherited [1][2][5]. 1. Explicit Mapping: Use the secrets keyword in the caller workflow to map specific secrets to the called workflow's inputs [1][6]. This is the recommended practice for security, as it limits the exposure of secrets to only what is necessary [6][4]. 2. Secret Inheritance: Using secrets: inherit in the caller workflow passes all secrets the caller has access to, including organization, repository, and environment secrets, to the called workflow [2][7][5]. This should be avoided if you do not fully trust the repository containing the reusable workflow [4]. SLANG_PR_BOT_TOKEN and Permissions In configurations such as the slang/slang project, a custom PAT like SLANG_PR_BOT_TOKEN is often used to perform organization-level tasks (e.g., managing Projects, Issues, and Pull Requests) that the default GITHUB_TOKEN cannot perform [8][9]. - Permissions: To grant a reusable workflow the necessary scopes (e.g., contents: write, pull-requests: write), you must explicitly define these permissions in the calling job [10]. Even if the reusable workflow requires these permissions, the caller must explicitly grant them at the job level [10]. - Least Privilege: It is a best practice to set permissions: {} at the top level of the caller and reusable workflows to disable the default GITHUB_TOKEN permissions, then grant only the required scopes at the specific job level [8][9]. Commit SHA and Immutable References To prevent supply chain attacks and ensure consistent execution, reusable workflows should be referenced by an immutable commit SHA (e.g., uses: org/repo/.github/workflows/workflow.yml@a1b2c3d4...) rather than a mutable tag or branch name [3][11][4]. Pinning to a SHA ensures that the workflow logic remains identical across runs and protects against unauthorized modifications to tags or branches [3][4]. Summary of Best Practices - Pin all reusable workflows to an immutable commit SHA [3][4]. - Prefer explicit secret mapping over secrets: inherit [6][4]. - Explicitly define job-level permissions in the caller, even for reusable workflows [10]. - Use least-privilege configurations (permissions: {}) for both callers and reusable workflows [8][9].

Citations:


Pin the privileged reusable workflow to an immutable commit.

The reusable workflow at line 27 uses the mutable master ref and receives SLANG_PR_BOT_TOKEN. A later shader-slang/slang change can alter the workflow that reads this token, whose permissions span organization Projects and pull-request/issue write access. pin the call to a reviewed full commit SHA.

Suggested fix
-    uses: shader-slang/slang/.github/workflows/pr-board-sync.yml@master
+    uses: shader-slang/slang/.github/workflows/pr-board-sync.yml@<reviewed-full-commit-sha>

Source: Path instructions

with:
mode: sweep
secrets:
SLANG_PR_BOT_TOKEN: ${{ secrets.SLANG_PR_BOT_TOKEN }}
10 changes: 10 additions & 0 deletions .github/zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Allow ref-pinning for slang reusable workflows (@master by design) and
# first-party GitHub actions; silence zizmor/CodeRabbit unpinned-uses nags.
rules:
unpinned-uses:
config:
policies:
shader-slang/slang/*: ref-pin

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n '^\s*uses:\s*shader-slang/slang/' .github/workflows

Repository: shader-slang/slangpy

Length of output: 725


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .github/zizmor.yml =="
cat -n .github/zizmor.yml

echo
echo "== all repository-local zizmor workflow references =="
rg -n '^\s*uses:\s*' .github/workflows .github || true

Repository: shader-slang/slangpy

Length of output: 9057


🌐 Web query:

zizmor ref-pin policy configuration symbol refs owner/repo/* pattern

💡 Result:

In zizmor, the ref-pin policy is a configuration setting for the unpinned-uses audit that allows specific GitHub Actions references to be pinned by branch or tag (symbolic references) rather than requiring a mandatory full commit SHA hash [1][2]. Configuration Details You can define policies for uses clauses within your zizmor configuration file (.github/zizmor.yml or zizmor.yml) under the rules.unpinned-uses.config.policies object [1][3][4]. Each entry maps a repository pattern to a specific policy [1][2]. Valid policies include: ref-pin: Permits pinning by branch, tag, or SHA [1][2]. hash-pin: Strictly requires pinning by full commit SHA [1][2]. any: Removes all pinning requirements for the matched pattern [1][2]. The owner/repo/* Pattern The owner/repo/* pattern is used to match all uses clauses originating from a specific repository, regardless of the subpath or reference used [4][5]. For example, a rule defined as actions/: ref-pin would allow symbolic references (like @v4) for any action within the actions organization [6][5]. General Configuration Structure To configure these policies, use the following YAML structure in your configuration file: rules: unpinned-uses: config: policies: "owner/repo/": ref-pin "other-owner/": hash-pin "": hash-pin Specificity and Matching Zizmor evaluates these patterns based on specificity, meaning more specific patterns (e.g., owner/repo/subpath) take precedence over broader ones (e.g., owner/repo/* or owner/*) [2][4][7]. If a uses clause does not match any explicit policy in your configuration, it falls back to the default audit policy, which typically requires hash-pinning [1][6][2]. Since version 1.20.0, the default behavior of zizmor is to require hash-pinning for all actions [1]. Users who wish to continue using symbolic references for trusted repositories must explicitly add them to their configuration as shown above [1][6].

Citations:


Narrow the Slang repository exception.

shader-slang/slang/* allows any Slang subpath to use a mutable reference. Current callers also use @master for /.github/actions/claude-code-runner, so restrict the ref-pin policy to only the trusted referenced paths instead of the full repository.

actions/*: ref-pin
github/*: ref-pin
dependabot/*: ref-pin
Loading