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
4 changes: 2 additions & 2 deletions .github/workflows/dependency-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
permissions:
contents: read
issues: write
uses: hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@241d646f6b83d17aeee2bb97a8c1e1e788eb6099
uses: hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@v1
Comment thread
omry marked this conversation as resolved.
with:
audit-kind: ${{ inputs.audit-kind || 'auto' }}

Expand All @@ -35,7 +35,7 @@ jobs:
permissions:
contents: write
pull-requests: write
uses: hydra-ecosystem/github-actions/.github/workflows/node-publish.yml@241d646f6b83d17aeee2bb97a8c1e1e788eb6099
uses: hydra-ecosystem/github-actions/.github/workflows/node-publish.yml@v1
with:
validation-passed: ${{ needs.audit.outputs.validation_passed }}
app-client-id: ${{ vars.NODE_AUDIT_APP_CLIENT_ID }}
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ For focused local runs without `nox`, use the same environment directly, for exa
- `.venv/bin/python -m pytest server/tests/unit/test_config.py`
- `.venv/bin/python -m pytest server/tests/unit/test_app.py`

### GitHub Actions references

External actions use full commit SHAs with version comments. Reusable workflows
also use full SHAs, with one explicit exception: the two Node maintenance calls
in `.github/workflows/dependency-audit.yml` follow
`hydra-ecosystem/github-actions@v1` for automatic compatible fixes. This trusts
the release tag maintained by that repository. A different source, workflow,
caller, branch, or major release requires a separate policy update. Full SHA
references remain valid for maintenance too. See the shared
[release policy](https://github.com/hydra-ecosystem/github-actions/blob/main/docs/workflow-releases.md).

The Docusaurus website lives in [website/](website/):

- `cd website && npm install`
Expand Down
85 changes: 80 additions & 5 deletions server/tests/unit/test_release_workflow_supply_chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,29 @@
import re
from pathlib import Path

import pytest
import yaml


ROOT = Path(__file__).resolve().parents[3]


def test_external_workflow_actions_have_immutable_pins_and_version_comments() -> None:
def _approved_reusable_workflow(reference: str, filename: str) -> bool:
if filename == "dependency-audit.yml" and reference in {
"hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@v1",
"hydra-ecosystem/github-actions/.github/workflows/node-publish.yml@v1",
}:
return True
return (
re.fullmatch(
r"[\w-]+/[\w.-]+/\.github/workflows/[\w.-]+\.ya?ml@[0-9a-f]{40}",
reference,
)
is not None
)


def test_external_workflow_actions_follow_reference_policy() -> None:
for path in (ROOT / ".github" / "workflows").glob("*.yml"):
for line in path.read_text().splitlines():
if "uses:" not in line:
Expand All @@ -18,10 +34,7 @@ def test_external_workflow_actions_have_immutable_pins_and_version_comments() ->
if reference.startswith("./"):
continue
if "/.github/workflows/" in reference:
assert re.fullmatch(
r"[\w-]+/[\w.-]+/\.github/workflows/[\w.-]+\.ya?ml@[0-9a-f]{40}",
reference,
), (path, line)
assert _approved_reusable_workflow(reference, path.name), (path, line)
else:
assert re.fullmatch(
r"[\w-]+/[\w./-]+@[0-9a-f]{40} # v\d+\.\d+\.\d+", reference
Expand Down Expand Up @@ -56,3 +69,65 @@ def test_actions_dependency_updates_are_configured() -> None:
and update["schedule"]["interval"] == "monthly"
for update in config["updates"]
)


@pytest.mark.parametrize(
"filename,reference,allowed",
[
(
"dependency-audit.yml",
"hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@v1",
True,
),
(
"dependency-audit.yml",
"hydra-ecosystem/github-actions/.github/workflows/node-publish.yml@v1",
True,
),
(
"publish.yml",
"hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@v1",
False,
),
(
"dependency-audit.yml",
"hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@v2",
False,
),
(
"dependency-audit.yml",
"hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@main",
False,
),
(
"dependency-audit.yml",
"hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@v1.2.3",
False,
),
(
"dependency-audit.yml",
"other/actions/.github/workflows/node-audit.yml@v1",
False,
),
(
"dependency-audit.yml",
"hydra-ecosystem/github-actions/.github/workflows/other.yml@v1",
False,
),
(
"publish.yml",
"other/actions/.github/workflows/publish.yml@" + "a" * 40,
True,
),
(
"dependency-audit.yml",
"hydra-ecosystem/github-actions/.github/workflows/node-audit.yml@"
+ "a" * 40,
True,
),
],
)
def test_reusable_workflow_reference_policy_boundary(
filename: str, reference: str, allowed: bool
) -> None:
assert _approved_reusable_workflow(reference, filename) is allowed
Loading