Skip to content
Closed
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
4 changes: 2 additions & 2 deletions .github/workflows/copy-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6
with:
node-version: '20'
- run: node --test scripts/copy-lint/check-copy.test.mjs
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/vercel-preview-guard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,22 +107,22 @@ jobs:
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
env:
PREVIEW_URL: ${{ needs.preview.outputs.preview_url }}
BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}
BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }} # pragma: allowlist secret
with:
github-token: ${{ github.token }}
script: |
const marker = '<!-- vercel-preview-access -->';
const secret = process.env.BYPASS_SECRET;
if (secret) core.setSecret(secret); // Emits ::add-mask:: before using it.
const bypassValue = process.env.BYPASS_SECRET;
if (bypassValue) core.setSecret(bypassValue); // Emits ::add-mask:: before using it.
const preview = process.env.PREVIEW_URL;
if (!preview) throw new Error('The preview job did not return an access URL');
const url = new URL(preview);
if (secret) {
url.searchParams.set('x-vercel-protection-bypass', secret);
if (bypassValue) {
url.searchParams.set('x-vercel-protection-bypass', bypassValue);
url.searchParams.set('x-vercel-set-bypass-cookie', 'true');
}
const body = `${marker}\nVercel preview: ${url.toString()}` +
(secret ? '' : '\n\nThe bypass secret is not configured.');
(bypassValue ? '' : '\n\nThe bypass secret is not configured.');
const { owner, repo } = context.repo;
const issue_number = context.issue.number;
const comments = await github.paginate(github.rest.issues.listComments, {
Expand Down
32 changes: 7 additions & 25 deletions .secrets.baseline

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/ci/check_supply_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from pathlib import Path

SHA40 = re.compile(r"^[0-9a-f]{40}$")
USES_RE = re.compile(r"[\"']?uses[\"']?:\s*[\"']?([A-Za-z0-9_.\-/]+)(?:@([^\"'#\s]+))?[\"']?")
USES_RE = re.compile(r"(?<![A-Za-z0-9_.-])[\"']?uses[\"']?:\s*[\"']?([A-Za-z0-9_.\-/]+)(?:@([^\"'#\s]+))?[\"']?")
USES_KEY_RE = re.compile(r"^\s*(?:-\s*)?[\"']?uses[\"']?\s*:(.*)$")
PIPE_SHELL_RE = re.compile(r"\|\s*(sudo(\s+-\S+)*\s+)?(sh|bash)\b")
LATEST_URL_RE = re.compile(r"https?://\S*latest\S*|@latest\b", re.IGNORECASE)
Expand Down
9 changes: 9 additions & 0 deletions scripts/workflow_inventory.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,18 @@ agent-sweep.yml
api-surface-issue.yml
backend-ci.yml
bundle-analysis.yml
copy-lint.yml
dependabot-lock-sync.yml
deploy.yml
engine-review-pass.yml
factory-local-ci.yml
frontend-ci.yml
head-sha-check-guard.yml
inflow-contract-ci.yml
infra-k8s-ci.yml
legacy-code-scan.yml
openapi-public-spec.yml
pr-blocker-checklist.yml
pr-gate.yml
pr-secrets-non-main.yml
production-uptime.yml
Expand All @@ -52,7 +56,12 @@ sdk-ci.yml
security.yml
sentinel.yml
supply-chain.yml
sync-main-into-prs.yml
test-suite-check.yml
vercel-preview-guard.yml
visual-preview.yml
visual-production.yml
visual-update-baselines.yml

[required-contexts]
CI Status Gate
Expand Down
11 changes: 11 additions & 0 deletions tests/scripts/test_check_supply_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ def test_action_pin_accepts_full_sha(repo: Path) -> None:
assert mod.check_action_pin(path, "ok.yml") == []


def test_action_pin_ignores_status_permissions_but_checks_uses(repo: Path) -> None:
path = _write(
repo,
".github/workflows/statuses.yml",
"permissions:\n statuses: write\n statuses: read\nsteps:\n - uses: actions/checkout@v4\n - {uses: actions/setup-node@v4}\n",
)
violations = mod.check_action_pin(path, "statuses.yml")
assert [v.line for v in violations] == [5, 6]
assert [v.rule for v in violations] == ["action-pin", "action-pin"]


def test_action_pin_rejects_tag_ref(repo: Path) -> None:
path = _write(repo, ".github/workflows/bad.yml", "steps:\n - uses: actions/checkout@v4\n")
violations = mod.check_action_pin(path, "bad.yml")
Expand Down
Loading