zizmor 1.2.0__tar.gz → 1.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of zizmor might be problematic. Click here for more details.
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/workflows/ci.yml +14 -2
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/workflows/site.yml +1 -1
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/workflows/zizmor.yml +1 -1
- {zizmor-1.2.0 → zizmor-1.2.1}/Cargo.lock +1 -1
- {zizmor-1.2.0 → zizmor-1.2.1}/Cargo.toml +1 -1
- {zizmor-1.2.0 → zizmor-1.2.1}/Makefile +4 -4
- {zizmor-1.2.0 → zizmor-1.2.1}/PKG-INFO +3 -1
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/release-notes.md +10 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/usage.md +1 -1
- zizmor-1.2.1/pyproject.toml +17 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/bot_conditions.rs +2 -3
- {zizmor-1.2.0 → zizmor-1.2.1}/src/main.rs +17 -13
- {zizmor-1.2.0 → zizmor-1.2.1}/src/models.rs +8 -13
- {zizmor-1.2.0 → zizmor-1.2.1}/src/registry.rs +53 -18
- {zizmor-1.2.0 → zizmor-1.2.1}/src/render.rs +5 -1
- {zizmor-1.2.0 → zizmor-1.2.1}/src/sarif.rs +2 -1
- zizmor-1.2.1/uv.lock +869 -0
- zizmor-1.2.0/pyproject.toml +0 -6
- zizmor-1.2.0/site-requirements.txt +0 -2
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/dependabot.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/workflows/pypi.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/.github/workflows/release.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/.gitignore +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/CONTRIBUTING.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/LICENSE +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/README.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/assets/favicon48x48.png +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/assets/rainbow.svg +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/assets/zizmor-demo.gif +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/audits.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/configuration.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/development.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/index.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/installation.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/magiclink.css +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/quickstart.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/snippets/help.txt +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/snippets/render-sponsors.py +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/snippets/render-trophies.py +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/snippets/sponsors.html +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/snippets/sponsors.json +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/snippets/trophies.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/snippets/trophies.txt +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/docs/trophy-case.md +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/mkdocs.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/artipacked.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/cache_poisoning.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/dangerous_triggers.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/excessive_permissions.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/github_env.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/hardcoded_container_credentials.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/impostor_commit.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/insecure_commands.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/known_vulnerable_actions.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/mod.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/ref_confusion.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/secrets_inherit.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/self_hosted_runner.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/template_injection.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/unpinned_uses.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/audit/use_trusted_publishing.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/config.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/expr/expr.pest +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/expr/mod.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/finding/locate.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/finding/mod.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/github_api.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/models/coordinate.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/models/uses.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/state.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/src/utils.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/acceptance.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/common.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshot.rs +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__artipacked-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__artipacked-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__artipacked-4.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__artipacked.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__bot_conditions.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-10.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-11.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-12.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-13.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-14.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-4.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-5.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-6.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-7.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-8.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning-9.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cache_poisoning.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__cant_retrieve.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__conflicting_online_options-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__conflicting_online_options-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__conflicting_online_options.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions-4.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions-5.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions-6.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions-7.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions-8.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions-9.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__excessive_permissions.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__github_env-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__github_env-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__github_env.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__insecure_commands-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__insecure_commands-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__insecure_commands.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__secrets_inherit.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__self_hosted-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__self_hosted-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__self_hosted-4.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__self_hosted-5.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__self_hosted-6.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__self_hosted-7.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__self_hosted-8.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__self_hosted.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__template_injection-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__template_injection-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__template_injection-4.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__template_injection-5.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__template_injection-6.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__template_injection-7.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__template_injection-8.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__template_injection.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__unpinned_uses-2.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__unpinned_uses-3.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__unpinned_uses-4.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/snapshots/snapshot__unpinned_uses.snap +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/artipacked/issue-447-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/artipacked.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/bot-conditions.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/caching-disabled-by-default.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/caching-enabled-by-default.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/caching-not-configurable.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/caching-opt-in-boolean-toggle.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/caching-opt-in-boolish-toggle.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/caching-opt-in-expression.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/caching-opt-in-multi-value-toggle.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/caching-opt-out.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/issue-343-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/issue-378-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/no-cache-aware-steps.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/publisher-step.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/workflow-release-branch-trigger.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning/workflow-tag-trigger.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/cache-poisoning.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions/issue-336-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions/jobs-broaden-permissions.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions/workflow-default-perms-all-jobs-explicit.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions/workflow-default-perms.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions/workflow-empty-perms.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions/workflow-read-all.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions/workflow-write-all.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions/workflow-write-explicit.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/excessive-permissions.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/github-env/action.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/github-env/github-path.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/github-env/issue-397-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/github_env.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/hardcoded-credentials.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/inlined-ignores.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/insecure-commands/action.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/insecure-commands.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/secrets-inherit.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/self-hosted/issue-283-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/self-hosted/self-hosted-matrix-dimension.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/self-hosted/self-hosted-matrix-exclusion.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/self-hosted/self-hosted-matrix-inclusion.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/self-hosted/self-hosted-runner-group.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/self-hosted/self-hosted-runner-label.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/self-hosted.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection/issue-22-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection/issue-339-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection/issue-418-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection/pr-317-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection/pr-425-backstop/action.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection/static-env.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection/template-injection-dynamic-matrix.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection/template-injection-static-matrix.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/template-injection.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/unpinned-uses/action.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/unpinned-uses/issue-433-repro.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/unpinned-uses.yml +0 -0
- {zizmor-1.2.0 → zizmor-1.2.1}/tests/test-data/use-trusted-publishing.yml +0 -0
|
@@ -33,7 +33,7 @@ jobs:
|
|
|
33
33
|
|
|
34
34
|
- uses: Swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
|
|
35
35
|
|
|
36
|
-
- uses: astral-sh/setup-uv@
|
|
36
|
+
- uses: astral-sh/setup-uv@b5f58b2abc5763ade55e4e9d0fe52cd1ff7979ca # v5.2.1
|
|
37
37
|
|
|
38
38
|
- name: Test
|
|
39
39
|
run: cargo test
|
|
@@ -43,9 +43,21 @@ jobs:
|
|
|
43
43
|
make snippets
|
|
44
44
|
git diff --exit-code
|
|
45
45
|
|
|
46
|
+
test-site:
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
|
50
|
+
with:
|
|
51
|
+
persist-credentials: false
|
|
52
|
+
|
|
53
|
+
- uses: astral-sh/setup-uv@b5f58b2abc5763ade55e4e9d0fe52cd1ff7979ca # v5.2.1
|
|
54
|
+
|
|
55
|
+
- name: Test site
|
|
56
|
+
run: make site
|
|
57
|
+
|
|
46
58
|
all-tests-pass:
|
|
47
59
|
if: always()
|
|
48
|
-
needs: [lint, test]
|
|
60
|
+
needs: [lint, test, test-site]
|
|
49
61
|
runs-on: ubuntu-latest
|
|
50
62
|
|
|
51
63
|
steps:
|
|
@@ -30,7 +30,7 @@ jobs:
|
|
|
30
30
|
persist-credentials: false
|
|
31
31
|
|
|
32
32
|
- name: Install the latest version of uv
|
|
33
|
-
uses: astral-sh/setup-uv@
|
|
33
|
+
uses: astral-sh/setup-uv@b5f58b2abc5763ade55e4e9d0fe52cd1ff7979ca # v5.2.1
|
|
34
34
|
|
|
35
35
|
- name: build site
|
|
36
36
|
run: make site
|
|
@@ -19,7 +19,7 @@ jobs:
|
|
|
19
19
|
with:
|
|
20
20
|
persist-credentials: false
|
|
21
21
|
- name: Install the latest version of uv
|
|
22
|
-
uses: astral-sh/setup-uv@
|
|
22
|
+
uses: astral-sh/setup-uv@b5f58b2abc5763ade55e4e9d0fe52cd1ff7979ca # v5.2.1
|
|
23
23
|
- name: Run zizmor 🌈
|
|
24
24
|
run: uvx zizmor --format sarif . > results.sarif
|
|
25
25
|
env:
|
|
@@ -3,12 +3,12 @@ all:
|
|
|
3
3
|
@echo "Run my targets individually!"
|
|
4
4
|
|
|
5
5
|
.PHONY: site
|
|
6
|
-
site:
|
|
7
|
-
|
|
6
|
+
site:
|
|
7
|
+
uv run --only-group docs mkdocs build
|
|
8
8
|
|
|
9
9
|
.PHONY: site-live
|
|
10
|
-
site-live:
|
|
11
|
-
|
|
10
|
+
site-live:
|
|
11
|
+
uv run --only-group docs mkdocs serve
|
|
12
12
|
|
|
13
13
|
.PHONY: snippets
|
|
14
14
|
snippets: trophies sponsors
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: zizmor
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
|
+
License-File: LICENSE
|
|
4
5
|
Summary: Static analysis for GitHub Actions
|
|
5
6
|
Keywords: cli,github-actions,static-analysis,security
|
|
6
7
|
Home-Page: https://github.com/woodruffw/zizmor
|
|
7
8
|
Author: William Woodruff <william@yossarian.net>
|
|
8
9
|
Author-email: William Woodruff <william@yossarian.net>
|
|
9
10
|
License: MIT
|
|
11
|
+
Requires-Python: >=3.9
|
|
10
12
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
11
13
|
Project-URL: Source Code, https://github.com/woodruffw/zizmor
|
|
12
14
|
|
|
@@ -11,6 +11,16 @@ of `zizmor`.
|
|
|
11
11
|
|
|
12
12
|
Nothing to see here (yet!)
|
|
13
13
|
|
|
14
|
+
## v1.2.1
|
|
15
|
+
|
|
16
|
+
This is a small corrective release for some SARIF behavior that
|
|
17
|
+
changed with v1.2.0.
|
|
18
|
+
|
|
19
|
+
### Bug Fixes 🐛
|
|
20
|
+
|
|
21
|
+
* SARIF outputs now use relative paths again, but more correctly
|
|
22
|
+
than before [v1.2.0](#v120) (#469)
|
|
23
|
+
|
|
14
24
|
## v1.2.0
|
|
15
25
|
|
|
16
26
|
This release comes with one new audit ([bot-conditions]), plus a handful
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["maturin>=1.0,<2.0"]
|
|
3
|
+
build-backend = "maturin"
|
|
4
|
+
|
|
5
|
+
# NOTE: This section is a stub; needed to prevent
|
|
6
|
+
# `uv run --only-group docs` from failing.
|
|
7
|
+
[project]
|
|
8
|
+
name = "zizmor"
|
|
9
|
+
dynamic = ["version"]
|
|
10
|
+
# Arbitrarily set to the oldest non-EOL Python.
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
|
|
13
|
+
[tool.maturin]
|
|
14
|
+
bindings = "bin"
|
|
15
|
+
|
|
16
|
+
[dependency-groups]
|
|
17
|
+
docs = ["mkdocs ~= 1.6", "mkdocs-material[imaging] ~= 9.5"]
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
use github_actions_models::common::{expr::ExplicitExpr, If};
|
|
2
2
|
|
|
3
|
+
use super::{audit_meta, Audit};
|
|
3
4
|
use crate::{
|
|
4
5
|
expr::{self, Expr},
|
|
5
6
|
finding::{Confidence, Severity},
|
|
6
7
|
models::JobExt,
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
use super::{audit_meta, Audit};
|
|
10
|
-
|
|
11
10
|
pub(crate) struct BotConditions;
|
|
12
11
|
|
|
13
12
|
audit_meta!(BotConditions, "bot-conditions", "spoofable bot actor check");
|
|
@@ -152,7 +151,7 @@ impl BotConditions {
|
|
|
152
151
|
// We have a bot condition but it doesn't dominate the expression.
|
|
153
152
|
(true, false) => Some(Confidence::Medium),
|
|
154
153
|
// No bot condition.
|
|
155
|
-
(
|
|
154
|
+
(..) => None,
|
|
156
155
|
}
|
|
157
156
|
}
|
|
158
157
|
}
|
|
@@ -160,17 +160,18 @@ fn tip(err: impl AsRef<str>, tip: impl AsRef<str>) -> String {
|
|
|
160
160
|
|
|
161
161
|
#[instrument(skip(mode, registry))]
|
|
162
162
|
fn collect_from_repo_dir(
|
|
163
|
-
|
|
163
|
+
top_dir: &Utf8Path,
|
|
164
|
+
current_dir: &Utf8Path,
|
|
164
165
|
mode: &CollectionMode,
|
|
165
166
|
registry: &mut InputRegistry,
|
|
166
167
|
) -> Result<()> {
|
|
167
168
|
// The workflow directory might not exist if we're collecting from
|
|
168
169
|
// a repository that only contains actions.
|
|
169
170
|
if mode.workflows() {
|
|
170
|
-
let workflow_dir = if
|
|
171
|
-
|
|
171
|
+
let workflow_dir = if current_dir.ends_with(".github/workflows") {
|
|
172
|
+
current_dir.into()
|
|
172
173
|
} else {
|
|
173
|
-
|
|
174
|
+
current_dir.join(".github/workflows")
|
|
174
175
|
};
|
|
175
176
|
|
|
176
177
|
if workflow_dir.is_dir() {
|
|
@@ -180,7 +181,7 @@ fn collect_from_repo_dir(
|
|
|
180
181
|
match input_path.extension() {
|
|
181
182
|
Some(ext) if ext == "yml" || ext == "yaml" => {
|
|
182
183
|
registry
|
|
183
|
-
.register_by_path(input_path)
|
|
184
|
+
.register_by_path(input_path, Some(top_dir))
|
|
184
185
|
.with_context(|| format!("failed to register input: {input_path}"))?;
|
|
185
186
|
}
|
|
186
187
|
_ => continue,
|
|
@@ -192,18 +193,18 @@ fn collect_from_repo_dir(
|
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
if mode.actions() {
|
|
195
|
-
for entry in
|
|
196
|
+
for entry in current_dir.read_dir_utf8()? {
|
|
196
197
|
let entry = entry?;
|
|
197
198
|
let entry_path = entry.path();
|
|
198
199
|
|
|
199
200
|
if entry_path.is_file()
|
|
200
201
|
&& matches!(entry_path.file_name(), Some("action.yml" | "action.yaml"))
|
|
201
202
|
{
|
|
202
|
-
let action = Action::from_file(entry_path)?;
|
|
203
|
+
let action = Action::from_file(entry_path, Some(top_dir))?;
|
|
203
204
|
registry.register_input(action.into())?;
|
|
204
205
|
} else if entry_path.is_dir() && !entry_path.ends_with(".github/workflows") {
|
|
205
206
|
// Recurse and limit the collection mode to only actions.
|
|
206
|
-
collect_from_repo_dir(entry_path, &CollectionMode::ActionsOnly, registry)?;
|
|
207
|
+
collect_from_repo_dir(top_dir, entry_path, &CollectionMode::ActionsOnly, registry)?;
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
210
|
}
|
|
@@ -285,13 +286,13 @@ fn collect_inputs(
|
|
|
285
286
|
for input in inputs {
|
|
286
287
|
let input_path = Utf8Path::new(input);
|
|
287
288
|
if input_path.is_file() {
|
|
289
|
+
// When collecting individual files, we don't know which part
|
|
290
|
+
// of the input path is the prefix.
|
|
288
291
|
registry
|
|
289
|
-
.register_by_path(input_path)
|
|
292
|
+
.register_by_path(input_path, None)
|
|
290
293
|
.with_context(|| format!("failed to register input: {input_path}"))?;
|
|
291
294
|
} else if input_path.is_dir() {
|
|
292
|
-
|
|
293
|
-
let absolute = input_path.canonicalize_utf8()?;
|
|
294
|
-
collect_from_repo_dir(&absolute, mode, &mut registry)?;
|
|
295
|
+
collect_from_repo_dir(input_path, input_path, mode, &mut registry)?;
|
|
295
296
|
} else {
|
|
296
297
|
// If this input isn't a file or directory, it's probably an
|
|
297
298
|
// `owner/repo(@ref)?` slug.
|
|
@@ -387,7 +388,10 @@ fn run() -> Result<ExitCode> {
|
|
|
387
388
|
})?);
|
|
388
389
|
Span::current().pb_inc(1);
|
|
389
390
|
}
|
|
390
|
-
tracing::info!(
|
|
391
|
+
tracing::info!(
|
|
392
|
+
"🌈 completed {input}",
|
|
393
|
+
input = input.key().best_effort_relative_path()
|
|
394
|
+
);
|
|
391
395
|
}
|
|
392
396
|
}
|
|
393
397
|
|
|
@@ -101,7 +101,7 @@ impl Workflow {
|
|
|
101
101
|
InputKey::Local(_) => None,
|
|
102
102
|
InputKey::Remote(_) => {
|
|
103
103
|
// NOTE: InputKey's Display produces a URL, hence `key.to_string()`.
|
|
104
|
-
Some(Link::new(key.
|
|
104
|
+
Some(Link::new(key.best_effort_relative_path(), &key.to_string()).to_string())
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
107
|
|
|
@@ -114,11 +114,9 @@ impl Workflow {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/// Load a workflow from the given file on disk.
|
|
117
|
-
pub(crate) fn from_file<P: AsRef<Utf8Path>>(
|
|
118
|
-
let contents = std::fs::read_to_string(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
Self::from_string(contents, InputKey::local(path)?)
|
|
117
|
+
pub(crate) fn from_file<P: AsRef<Utf8Path>>(path: P, prefix: Option<P>) -> Result<Self> {
|
|
118
|
+
let contents = std::fs::read_to_string(path.as_ref())?;
|
|
119
|
+
Self::from_string(contents, InputKey::local(path, prefix)?)
|
|
122
120
|
}
|
|
123
121
|
|
|
124
122
|
/// This workflow's [`SymbolicLocation`].
|
|
@@ -716,13 +714,10 @@ impl Debug for Action {
|
|
|
716
714
|
|
|
717
715
|
impl Action {
|
|
718
716
|
/// Load an action from the given file on disk.
|
|
719
|
-
pub(crate) fn from_file<P: AsRef<Utf8Path>>(
|
|
717
|
+
pub(crate) fn from_file<P: AsRef<Utf8Path>>(path: P, prefix: Option<P>) -> Result<Self> {
|
|
720
718
|
let contents =
|
|
721
|
-
std::fs::read_to_string(
|
|
722
|
-
|
|
723
|
-
let path = p.as_ref().canonicalize_utf8()?;
|
|
724
|
-
|
|
725
|
-
Self::from_string(contents, InputKey::local(path)?)
|
|
719
|
+
std::fs::read_to_string(path.as_ref()).with_context(|| "couldn't read action file")?;
|
|
720
|
+
Self::from_string(contents, InputKey::local(path, prefix)?)
|
|
726
721
|
}
|
|
727
722
|
|
|
728
723
|
/// Load a workflow from a buffer, with an assigned name.
|
|
@@ -736,7 +731,7 @@ impl Action {
|
|
|
736
731
|
InputKey::Local(_) => None,
|
|
737
732
|
InputKey::Remote(_) => {
|
|
738
733
|
// NOTE: InputKey's Display produces a URL, hence `key.to_string()`.
|
|
739
|
-
Some(Link::new(key.
|
|
734
|
+
Some(Link::new(key.best_effort_relative_path(), &key.to_string()).to_string())
|
|
740
735
|
}
|
|
741
736
|
};
|
|
742
737
|
|
|
@@ -20,7 +20,10 @@ use crate::{
|
|
|
20
20
|
|
|
21
21
|
#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize)]
|
|
22
22
|
pub(crate) struct LocalKey {
|
|
23
|
-
path
|
|
23
|
+
/// The path's nondeterministic prefix, if any.
|
|
24
|
+
prefix: Option<Utf8PathBuf>,
|
|
25
|
+
/// The given path to the input. This can be absolute or relative.
|
|
26
|
+
given_path: Utf8PathBuf,
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize)]
|
|
@@ -45,7 +48,7 @@ pub(crate) enum InputKey {
|
|
|
45
48
|
impl Display for InputKey {
|
|
46
49
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
47
50
|
match self {
|
|
48
|
-
InputKey::Local(local) => write!(f, "file://{path}", path = local.
|
|
51
|
+
InputKey::Local(local) => write!(f, "file://{path}", path = local.given_path),
|
|
49
52
|
InputKey::Remote(remote) => {
|
|
50
53
|
// No ref means assume HEAD, i.e. whatever's on the default branch.
|
|
51
54
|
let git_ref = remote.git_ref.as_deref().unwrap_or("HEAD");
|
|
@@ -62,13 +65,16 @@ impl Display for InputKey {
|
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
impl InputKey {
|
|
65
|
-
pub(crate) fn local(path:
|
|
68
|
+
pub(crate) fn local<P: AsRef<Utf8Path>>(path: P, prefix: Option<P>) -> Result<Self> {
|
|
66
69
|
// All keys must have a filename component.
|
|
67
|
-
if path.file_name().is_none() {
|
|
70
|
+
if path.as_ref().file_name().is_none() {
|
|
68
71
|
return Err(anyhow!("invalid local input: no filename component"));
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
Ok(Self::Local(LocalKey {
|
|
74
|
+
Ok(Self::Local(LocalKey {
|
|
75
|
+
prefix: prefix.map(|p| p.as_ref().to_path_buf()),
|
|
76
|
+
given_path: path.as_ref().to_path_buf(),
|
|
77
|
+
}))
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
pub(crate) fn remote(slug: &RepositoryUses, path: String) -> Result<Self> {
|
|
@@ -84,13 +90,18 @@ impl InputKey {
|
|
|
84
90
|
}))
|
|
85
91
|
}
|
|
86
92
|
|
|
87
|
-
///
|
|
93
|
+
/// Return a "best-effort" relative path for this [`InputKey`].
|
|
88
94
|
///
|
|
89
|
-
/// This will be
|
|
90
|
-
/// path for
|
|
91
|
-
pub(crate) fn
|
|
95
|
+
/// This will always be a relative path for remote keys,
|
|
96
|
+
/// and will be a "best-effort" relative path for local keys.
|
|
97
|
+
pub(crate) fn best_effort_relative_path(&self) -> &str {
|
|
92
98
|
match self {
|
|
93
|
-
InputKey::Local(local) => local
|
|
99
|
+
InputKey::Local(local) => local
|
|
100
|
+
.prefix
|
|
101
|
+
.as_ref()
|
|
102
|
+
.and_then(|pfx| local.given_path.strip_prefix(dbg!(pfx)).ok())
|
|
103
|
+
.unwrap_or_else(|| &local.given_path)
|
|
104
|
+
.as_str(),
|
|
94
105
|
InputKey::Remote(remote) => remote.path.as_str(),
|
|
95
106
|
}
|
|
96
107
|
}
|
|
@@ -100,7 +111,7 @@ impl InputKey {
|
|
|
100
111
|
// NOTE: Safe unwraps, since the presence of a filename component
|
|
101
112
|
// is a construction invariant of all `InputKey` variants.
|
|
102
113
|
match self {
|
|
103
|
-
InputKey::Local(local) => local.
|
|
114
|
+
InputKey::Local(local) => local.given_path.file_name().unwrap(),
|
|
104
115
|
InputKey::Remote(remote) => remote.path.file_name().unwrap(),
|
|
105
116
|
}
|
|
106
117
|
}
|
|
@@ -108,8 +119,6 @@ impl InputKey {
|
|
|
108
119
|
|
|
109
120
|
pub(crate) struct InputRegistry {
|
|
110
121
|
pub(crate) inputs: IndexMap<InputKey, AuditInput>,
|
|
111
|
-
// pub(crate) actions: IndexMap<InputKey, Action>,
|
|
112
|
-
// pub(crate) workflows: IndexMap<InputKey, Workflow>,
|
|
113
122
|
}
|
|
114
123
|
|
|
115
124
|
impl InputRegistry {
|
|
@@ -140,10 +149,14 @@ impl InputRegistry {
|
|
|
140
149
|
|
|
141
150
|
/// Registers a workflow or action definition from its path on disk.
|
|
142
151
|
#[instrument(skip(self))]
|
|
143
|
-
pub(crate) fn register_by_path(
|
|
144
|
-
|
|
152
|
+
pub(crate) fn register_by_path(
|
|
153
|
+
&mut self,
|
|
154
|
+
path: &Utf8Path,
|
|
155
|
+
prefix: Option<&Utf8Path>,
|
|
156
|
+
) -> Result<()> {
|
|
157
|
+
match Workflow::from_file(path, prefix) {
|
|
145
158
|
Ok(workflow) => self.register_input(workflow.into()),
|
|
146
|
-
Err(we) => match Action::from_file(path) {
|
|
159
|
+
Err(we) => match Action::from_file(path, prefix) {
|
|
147
160
|
Ok(action) => self.register_input(action.into()),
|
|
148
161
|
Err(ae) => Err(anyhow!("failed to register input as workflow or action"))
|
|
149
162
|
.with_context(|| we)
|
|
@@ -289,8 +302,8 @@ mod tests {
|
|
|
289
302
|
use super::InputKey;
|
|
290
303
|
|
|
291
304
|
#[test]
|
|
292
|
-
fn
|
|
293
|
-
let local = InputKey::local("/foo/bar/baz.yml"
|
|
305
|
+
fn test_input_key_display() {
|
|
306
|
+
let local = InputKey::local("/foo/bar/baz.yml", None).unwrap();
|
|
294
307
|
assert_eq!(local.to_string(), "file:///foo/bar/baz.yml");
|
|
295
308
|
|
|
296
309
|
// No ref
|
|
@@ -313,4 +326,26 @@ mod tests {
|
|
|
313
326
|
"https://github.com/foo/bar/blob/v1/.github/workflows/baz.yml"
|
|
314
327
|
);
|
|
315
328
|
}
|
|
329
|
+
|
|
330
|
+
#[test]
|
|
331
|
+
fn test_input_key_local_path() {
|
|
332
|
+
let local = InputKey::local("/foo/bar/baz.yml", None).unwrap();
|
|
333
|
+
assert_eq!(local.best_effort_relative_path(), "/foo/bar/baz.yml");
|
|
334
|
+
|
|
335
|
+
let local = InputKey::local("/foo/bar/baz.yml", Some("/foo")).unwrap();
|
|
336
|
+
assert_eq!(local.best_effort_relative_path(), "bar/baz.yml");
|
|
337
|
+
|
|
338
|
+
let local = InputKey::local("/foo/bar/baz.yml", Some("/foo/bar/")).unwrap();
|
|
339
|
+
assert_eq!(local.best_effort_relative_path(), "baz.yml");
|
|
340
|
+
|
|
341
|
+
let local = InputKey::local(
|
|
342
|
+
"/home/runner/work/repo/repo/.github/workflows/baz.yml",
|
|
343
|
+
Some("/home/runner/work/repo/repo"),
|
|
344
|
+
)
|
|
345
|
+
.unwrap();
|
|
346
|
+
assert_eq!(
|
|
347
|
+
local.best_effort_relative_path(),
|
|
348
|
+
".github/workflows/baz.yml"
|
|
349
|
+
);
|
|
350
|
+
}
|
|
316
351
|
}
|
|
@@ -50,7 +50,11 @@ pub(crate) fn finding_snippet<'w>(
|
|
|
50
50
|
Snippet::source(input.document().source())
|
|
51
51
|
.fold(true)
|
|
52
52
|
.line_start(1)
|
|
53
|
-
.origin(
|
|
53
|
+
.origin(
|
|
54
|
+
input
|
|
55
|
+
.link()
|
|
56
|
+
.unwrap_or(input_key.best_effort_relative_path()),
|
|
57
|
+
)
|
|
54
58
|
.annotations(locations.iter().map(|loc| {
|
|
55
59
|
let annotation = match loc.symbolic.link {
|
|
56
60
|
Some(ref link) => link,
|
|
@@ -125,7 +125,8 @@ fn build_locations<'a>(locations: impl Iterator<Item = &'a Location<'a>>) -> Vec
|
|
|
125
125
|
PhysicalLocation::builder()
|
|
126
126
|
.artifact_location(
|
|
127
127
|
ArtifactLocation::builder()
|
|
128
|
-
.
|
|
128
|
+
.uri_base_id("%SRCROOT%")
|
|
129
|
+
.uri(location.symbolic.key.best_effort_relative_path())
|
|
129
130
|
.build(),
|
|
130
131
|
)
|
|
131
132
|
.region(
|