From 4c6bd0828afb1cf6869d8658f43f5b7f334cbbf7 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 15:55:47 +0900 Subject: [PATCH 01/15] test(security): require atomic CodeQL action revision --- .../test_codeql_action_revision_contract.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 services/analysis-engine/tests/test_codeql_action_revision_contract.py diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py new file mode 100644 index 00000000..3c53f3e1 --- /dev/null +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -0,0 +1,61 @@ +"""Supply-chain contracts for a coherent GitHub CodeQL Action revision.""" + +from __future__ import annotations + +from pathlib import Path +import re + + +_REPOSITORY_ROOT = Path(__file__).resolve().parents[3] +_WORKFLOW_ROOT = _REPOSITORY_ROOT / ".github" / "workflows" +_EXPECTED_CODEQL_ACTION_SHA = "5595ccaf912efad79be6eef63a5619ff05969be3" +_EXPECTED_CODEQL_ACTION_VERSION = "v4.37.6" +_CODEQL_ACTION_REFERENCE = re.compile( + r"github/codeql-action/(init|autobuild|analyze|upload-sarif)@([0-9a-f]{40})([^\n]*)" +) + + +def _codeql_action_references() -> list[tuple[Path, str, str, str]]: + """Return every pinned CodeQL Action reference from checked-in workflows.""" + references: list[tuple[Path, str, str, str]] = [] + for workflow_path in sorted(_WORKFLOW_ROOT.glob("*.y*ml")): + workflow_text = workflow_path.read_text(encoding="utf-8") + for action_name, revision_sha, suffix in _CODEQL_ACTION_REFERENCE.findall( + workflow_text + ): + references.append( + (workflow_path, action_name, revision_sha, suffix.strip()) + ) + return references + + +def test_every_codeql_action_step_uses_the_same_reviewed_revision() -> None: + """Prevent independently updated phases from creating mixed CodeQL runtimes.""" + references = _codeql_action_references() + + assert references + assert {revision_sha for _, _, revision_sha, _ in references} == { + _EXPECTED_CODEQL_ACTION_SHA + } + assert all( + f"# {_EXPECTED_CODEQL_ACTION_VERSION}" in suffix + for _, _, _, suffix in references + ) + + +def test_analysis_workflow_keeps_init_autobuild_and_analyze_atomic() -> None: + """Require the analysis lifecycle to move as one immutable dependency unit.""" + workflow_path = _WORKFLOW_ROOT / "codeql.yml" + workflow_text = workflow_path.read_text(encoding="utf-8") + references = { + action_name: revision_sha + for action_name, revision_sha, _suffix in _CODEQL_ACTION_REFERENCE.findall( + workflow_text + ) + } + + assert references == { + "init": _EXPECTED_CODEQL_ACTION_SHA, + "autobuild": _EXPECTED_CODEQL_ACTION_SHA, + "analyze": _EXPECTED_CODEQL_ACTION_SHA, + } From fb7189d390b4f0a0ae79bfffcea5179929cda13d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 16:04:43 +0900 Subject: [PATCH 02/15] fix(security): align CodeQL analysis phases --- .github/workflows/codeql.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 27c5b540..ee9b6019 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,8 +32,8 @@ jobs: - python steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + - uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 with: languages: ${{ matrix.language }} - - uses: github/codeql-action/autobuild@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 - - uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + - uses: github/codeql-action/autobuild@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + - uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 From 32e3c27cebbf20a49402012852a51f7720e816fe Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 16:05:03 +0900 Subject: [PATCH 03/15] fix(security): align Scorecard SARIF uploader --- .github/workflows/ossf-scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml index 2a4b6eaa..a3c28778 100644 --- a/.github/workflows/ossf-scorecard.yml +++ b/.github/workflows/ossf-scorecard.yml @@ -79,6 +79,6 @@ jobs: python3 trusted-scorecard-scripts/scripts/checks/normalize_scorecard_sarif.py scorecard-sarif/results.sarif normalized-scorecard-results.sarif - - uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 peeled commit; SHA pinning retained as supply-chain attack mitigation. + - uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6; immutable SHA pinning retained as supply-chain attack mitigation. with: sarif_file: normalized-scorecard-results.sarif From b03aa9962d42e857245f7637d59af2da16dbc22e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 16:05:18 +0900 Subject: [PATCH 04/15] fix(security): align Trivy SARIF uploader --- .github/workflows/trivy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index d79ec32e..cd417efb 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -48,7 +48,7 @@ jobs: skip-dirs: 'services/analysis-engine/.venv' trivyignores: ./.trivyignore - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 peeled commit; SHA pinning retained as supply-chain attack mitigation. + uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6; immutable SHA pinning retained as supply-chain attack mitigation. if: always() with: sarif_file: trivy-results.sarif From a04a25f646c13b21e4da4614a4dd0b01832f2ac1 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 16:06:14 +0900 Subject: [PATCH 05/15] docs(security): record atomic CodeQL revision policy --- .../codeql-action-atomic-revision.md | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docs/doctoring/codeql-action-atomic-revision.md diff --git a/docs/doctoring/codeql-action-atomic-revision.md b/docs/doctoring/codeql-action-atomic-revision.md new file mode 100644 index 00000000..61312f4f --- /dev/null +++ b/docs/doctoring/codeql-action-atomic-revision.md @@ -0,0 +1,61 @@ +# Atomic CodeQL Action revision policy + +## Decision + +BandScope treats the CodeQL Action lifecycle as one supply-chain dependency. Every checked-in reference to `github/codeql-action/init`, `autobuild`, `analyze`, and `upload-sarif` must use the same reviewed full-length commit SHA and matching release annotation. + +The current reviewed revision is CodeQL Action `v4.37.6` at commit `5595ccaf912efad79be6eef63a5619ff05969be3`. + +GitHub documents `init` as the phase that initializes CodeQL, `autobuild` as the optional automatic build phase, and `analyze` as the phase that finalizes the database, runs queries, and uploads results. `upload-sarif` publishes SARIF generated by other tools. These phases exchange state and therefore move together in this repository rather than through independent dependency pull requests. + +## Threat and compatibility boundary + +A full commit SHA is the immutable execution identity. Tags remain useful release labels, but they are not accepted as the workflow execution reference. GitHub identifies a full-length commit SHA as the strongest immutable action reference and supports organization policy requiring that form. + +Independently updating one phase can leave the repository with mixed JavaScript bundles, CodeQL CLI expectations, feature flags, or SARIF transport behavior. Even when each individual release is valid, the mixed lifecycle has not been reviewed or tested as a unit. The atomic policy prevents both persistent drift and the transient mixed state that can occur when several Dependabot pull requests merge at different times. + +```mermaid +flowchart LR + A[CodeQL init] --> B[CodeQL autobuild] + B --> C[CodeQL analyze] + C --> D[GitHub code scanning] + E[Trivy and Scorecard SARIF] --> F[CodeQL upload-sarif] + R[One reviewed release SHA] --> A + R --> B + R --> C + R --> F +``` + +The change does not alter workflow triggers, language selection, build behavior, SARIF paths, permissions, or failure handling. It changes only the immutable CodeQL Action implementation identity and version comments. + +## Verification contract + +`services/analysis-engine/tests/test_codeql_action_revision_contract.py` scans every workflow and fails unless: + +1. all CodeQL Action phases use one exact reviewed SHA; +2. every reference carries the matching `v4.37.6` annotation; and +3. `codeql.yml` keeps `init`, `autobuild`, and `analyze` on that same revision. + +Repository CI, CodeQL, SAST, dependency/security scans, SBOM generation, central coverage evidence, automated review, independent approval, and branch protection must all validate the final exact head. Results from split predecessor pull requests are not transferable. + +## Update procedure + +1. Identify the newest supported CodeQL Action v4 release from the upstream GitHub repository. +2. Verify the tag resolves to the intended upstream commit and inspect the release notes. +3. Add or update the contract expectation first and observe the RED failure against the old revision. +4. Update every `init`, `autobuild`, `analyze`, and `upload-sarif` reference in one branch. +5. Run the focused contract, workflow/static checks, and the complete repository gates. +6. Merge only after exact-current-head review and branch protection succeed without bypass. +7. Close split dependency pull requests as superseded; do not reuse their checks or approvals. + +## Rollback + +Rollback restores the previously accepted full-length SHA across every CodeQL Action phase in one reviewed commit. A partial rollback is prohibited. After rollback, rerun the same exact-head security, quality, SARIF publication, and review gates before accepting the branch. + +## References + +GitHub. (2026). *CodeQL Action v4.37.6* [Software release]. https://github.com/github/codeql-action/releases/tag/v4.37.6 + +GitHub. (n.d.). *CodeQL code scanning for compiled languages*. GitHub Docs. Retrieved August 7, 2026, from https://docs.github.com/en/code-security/how-tos/find-and-fix-code-vulnerabilities/manage-your-configuration/codeql-for-compiled-languages + +GitHub. (n.d.). *Secure use reference*. GitHub Docs. Retrieved August 7, 2026, from https://docs.github.com/en/actions/reference/security/secure-use From 8aced19e82b1aefad54b370e2986de700ef4d75b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 16:06:39 +0900 Subject: [PATCH 06/15] docs(changelog): record atomic CodeQL update --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eea69689..25611247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ - Display the analyzed song tempo (BPM) as a badge in the rehearsal workspace. - 각 합주 역할(Role)별 개인 연습 진행도를 0~100% 범위로 기록 및 시각화할 수 있는 연습 진척도(`practiceProgress`) 트래커 기능 추가. UI 컨트롤(슬라이더 및 +/- 버튼)과 한/영 다국어 지원 포함. +### Changed + +- Updated every CodeQL Action phase and SARIF uploader together to the reviewed immutable `v4.37.6` revision, with a regression contract that prevents mixed `init`, `autobuild`, `analyze`, and `upload-sarif` versions. + ## [0.1.3] - 2026-04-29 ### Fixed @@ -51,7 +55,7 @@ - Issue #32: Implemented local analysis orchestration and secure IPC boundaries - Issue #33: Implemented secure local audio intake and project bootstrap - Issue #35: Engineered section, form, and cue anchor extraction pipeline -- Issue #34: Implemented role extraction targets and part graph +- Issue #34: Added role extraction targets and part graph - Issue #31: Added role-specific harmony, range, overlap, and confidence metrics - Issue #28: Delivered practical rehearsal workspace UI - Issue #27: Supported manual overrides, provenance tracking, and local project persistence From 829243b0f5040a1518e84fcddc63a8c58b93ceed Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 16:07:58 +0900 Subject: [PATCH 07/15] chore(changelog): preserve historical wording --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25611247..105f06d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,7 +55,7 @@ - Issue #32: Implemented local analysis orchestration and secure IPC boundaries - Issue #33: Implemented secure local audio intake and project bootstrap - Issue #35: Engineered section, form, and cue anchor extraction pipeline -- Issue #34: Added role extraction targets and part graph +- Issue #34: Implemented role extraction targets and part graph - Issue #31: Added role-specific harmony, range, overlap, and confidence metrics - Issue #28: Delivered practical rehearsal workspace UI - Issue #27: Supported manual overrides, provenance tracking, and local project persistence From 2947ea5e3d0567edb1d477d0dd70c2f2e4eb8ec6 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 16:50:36 +0900 Subject: [PATCH 08/15] fix(test): sort CodeQL contract imports --- .../tests/test_codeql_action_revision_contract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py index 3c53f3e1..e84ce3ed 100644 --- a/services/analysis-engine/tests/test_codeql_action_revision_contract.py +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -2,8 +2,8 @@ from __future__ import annotations -from pathlib import Path import re +from pathlib import Path _REPOSITORY_ROOT = Path(__file__).resolve().parents[3] From 79fd7e7cd3022a6f9c2e3d182730aa89b3cbdd6c Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 17:29:16 +0900 Subject: [PATCH 09/15] fix(test): match repository import ordering --- .../tests/test_codeql_action_revision_contract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py index e84ce3ed..3c53f3e1 100644 --- a/services/analysis-engine/tests/test_codeql_action_revision_contract.py +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -2,8 +2,8 @@ from __future__ import annotations -import re from pathlib import Path +import re _REPOSITORY_ROOT = Path(__file__).resolve().parents[3] From 8946694d350e17ad38462e7e19ab8dad62080b12 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 19:09:11 +0900 Subject: [PATCH 10/15] test(security): normalize CodeQL contract imports --- .../tests/test_codeql_action_revision_contract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py index 3c53f3e1..e84ce3ed 100644 --- a/services/analysis-engine/tests/test_codeql_action_revision_contract.py +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -2,8 +2,8 @@ from __future__ import annotations -from pathlib import Path import re +from pathlib import Path _REPOSITORY_ROOT = Path(__file__).resolve().parents[3] From 2bcc5b14f1ee30048375afd2e3ce1261fd1c7f62 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 19:14:20 +0900 Subject: [PATCH 11/15] test(security): use canonical direct stdlib imports --- .../tests/test_codeql_action_revision_contract.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py index e84ce3ed..88531287 100644 --- a/services/analysis-engine/tests/test_codeql_action_revision_contract.py +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -2,11 +2,11 @@ from __future__ import annotations +import pathlib import re -from pathlib import Path -_REPOSITORY_ROOT = Path(__file__).resolve().parents[3] +_REPOSITORY_ROOT = pathlib.Path(__file__).resolve().parents[3] _WORKFLOW_ROOT = _REPOSITORY_ROOT / ".github" / "workflows" _EXPECTED_CODEQL_ACTION_SHA = "5595ccaf912efad79be6eef63a5619ff05969be3" _EXPECTED_CODEQL_ACTION_VERSION = "v4.37.6" @@ -15,9 +15,9 @@ ) -def _codeql_action_references() -> list[tuple[Path, str, str, str]]: +def _codeql_action_references() -> list[tuple[pathlib.Path, str, str, str]]: """Return every pinned CodeQL Action reference from checked-in workflows.""" - references: list[tuple[Path, str, str, str]] = [] + references: list[tuple[pathlib.Path, str, str, str]] = [] for workflow_path in sorted(_WORKFLOW_ROOT.glob("*.y*ml")): workflow_text = workflow_path.read_text(encoding="utf-8") for action_name, revision_sha, suffix in _CODEQL_ACTION_REFERENCE.findall( From 7c9343aede26a44239b12c805fdd0ab0b1398dba Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 19:26:56 +0900 Subject: [PATCH 12/15] test(security): match canonical stdlib import layout --- .../tests/test_codeql_action_revision_contract.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py index 88531287..e84ce3ed 100644 --- a/services/analysis-engine/tests/test_codeql_action_revision_contract.py +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -2,11 +2,11 @@ from __future__ import annotations -import pathlib import re +from pathlib import Path -_REPOSITORY_ROOT = pathlib.Path(__file__).resolve().parents[3] +_REPOSITORY_ROOT = Path(__file__).resolve().parents[3] _WORKFLOW_ROOT = _REPOSITORY_ROOT / ".github" / "workflows" _EXPECTED_CODEQL_ACTION_SHA = "5595ccaf912efad79be6eef63a5619ff05969be3" _EXPECTED_CODEQL_ACTION_VERSION = "v4.37.6" @@ -15,9 +15,9 @@ ) -def _codeql_action_references() -> list[tuple[pathlib.Path, str, str, str]]: +def _codeql_action_references() -> list[tuple[Path, str, str, str]]: """Return every pinned CodeQL Action reference from checked-in workflows.""" - references: list[tuple[pathlib.Path, str, str, str]] = [] + references: list[tuple[Path, str, str, str]] = [] for workflow_path in sorted(_WORKFLOW_ROOT.glob("*.y*ml")): workflow_text = workflow_path.read_text(encoding="utf-8") for action_name, revision_sha, suffix in _CODEQL_ACTION_REFERENCE.findall( From 81ad632c3e23146611f1ed6d06154730252bae28 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 19:45:25 +0900 Subject: [PATCH 13/15] style(ci): normalize CodeQL contract imports --- .../tests/test_codeql_action_revision_contract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py index e84ce3ed..3c53f3e1 100644 --- a/services/analysis-engine/tests/test_codeql_action_revision_contract.py +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -2,8 +2,8 @@ from __future__ import annotations -import re from pathlib import Path +import re _REPOSITORY_ROOT = Path(__file__).resolve().parents[3] From ea829ee26edc7fa1bb56394f64510095565ce3ca Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 20:20:21 +0900 Subject: [PATCH 14/15] style(test): satisfy Ruff import ordering --- .../tests/test_codeql_action_revision_contract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py index 3c53f3e1..e84ce3ed 100644 --- a/services/analysis-engine/tests/test_codeql_action_revision_contract.py +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -2,8 +2,8 @@ from __future__ import annotations -from pathlib import Path import re +from pathlib import Path _REPOSITORY_ROOT = Path(__file__).resolve().parents[3] From ee4fa4c4f88b30312d631199c3948a4b307ac67f Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 7 Aug 2026 20:37:31 +0900 Subject: [PATCH 15/15] style(test): match Ruff import-block formatting --- .../tests/test_codeql_action_revision_contract.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/services/analysis-engine/tests/test_codeql_action_revision_contract.py b/services/analysis-engine/tests/test_codeql_action_revision_contract.py index e84ce3ed..1f9bc2d6 100644 --- a/services/analysis-engine/tests/test_codeql_action_revision_contract.py +++ b/services/analysis-engine/tests/test_codeql_action_revision_contract.py @@ -5,7 +5,6 @@ import re from pathlib import Path - _REPOSITORY_ROOT = Path(__file__).resolve().parents[3] _WORKFLOW_ROOT = _REPOSITORY_ROOT / ".github" / "workflows" _EXPECTED_CODEQL_ACTION_SHA = "5595ccaf912efad79be6eef63a5619ff05969be3" @@ -20,12 +19,8 @@ def _codeql_action_references() -> list[tuple[Path, str, str, str]]: references: list[tuple[Path, str, str, str]] = [] for workflow_path in sorted(_WORKFLOW_ROOT.glob("*.y*ml")): workflow_text = workflow_path.read_text(encoding="utf-8") - for action_name, revision_sha, suffix in _CODEQL_ACTION_REFERENCE.findall( - workflow_text - ): - references.append( - (workflow_path, action_name, revision_sha, suffix.strip()) - ) + for action_name, revision_sha, suffix in _CODEQL_ACTION_REFERENCE.findall(workflow_text): + references.append((workflow_path, action_name, revision_sha, suffix.strip())) return references @@ -49,9 +44,7 @@ def test_analysis_workflow_keeps_init_autobuild_and_analyze_atomic() -> None: workflow_text = workflow_path.read_text(encoding="utf-8") references = { action_name: revision_sha - for action_name, revision_sha, _suffix in _CODEQL_ACTION_REFERENCE.findall( - workflow_text - ) + for action_name, revision_sha, _suffix in _CODEQL_ACTION_REFERENCE.findall(workflow_text) } assert references == {