Files
github--spec-kit/tests/test_github_workflows.py
dependabot[bot] b41058b5e8 chore(deps): bump astral-sh/setup-uv from 9.0.0 to 10.0.1 (#4244)
* chore(deps): bump astral-sh/setup-uv from 9.0.0 to 10.0.1

Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 9.0.0 to 10.0.1.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/c771a70e6277c0a99b617c7a806ffedaca235ff9...20cfd1bf945f4377ade1205e4dbc17946fc9a30d)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 10.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(workflows): align setup-uv generated sources

Update the agentic workflow sources, action cache, generated metadata, and regression expectation for setup-uv v10.0.1.

Assisted-by: GitHub Copilot (model: GPT-5.6 Sol, autonomous)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 394a7929-b17c-470f-a3e6-b5863f9c9d40

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com>
Copilot-Session: 394a7929-b17c-470f-a3e6-b5863f9c9d40
2026-08-21 12:44:25 -05:00

170 lines
5.8 KiB
Python

"""Static checks for repository GitHub Actions workflows."""
from __future__ import annotations
import re
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent
WORKFLOWS_DIR = REPO_ROOT / ".github" / "workflows"
# Match both the dedicated-step form (` uses: x@sha`) and the
# inline shorthand (` - uses: x@sha`) used in catalog-assign.yml.
USES_RE = re.compile(r"^\s*(?:-\s*)?uses:\s*(?P<ref>\S+)", re.MULTILINE)
PINNED_SHA_RE = re.compile(r"@[0-9a-f]{40}$", re.IGNORECASE)
COMMUNITY_SUBMISSION_WORKFLOWS = (
(
"bundle",
"bundle-submission",
"bundles/catalog.community.json",
"docs/community/bundles.md",
"Modify only `bundles/catalog.community.json`",
),
(
"extension",
"extension-submission",
"extensions/catalog.community.json",
"docs/community/extensions.md",
"Do not modify any other files",
),
(
"preset",
"preset-submission",
"presets/catalog.community.json",
"docs/community/presets.md",
"Do not modify any other files",
),
)
def _create_pull_request_allowed_files(source_text: str) -> list[str]:
create_pr_match = re.search(
r"(?m)^ create-pull-request:\n(?P<body>(?:^ [^\n]*\n?)+)",
source_text,
)
assert create_pr_match is not None
allowed_files_match = re.search(
r"(?m)^ allowed-files:\n(?P<files>(?:^ - [^\n]+\n?)+)",
create_pr_match.group("body"),
)
assert allowed_files_match is not None
return [
line.strip().removeprefix("- ")
for line in allowed_files_match.group("files").splitlines()
if line.strip()
]
def test_github_actions_are_pinned_to_full_commit_shas():
unpinned_refs = []
workflows = sorted(
list(WORKFLOWS_DIR.glob("*.yml")) + list(WORKFLOWS_DIR.glob("*.yaml"))
)
assert workflows
for workflow in workflows:
workflow_text = workflow.read_text(encoding="utf-8")
for match in USES_RE.finditer(workflow_text):
uses_ref = match.group("ref")
if uses_ref.startswith(("./", "../")):
continue
if PINNED_SHA_RE.search(uses_ref):
continue
unpinned_refs.append(f"{workflow.relative_to(REPO_ROOT)}: {uses_ref}")
assert unpinned_refs == []
def test_pinned_action_ref_accepts_uppercase_hex_sha():
assert PINNED_SHA_RE.search(
"actions/example@0123456789ABCDEF0123456789ABCDEF01234567"
)
def test_community_submission_automation_is_wired_to_allowed_files():
assignment = WORKFLOWS_DIR / "catalog-assign.yml"
assignment_text = assignment.read_text(encoding="utf-8")
for workflow, label, catalog_file, docs_file, instruction in (
COMMUNITY_SUBMISSION_WORKFLOWS
):
source = WORKFLOWS_DIR / f"add-community-{workflow}.md"
compiled = WORKFLOWS_DIR / f"add-community-{workflow}.lock.yml"
assert source.is_file()
assert compiled.is_file()
source_text = source.read_text(encoding="utf-8")
compiled_text = compiled.read_text(encoding="utf-8")
assert f"names: [{label}]" in source_text
assert catalog_file in source_text
assert docs_file in source_text
assert instruction in source_text
assert _create_pull_request_allowed_files(source_text) == [
catalog_file,
docs_file,
]
assert f'"allowed_files":["{catalog_file}","{docs_file}"]' in compiled_text
assert label in assignment_text
def test_community_submission_allowed_files_do_not_include_other_catalogs_or_docs():
allowed_by_workflow = {
workflow: set(
_create_pull_request_allowed_files(
(WORKFLOWS_DIR / f"add-community-{workflow}.md").read_text(
encoding="utf-8"
)
)
)
for workflow, *_ in COMMUNITY_SUBMISSION_WORKFLOWS
}
workflow_allowed_files = list(allowed_by_workflow.items())
for index, (workflow, allowed_files) in enumerate(workflow_allowed_files):
for other_workflow, other_allowed_files in workflow_allowed_files[index + 1 :]:
overlapping_files = allowed_files & other_allowed_files
assert overlapping_files == set(), (
f"{workflow} and {other_workflow} share allowed files: "
f"{sorted(overlapping_files)}"
)
def test_bug_test_workflow_provisions_python_dependencies():
source = WORKFLOWS_DIR / "bug-test.md"
compiled = WORKFLOWS_DIR / "bug-test.lock.yml"
assert source.is_file()
assert compiled.is_file()
source_text = source.read_text(encoding="utf-8")
compiled_text = compiled.read_text(encoding="utf-8")
setup_uv = (
"astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1"
)
setup_python = (
"actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0"
)
assert " - pypi.org" in source_text
assert " - files.pythonhosted.org" in source_text
assert setup_uv in source_text
assert setup_python in source_text
assert 'run: uv pip install --system -e ".[test]"' in source_text
assert '"pypi.org"' in compiled_text
assert '"files.pythonhosted.org"' in compiled_text
checkout_index = compiled_text.index("- name: Checkout repository")
uv_index = compiled_text.index("- name: Setup uv")
python_index = compiled_text.index("- name: Set up Python")
sync_index = compiled_text.index("- name: Install Python test dependencies")
agent_index = compiled_text.index("- name: Execute GitHub Copilot CLI")
assert checkout_index < uv_index < python_index < sync_index < agent_index
assert setup_uv in compiled_text
assert setup_python in compiled_text
assert 'run: uv pip install --system -e ".[test]"' in compiled_text