From 4ceae203a34be304e45ffb50672235e3d590dfd4 Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Sun, 1 Mar 2026 11:37:15 +0000 Subject: [PATCH 1/3] feat(CC-0003): add minimal GitHub Actions CI workflow - Add `.github/workflows/ci.yaml` with three parallel jobs (lint, test, test-integration) triggered on push to main and pull_request events - Use golangci-lint-action v9 (v2.10) for lint job, delegating Go setup to the action internally - Run `make test` and `make test-integration` in separate jobs using actions/setup-go with `go-version-file: go.work` for version management and automatic module caching - Pin all GitHub Actions to full 40-character commit SHAs with version comments for supply-chain hardening - Set least-privilege permissions (`contents: read`) and add concurrency group with cancel-in-progress to avoid redundant runs on superseded pushes - Add reference documentation at `docs/ci-workflow.md` covering trigger events, job descriptions, Go setup conventions, concurrency behavior, and project dependencies AI-assisted: Claude Code On-behalf-of: @SAP christian.berendt@sap.com Signed-off-by: Christian Berendt --- .github/workflows/ci.yaml | 46 ++++++++ ...dd-minimal-github-actions-ci-workflow.json | 64 +++++++++- ...l-github-actions-ci-workflow-review-1.json | 69 +++++++++++ docs/ci-workflow.md | 111 ++++++++++++++++++ 4 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yaml rename .planwerk/{features => progress}/CC-0003-a003-add-minimal-github-actions-ci-workflow.json (95%) create mode 100644 .planwerk/reviews/CC-0003-a003-add-minimal-github-actions-ci-workflow-review-1.json create mode 100644 docs/ci-workflow.md diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..c3419c7 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,46 @@ +# SPDX-FileCopyrightText: Copyright 2026 SAP SE or an SAP affiliate company +# +# SPDX-License-Identifier: Apache-2.0 +--- +name: CI + +"on": + push: + branches: [main] + pull_request: + +permissions: + contents: read + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9 + with: + version: v2.10 + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 + with: + go-version-file: go.work + - name: Run unit tests + run: make test + + test-integration: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 + with: + go-version-file: go.work + - name: Run integration tests + run: make test-integration diff --git a/.planwerk/features/CC-0003-a003-add-minimal-github-actions-ci-workflow.json b/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json similarity index 95% rename from .planwerk/features/CC-0003-a003-add-minimal-github-actions-ci-workflow.json rename to .planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json index 02669b3..61f446f 100644 --- a/.planwerk/features/CC-0003-a003-add-minimal-github-actions-ci-workflow.json +++ b/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json @@ -2,8 +2,8 @@ "feature_id": "CC-0003", "title": "A003: Add minimal GitHub Actions CI workflow", "slug": "a003-add-minimal-github-actions-ci-workflow", - "status": "prepared", - "phase": null, + "status": "processing", + "phase": "awaiting_external_review", "summary": "", "description": "**Size:** πŸ”§ small\n**Category:** infrastructure\n**Priority:** medium\n\n## Summary\n\nCreate a GitHub Actions CI workflow (`.github/workflows/ci.yaml`) that runs three parallel jobs β€” `lint`, `test`, and `test-integration` β€” on every PR and push to `main`. The workflow uses Go workspace mode via `go.work`, includes concurrency control to cancel superseded runs, and depends on the Makefile and Go workspace scaffolded by CC-0001.\n\n## Scope\n\n**Included:**\n- `.github/workflows/ci.yaml` with triggers on `push` to `main` and `pull_request`\n- `lint` job using `golangci/golangci-lint-action` against the Go workspace root\n- `test` job running `make test` (unit tests)\n- `test-integration` job running `make test-integration` (envtest-based integration tests)\n- `actions/setup-go` with Go version read from `go.mod` and module caching\n- SPDX license header (matching existing `reuse.yaml` / `deploy-docs.yaml` conventions)\n- `permissions: contents: read` (least privilege, matching `reuse.yaml`)\n- Concurrency group `${{ github.ref }}-${{ github.workflow }}` with `cancel-in-progress: true` (matching `mega-linter.yml` pattern)\n\n**Excluded (with rationale):**\n- Container image builds β€” CC-0007, separate workflow\n- Helm chart packaging/push β€” S017/S018, YAGNI until charts exist\n- E2E/Chainsaw tests β€” S018, requires kind cluster setup, not part of minimal CI\n- Code coverage reporting/thresholds β€” S018, YAGNI for the minimal CI gate\n- Branch protection rule configuration β€” repo setting, not a workflow file\n- Matrix builds per operator module β€” Makefile abstracts this via `OPERATORS` variable; Go workspace mode with `go.work` provides single cache/download\n\n## Visualization\n\n```mermaid\nflowchart TD\n trigger[\"Push to main / PR\"]\n\n trigger --> lint\n trigger --> test\n trigger --> integ\n\n subgraph lint[\"lint\"]\n L1[\"actions/checkout@v4\"] --> L2[\"actions/setup-go\"]\n L2 --> L3[\"golangci-lint-action\"]\n end\n\n subgraph test[\"test\"]\n T1[\"actions/checkout@v4\"] --> T2[\"actions/setup-go\"]\n T2 --> T3[\"make test\"]\n end\n\n subgraph integ[\"test-integration\"]\n I1[\"actions/checkout@v4\"] --> I2[\"actions/setup-go\"]\n I2 --> I3[\"make test-integration\"]\n end\n\n lint --> merge[\"PR Merge Gate\"]\n test --> merge\n integ --> merge\n```\n\n```mermaid\nsequenceDiagram\n participant Dev as Developer\n participant GH as GitHub\n participant CI as CI Workflow\n participant Lint as lint job\n participant Test as test job\n participant Integ as test-integration job\n\n Dev->>GH: Push / Open PR\n GH->>CI: Trigger ci.yaml\n par All jobs run in parallel\n CI->>Lint: golangci-lint-action\n CI->>Test: make test\n CI->>Integ: make test-integration\n end\n Lint-->>CI: pass/fail\n Test-->>CI: pass/fail\n Integ-->>CI: pass/fail\n CI-->>GH: All checks status\n GH-->>Dev: PR status update\n```\n\n## Key Components\n\n- **`.github/workflows/ci.yaml`** β€” Single workflow file with 3 parallel jobs. Follows existing conventions: SPDX header (`Copyright 2026 SAP SE or an SAP affiliate company`), `\"on\"` quoting, `ubuntu-latest`, `permissions: contents: read`. Uses `.yaml` extension matching `reuse.yaml` and `deploy-docs.yaml`\n- **`lint` job** β€” Uses `golangci/golangci-lint-action` (handles installation, caching, version pinning); targets the Go workspace root. No separate `actions/setup-go` needed β€” the action handles Go setup internally\n- **`test` job** β€” `actions/setup-go` with `go-version-file: go.mod` + module caching, then `make test`. Relies on CC-0001 Makefile iterating over `OPERATORS`\n- **`test-integration` job** β€” Same Go setup as `test`, then `make test-integration`. May require envtest binaries β€” depends on whether CC-0001's Makefile handles `setup-envtest` download within the target or needs a separate `make install-test-deps` step first\n- **Concurrency group** β€” `${{ github.ref }}-${{ github.workflow }}` with `cancel-in-progress: true`, mirroring `mega-linter.yml:32-34`\n- **Dependency** β€” Hard dependency on CC-0001 (Go workspace, Makefile targets, `.golangci.yml`) and CC-0002 (test infrastructure for `test-integration` to be meaningful)", "stories": [ @@ -322,6 +322,7 @@ "title": "Create `.github/workflows/ci.yaml` with SPDX header (Copyright 2026 SAP SE or an SAP affiliate company, Apache-2.0), `---` separator, workflow name `CI`, quoted `\"on\"` triggers (push branches: [main] + pull_request), top-level `permissions: contents: read`, concurrency group `${{ github.ref }}-${{ github.workflow }}` with cancel-in-progress: true (REQ-001, REQ-006, REQ-007, REQ-008)", "level": 1, "estimate_minutes": 15, + "status": "done", "requirements": [ "REQ-001", "REQ-006", @@ -334,6 +335,7 @@ "title": "Add `lint` job to ci.yaml β€” runs-on: ubuntu-latest, step 1: actions/checkout@v4, step 2: golangci/golangci-lint-action@v9 with `version: v2.10` pinned. No separate actions/setup-go step (action handles Go setup internally). No `needs:` key. (REQ-002, REQ-005)", "level": 1, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-002", "REQ-005" @@ -344,6 +346,7 @@ "title": "Add `test` job to ci.yaml β€” runs-on: ubuntu-latest, step 1: actions/checkout@v4, step 2: actions/setup-go@v5 with `go-version-file: go.work` (module caching enabled by default), step 3: name 'Run unit tests' with `run: make test`. No `needs:` key. (REQ-003, REQ-005)", "level": 1, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-003", "REQ-005" @@ -354,6 +357,7 @@ "title": "Add `test-integration` job to ci.yaml β€” runs-on: ubuntu-latest, step 1: actions/checkout@v4, step 2: actions/setup-go@v5 with `go-version-file: go.work` (identical to test job), step 3: name 'Run integration tests' with `run: make test-integration`. No `needs:` key. (REQ-004, REQ-005)", "level": 1, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-004", "REQ-005" @@ -364,6 +368,7 @@ "title": "Validate complete ci.yaml YAML syntax and GitHub Actions workflow schema correctness β€” valid `on`/`jobs`/`steps` structure, no YAML parsing errors, all action references use valid `owner/repo@version` format (REQ-001)", "level": 2, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-001" ] @@ -373,6 +378,7 @@ "title": "Verify SPDX header matches deploy-docs.yaml exactly: first line `# SPDX-FileCopyrightText: Copyright 2026 SAP SE or an SAP affiliate company`, second line `#`, third line `# SPDX-License-Identifier: Apache-2.0`, followed by `---` separator (REQ-008)", "level": 2, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-008" ] @@ -382,6 +388,7 @@ "title": "Verify concurrency group key is exactly `${{ github.ref }}-${{ github.workflow }}` with `cancel-in-progress: true`, matching mega-linter.yml lines 32-34 character-for-character (REQ-006)", "level": 2, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-006" ] @@ -391,6 +398,7 @@ "title": "Verify lint job has only 2 steps (checkout + golangci-lint-action), no actions/setup-go step, no working-directory override, and golangci-lint-action targets the workspace root implicitly (REQ-002)", "level": 2, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-002" ] @@ -400,6 +408,7 @@ "title": "Verify test and test-integration jobs both use `go-version-file: go.work` (not hardcoded `go-version:`), and that actions/setup-go module caching is not explicitly disabled (default cache: true) (REQ-003, REQ-004)", "level": 2, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-003", "REQ-004" @@ -410,6 +419,7 @@ "title": "Verify all three jobs (lint, test, test-integration) have no `needs:` key β€” confirming they run in parallel with no inter-job dependencies (REQ-005)", "level": 2, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-005" ] @@ -419,6 +429,7 @@ "title": "Add reference documentation for CI workflow: file location (.github/workflows/ci.yaml), trigger events, job descriptions (lint/test/test-integration), Go setup convention (go-version-file: go.work), concurrency behavior, dependency on CC-0001 Makefile targets and .golangci.yml (REQ-001 to REQ-008)", "level": 3, "estimate_minutes": 20, + "status": "done", "requirements": [ "REQ-001", "REQ-002", @@ -435,6 +446,7 @@ "title": "Cross-reference implementation against feature scope checklist β€” verify all 'Included' items present (triggers, lint, test, test-integration, setup-go, SPDX, permissions, concurrency) and all 'Excluded' items absent (no image builds, no helm, no E2E/Chainsaw, no coverage, no branch protection, no matrix builds) (all REQs)", "level": 3, "estimate_minutes": 10, + "status": "done", "requirements": [ "REQ-001", "REQ-002", @@ -590,6 +602,10 @@ "prepared": { "github_account": "berendt", "timestamp": "2026-02-22T22:51:47.893430" + }, + "processing": { + "github_account": "berendt", + "timestamp": "2026-03-01T09:29:26.354834" } }, "execution_history": [ @@ -606,6 +622,50 @@ "status": "done" } ] + }, + { + "run_id": "bfd8923c-7c70-46f8-9569-cf0e41335bc2", + "timestamp": "2026-03-01T09:45:06.550519", + "total_duration": 807.3583419322968, + "status": "completed", + "timings": [ + { + "name": "Level 1 (4 tasks)", + "duration": 105.38839960098267, + "type": "level", + "status": "done" + }, + { + "name": "Level 2 (6 tasks)", + "duration": 66.77299308776855, + "type": "level", + "status": "done" + }, + { + "name": "Level 3 (2 tasks)", + "duration": 198.62502026557922, + "type": "level", + "status": "done" + }, + { + "name": "[CC-0003] Code Review", + "duration": 156.1170859336853, + "type": "review", + "status": "done" + }, + { + "name": "[CC-0003] Improvements", + "duration": 146.03618097305298, + "type": "improve", + "status": "done" + }, + { + "name": "[CC-0003] Simplify", + "duration": 134.41866207122803, + "type": "simplify", + "status": "done" + } + ] } ] } \ No newline at end of file diff --git a/.planwerk/reviews/CC-0003-a003-add-minimal-github-actions-ci-workflow-review-1.json b/.planwerk/reviews/CC-0003-a003-add-minimal-github-actions-ci-workflow-review-1.json new file mode 100644 index 0000000..61148c9 --- /dev/null +++ b/.planwerk/reviews/CC-0003-a003-add-minimal-github-actions-ci-workflow-review-1.json @@ -0,0 +1,69 @@ +{ + "feature_id": "CC-0003", + "title": "A003: Add minimal GitHub Actions CI workflow", + "date": "2026-03-01", + "verdict": "APPROVED", + "summary": "Minimal GitHub Actions CI workflow implemented as a single `.github/workflows/ci.yaml` file with three parallel jobs (lint, test, test-integration). Follows all specified conventions: SPDX header, quoted `\"on\"`, `permissions: contents: read`, concurrency group matching mega-linter.yml. Reference documentation added at `docs/ci-workflow.md`. All plan tasks (1.1-1.4, 2.1-2.6, 3.1-3.2) are fulfilled. No excluded scope items present.", + "tests_checklist": [ + {"item": "YAML syntax validated (yaml.safe_load parses without error)", "checked": true}, + {"item": "GitHub Actions schema structure validated (name, on, permissions, concurrency, jobs keys present and correct)", "checked": true}, + {"item": "All three jobs verified parallel (no `needs:` keys)", "checked": true}, + {"item": "Action versions validated (checkout@v4, golangci-lint-action@v9 with v2.10, setup-go@v5)", "checked": true}, + {"item": "go-version-file: go.work confirmed (not hardcoded go-version)", "checked": true}, + {"item": "Module caching not explicitly disabled (actions/setup-go default cache: true)", "checked": true} + ], + "code_quality_checklist": [ + {"item": "Follows existing project conventions (SPDX header, .yaml extension, quoted on)", "checked": true}, + {"item": "Minimal and focused β€” 46 lines, no unnecessary configuration", "checked": true}, + {"item": "No dead code or commented-out sections", "checked": true}, + {"item": "Clear step naming (Run unit tests, Run integration tests)", "checked": true}, + {"item": "File location matches project structure (.github/workflows/)", "checked": true} + ], + "security_checklist": [ + {"item": "Least-privilege permissions: top-level `contents: read` only", "checked": true}, + {"item": "No job-level permission overrides", "checked": true}, + {"item": "No secrets referenced or hardcoded", "checked": true}, + {"item": "No workflow_dispatch trigger (prevents unauthorized manual runs)", "checked": true}, + {"item": "Actions pinned to major versions (@v4, @v9, @v5)", "checked": true} + ], + "architecture_checklist": [ + {"item": "Solution is minimal β€” three jobs, no complex dependencies or matrix builds", "checked": true}, + {"item": "Delegates to Makefile targets (test, test-integration) β€” no duplicated build logic", "checked": true}, + {"item": "Uses go.work for Go version (single source of truth)", "checked": true}, + {"item": "Concurrency group scoped per-branch per-workflow", "checked": true} + ], + "dry_yagni_checklist": [ + {"item": "No duplicated configuration across jobs (only necessary per-job setup)", "checked": true}, + {"item": "No excluded scope items present (no image builds, helm, E2E, coverage, matrix)", "checked": true}, + {"item": "No future-proofing or over-engineering", "checked": true} + ], + "fail_fast_checklist": [ + {"item": "Concurrency cancel-in-progress cancels superseded runs immediately", "checked": true}, + {"item": "Jobs run in parallel for fastest feedback", "checked": true} + ], + "defensive_checklist": [ + {"item": "Permissions restricted to minimum required (contents: read)", "checked": true}, + {"item": "No external inputs or user-controlled parameters in workflow", "checked": true} + ], + "security_findings": [], + "architecture_findings": [], + "issues_found": [ + { + "id": "NOTE-1", + "severity": "info", + "check_id": "C5", + "description": "The `make test-integration` target in the Makefile is currently a stub that calls `$(error ...)` on main. The CI job will fail until this target is properly implemented. This is a known dependency (CC-0002 scope item S002) and not a defect in the CI workflow itself β€” the workflow correctly delegates to the Makefile target.", + "location": "Makefile:73-74", + "fix": "No action required for CC-0003. The Makefile target will be implemented by the relevant future task." + } + ], + "suggested_improvements": [ + "Consider pinning actions to full SHA refs (e.g., actions/checkout@) instead of major version tags for supply-chain hardening β€” this is a future enhancement, not blocking for the minimal CI gate", + "When the `test-integration` Makefile target is implemented, verify the CI job passes end-to-end on a real PR" + ], + "next_steps": [ + "Merge this workflow and verify all three jobs execute successfully on the first real PR", + "Configure branch protection rules (repo setting) to require lint, test, and test-integration as required status checks", + "Implement the `test-integration` Makefile target (S002 dependency) so the test-integration CI job passes" + ] +} diff --git a/docs/ci-workflow.md b/docs/ci-workflow.md new file mode 100644 index 0000000..1466219 --- /dev/null +++ b/docs/ci-workflow.md @@ -0,0 +1,111 @@ + + +--- +title: CI Workflow +quadrant: infrastructure +--- + +# CI Workflow + +Reference documentation for the GitHub Actions CI workflow (`.github/workflows/ci.yaml`). + +## File Location + +```text +.github/workflows/ci.yaml +``` + +## Trigger Events + +The workflow triggers on: + +- **`push`** to the `main` branch β€” runs CI on every direct push to main. +- **`pull_request`** (all activity types) β€” runs CI on PR open, synchronize, and reopen. + +Pushes to non-main branches without an open PR do **not** trigger the workflow. + +## Jobs + +All three jobs run in **parallel** with no inter-job dependencies (`needs:` is absent). +Each job uses `runs-on: ubuntu-latest`. + +### `lint` + +Runs golangci-lint against the Go workspace root. + +| Step | Action | +| --- | --- | +| 1 | `actions/checkout` (SHA-pinned, v4) | +| 2 | `golangci/golangci-lint-action` (SHA-pinned, v9) with `version: v2.10` | + +The golangci-lint-action handles Go installation internally β€” no separate `actions/setup-go` step is needed. The action reads the project's `.golangci.yml` for linter configuration. + +### `test` + +Runs unit tests via the Makefile. + +| Step | Action | +| --- | --- | +| 1 | `actions/checkout` (SHA-pinned, v4) | +| 2 | `actions/setup-go` (SHA-pinned, v5) with `go-version-file: go.work` | +| 3 | `make test` | + +### `test-integration` + +Runs envtest-based integration tests via the Makefile. + +| Step | Action | +| --- | --- | +| 1 | `actions/checkout` (SHA-pinned, v4) | +| 2 | `actions/setup-go` (SHA-pinned, v5) with `go-version-file: go.work` | +| 3 | `make test-integration` | + +## Go Setup Convention + +Both `test` and `test-integration` jobs use `actions/setup-go@v5` with: + +- **`go-version-file: go.work`** β€” the Go version is read from the workspace file rather than hardcoded, so upgrading Go only requires updating `go.work`. +- **Module caching** β€” enabled by default in `actions/setup-go@v5` (caches `~/go/pkg/mod`). Not explicitly disabled. + +The `lint` job does not use a separate `actions/setup-go` step because `golangci-lint-action` manages Go installation internally. + +## Concurrency + +```yaml +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true +``` + +- Scoped per-branch per-workflow: pushing to branch A does not cancel runs on branch B. +- New pushes to the same branch cancel any in-progress CI run for that branch. +- Matches the concurrency pattern used in `mega-linter.yml`. + +## Permissions + +```yaml +permissions: + contents: read +``` + +Top-level `contents: read` applies to all jobs (least-privilege). No job-level `permissions:` overrides exist. + +## Dependencies + +This workflow depends on artifacts from [CC-0001](https://github.com/C5C3/forge/pull/1): + +- **`go.work`** β€” used by `actions/setup-go` to determine the Go version. +- **`Makefile`** β€” provides `test` and `test-integration` targets that iterate over operator modules via the `OPERATORS` variable. +- **`.golangci.yml`** β€” linter configuration consumed by `golangci-lint-action`. + +## Conventions + +- **SPDX header**: `Copyright 2026 SAP SE or an SAP affiliate company`, `Apache-2.0` β€” matching `deploy-docs.yaml`. +- **File extension**: `.yaml` (not `.yml`) β€” matching `reuse.yaml` and `deploy-docs.yaml`. +- **`"on"` quoting**: the trigger key is quoted to prevent YAML boolean interpretation. +- **YAML document separator**: `---` follows the SPDX header block. +- **SHA-pinned actions**: all `uses:` references pin to full 40-character commit SHAs with a version comment (e.g., `actions/checkout@ # v4`). This prevents supply-chain attacks via mutable tags. When updating an action version, resolve the new tag to its commit SHA and update both the hash and the comment. From 1091de5850ecaa4e8d0a75636d1e0a22943479bb Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Sun, 1 Mar 2026 11:37:19 +0000 Subject: [PATCH 2/3] chore(CC-0003): link PR https://github.com/C5C3/forge/pull/3 --- .../CC-0003-a003-add-minimal-github-actions-ci-workflow.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json b/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json index 61f446f..c931c71 100644 --- a/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json +++ b/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json @@ -608,6 +608,8 @@ "timestamp": "2026-03-01T09:29:26.354834" } }, + "github_pr": "https://github.com/C5C3/forge/pull/3", + "pr_number": 3, "execution_history": [ { "run_id": "e5b09a22-e1b5-4eda-9353-41e58bf3f3b2", From 5d671fb5cf6c922d700a758f1ba60c96825ef0f6 Mon Sep 17 00:00:00 2001 From: Christian Berendt Date: Sun, 1 Mar 2026 14:57:18 +0000 Subject: [PATCH 3/3] fix(CC-0003): fix failing CI check: lint AI-assisted: Claude Code On-behalf-of: @SAP christian.berendt@sap.com Signed-off-by: Christian Berendt --- .github/workflows/ci.yaml | 1 + .golangci.yml | 28 +++++++-------- ...dd-minimal-github-actions-ci-workflow.json | 2 +- ...-review-by-sourcery-ai-bot-external-1.json | 35 +++++++++++++++++++ 4 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 .planwerk/reviews/CC-0003-github-review-by-sourcery-ai-bot-external-1.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c3419c7..9813658 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,6 +24,7 @@ jobs: - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9 with: version: v2.10 + args: ./internal/common/... ./operators/c5c3/... ./operators/keystone/... test: runs-on: ubuntu-latest diff --git a/.golangci.yml b/.golangci.yml index 7109c34..c45bf9d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,26 +1,24 @@ +version: "2" + run: timeout: 5m linters: + default: none enable: - govet - errcheck - staticcheck - unused - - gosimple - ineffassign - - typecheck - gocritic - -issues: - exclude-rules: - - path: "zz_generated.*\\.go$" - linters: - - govet - - errcheck - - staticcheck - - unused - - gosimple - - ineffassign - - typecheck - - gocritic + exclusions: + rules: + - path: "zz_generated.*\\.go$" + linters: + - govet + - errcheck + - staticcheck + - unused + - ineffassign + - gocritic diff --git a/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json b/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json index c931c71..004cccb 100644 --- a/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json +++ b/.planwerk/progress/CC-0003-a003-add-minimal-github-actions-ci-workflow.json @@ -3,7 +3,7 @@ "title": "A003: Add minimal GitHub Actions CI workflow", "slug": "a003-add-minimal-github-actions-ci-workflow", "status": "processing", - "phase": "awaiting_external_review", + "phase": "improving", "summary": "", "description": "**Size:** πŸ”§ small\n**Category:** infrastructure\n**Priority:** medium\n\n## Summary\n\nCreate a GitHub Actions CI workflow (`.github/workflows/ci.yaml`) that runs three parallel jobs β€” `lint`, `test`, and `test-integration` β€” on every PR and push to `main`. The workflow uses Go workspace mode via `go.work`, includes concurrency control to cancel superseded runs, and depends on the Makefile and Go workspace scaffolded by CC-0001.\n\n## Scope\n\n**Included:**\n- `.github/workflows/ci.yaml` with triggers on `push` to `main` and `pull_request`\n- `lint` job using `golangci/golangci-lint-action` against the Go workspace root\n- `test` job running `make test` (unit tests)\n- `test-integration` job running `make test-integration` (envtest-based integration tests)\n- `actions/setup-go` with Go version read from `go.mod` and module caching\n- SPDX license header (matching existing `reuse.yaml` / `deploy-docs.yaml` conventions)\n- `permissions: contents: read` (least privilege, matching `reuse.yaml`)\n- Concurrency group `${{ github.ref }}-${{ github.workflow }}` with `cancel-in-progress: true` (matching `mega-linter.yml` pattern)\n\n**Excluded (with rationale):**\n- Container image builds β€” CC-0007, separate workflow\n- Helm chart packaging/push β€” S017/S018, YAGNI until charts exist\n- E2E/Chainsaw tests β€” S018, requires kind cluster setup, not part of minimal CI\n- Code coverage reporting/thresholds β€” S018, YAGNI for the minimal CI gate\n- Branch protection rule configuration β€” repo setting, not a workflow file\n- Matrix builds per operator module β€” Makefile abstracts this via `OPERATORS` variable; Go workspace mode with `go.work` provides single cache/download\n\n## Visualization\n\n```mermaid\nflowchart TD\n trigger[\"Push to main / PR\"]\n\n trigger --> lint\n trigger --> test\n trigger --> integ\n\n subgraph lint[\"lint\"]\n L1[\"actions/checkout@v4\"] --> L2[\"actions/setup-go\"]\n L2 --> L3[\"golangci-lint-action\"]\n end\n\n subgraph test[\"test\"]\n T1[\"actions/checkout@v4\"] --> T2[\"actions/setup-go\"]\n T2 --> T3[\"make test\"]\n end\n\n subgraph integ[\"test-integration\"]\n I1[\"actions/checkout@v4\"] --> I2[\"actions/setup-go\"]\n I2 --> I3[\"make test-integration\"]\n end\n\n lint --> merge[\"PR Merge Gate\"]\n test --> merge\n integ --> merge\n```\n\n```mermaid\nsequenceDiagram\n participant Dev as Developer\n participant GH as GitHub\n participant CI as CI Workflow\n participant Lint as lint job\n participant Test as test job\n participant Integ as test-integration job\n\n Dev->>GH: Push / Open PR\n GH->>CI: Trigger ci.yaml\n par All jobs run in parallel\n CI->>Lint: golangci-lint-action\n CI->>Test: make test\n CI->>Integ: make test-integration\n end\n Lint-->>CI: pass/fail\n Test-->>CI: pass/fail\n Integ-->>CI: pass/fail\n CI-->>GH: All checks status\n GH-->>Dev: PR status update\n```\n\n## Key Components\n\n- **`.github/workflows/ci.yaml`** β€” Single workflow file with 3 parallel jobs. Follows existing conventions: SPDX header (`Copyright 2026 SAP SE or an SAP affiliate company`), `\"on\"` quoting, `ubuntu-latest`, `permissions: contents: read`. Uses `.yaml` extension matching `reuse.yaml` and `deploy-docs.yaml`\n- **`lint` job** β€” Uses `golangci/golangci-lint-action` (handles installation, caching, version pinning); targets the Go workspace root. No separate `actions/setup-go` needed β€” the action handles Go setup internally\n- **`test` job** β€” `actions/setup-go` with `go-version-file: go.mod` + module caching, then `make test`. Relies on CC-0001 Makefile iterating over `OPERATORS`\n- **`test-integration` job** β€” Same Go setup as `test`, then `make test-integration`. May require envtest binaries β€” depends on whether CC-0001's Makefile handles `setup-envtest` download within the target or needs a separate `make install-test-deps` step first\n- **Concurrency group** β€” `${{ github.ref }}-${{ github.workflow }}` with `cancel-in-progress: true`, mirroring `mega-linter.yml:32-34`\n- **Dependency** β€” Hard dependency on CC-0001 (Go workspace, Makefile targets, `.golangci.yml`) and CC-0002 (test infrastructure for `test-integration` to be meaningful)", "stories": [ diff --git a/.planwerk/reviews/CC-0003-github-review-by-sourcery-ai-bot-external-1.json b/.planwerk/reviews/CC-0003-github-review-by-sourcery-ai-bot-external-1.json new file mode 100644 index 0000000..f269041 --- /dev/null +++ b/.planwerk/reviews/CC-0003-github-review-by-sourcery-ai-bot-external-1.json @@ -0,0 +1,35 @@ +{ + "feature_id": "CC-0003", + "title": "GitHub Review by sourcery-ai[bot]", + "summary": "Hey - I've found 1 issue, and left some high level feedback:\n\n- Consider adding `paths` / `paths-ignore` filters to the workflow triggers so that docs-only or non-Go changes don’t unnecessarily run the full CI pipeline.\n- It may be useful to set explicit `timeout-minutes` values on each job (lint, test, test-integration) to avoid hanging runs consuming runners indefinitely if something stalls.\n\n
\nPrompt for AI Agents\n\n~~~markdown\nPlease address the comments from this code review:\n\n## Overall Comments\n- Consider adding `paths` / `paths-ignore` filters to the workflow triggers so that docs-only or non-Go changes don’t unnecessarily run the full CI pipeline.\n- It may be useful to set explicit `timeout-minutes` values on each job (lint, test, test-integration) to avoid hanging runs consuming runners indefinitely if something stalls.\n\n## Individual Comments\n\n### Comment 1\n\n\n+ - name: Run unit tests\n+ run: make test\n+\n+ test-integration:\n+ runs-on: ubuntu-latest\n+ steps:\n+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4\n+ - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5\n+ with:\n+ go-version-file: go.work\n+ - name: Run integration tests\n+ run: make test-integration\n\n\n**suggestion (testing):** Adding explicit timeouts for long-running integration tests can prevent stuck workflows.\n\nSince `make test-integration` may depend on external services and could hang, please configure `timeout-minutes` on this job (or the test step) so a stuck run doesn’t block runners indefinitely.\n\n```suggestion\n test-integration:\n runs-on: ubuntu-latest\n timeout-minutes: 30\n```\n\n~~~\n\n
\n\n***\n\n
\nSourcery is free for open source - if you like our reviews please consider sharing them ✨\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20got%20an%20instant%20code%20review%20from%20%40SourceryAI%2C%20and%20it%20was%20brilliant%21%20It%27s%20free%20for%20open%20source%20and%20has%20a%20free%20trial%20for%20private%20code.%20Check%20it%20out%20https%3A//sourcery.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20got%20an%20instant%20code%20review%20from%20%40SourceryAI%2C%20and%20it%20was%20brilliant%21%20It%27s%20free%20for%20open%20source%20and%20has%20a%20free%20trial%20for%20private%20code.%20Check%20it%20out%20https%3A//sourcery.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https://sourcery.ai)\n- [Facebook](https://www.facebook.com/sharer/sharer.php?u=https://sourcery.ai)\n\n
\n\n\nHelp me be more useful! Please click πŸ‘ or πŸ‘Ž on each comment and I'll use the feedback to improve your reviews.\n", + "verdict": "NEEDS_CHANGES", + "tests_checklist": [], + "code_quality_checklist": [], + "security_checklist": [], + "architecture_checklist": [], + "dry_yagni_checklist": [], + "fail_fast_checklist": [], + "defensive_checklist": [], + "security_findings": [], + "architecture_findings": [], + "issues_found": [], + "suggested_improvements": [], + "next_steps": [], + "reviewer": "sourcery-ai[bot]", + "date": "2026-03-01T11:38:24Z", + "commit_reference": "", + "review_type": "external", + "sequence_number": 1, + "external_feedback": "Hey - I've found 1 issue, and left some high level feedback:\n\n- Consider adding `paths` / `paths-ignore` filters to the workflow triggers so that docs-only or non-Go changes don’t unnecessarily run the full CI pipeline.\n- It may be useful to set explicit `timeout-minutes` values on each job (lint, test, test-integration) to avoid hanging runs consuming runners indefinitely if something stalls.\n\n
\nPrompt for AI Agents\n\n~~~markdown\nPlease address the comments from this code review:\n\n## Overall Comments\n- Consider adding `paths` / `paths-ignore` filters to the workflow triggers so that docs-only or non-Go changes don’t unnecessarily run the full CI pipeline.\n- It may be useful to set explicit `timeout-minutes` values on each job (lint, test, test-integration) to avoid hanging runs consuming runners indefinitely if something stalls.\n\n## Individual Comments\n\n### Comment 1\n\n\n+ - name: Run unit tests\n+ run: make test\n+\n+ test-integration:\n+ runs-on: ubuntu-latest\n+ steps:\n+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4\n+ - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5\n+ with:\n+ go-version-file: go.work\n+ - name: Run integration tests\n+ run: make test-integration\n\n\n**suggestion (testing):** Adding explicit timeouts for long-running integration tests can prevent stuck workflows.\n\nSince `make test-integration` may depend on external services and could hang, please configure `timeout-minutes` on this job (or the test step) so a stuck run doesn’t block runners indefinitely.\n\n```suggestion\n test-integration:\n runs-on: ubuntu-latest\n timeout-minutes: 30\n```\n\n~~~\n\n
\n\n***\n\n
\nSourcery is free for open source - if you like our reviews please consider sharing them ✨\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20got%20an%20instant%20code%20review%20from%20%40SourceryAI%2C%20and%20it%20was%20brilliant%21%20It%27s%20free%20for%20open%20source%20and%20has%20a%20free%20trial%20for%20private%20code.%20Check%20it%20out%20https%3A//sourcery.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20got%20an%20instant%20code%20review%20from%20%40SourceryAI%2C%20and%20it%20was%20brilliant%21%20It%27s%20free%20for%20open%20source%20and%20has%20a%20free%20trial%20for%20private%20code.%20Check%20it%20out%20https%3A//sourcery.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https://sourcery.ai)\n- [Facebook](https://www.facebook.com/sharer/sharer.php?u=https://sourcery.ai)\n\n
\n\n\nHelp me be more useful! Please click πŸ‘ or πŸ‘Ž on each comment and I'll use the feedback to improve your reviews.\n", + "code_comments": [ + { + "body": "**suggestion (testing):** Adding explicit timeouts for long-running integration tests can prevent stuck workflows.\n\nSince `make test-integration` may depend on external services and could hang, please configure `timeout-minutes` on this job (or the test step) so a stuck run doesn’t block runners indefinitely.\n\n```suggestion\n test-integration:\n runs-on: ubuntu-latest\n timeout-minutes: 30\n```", + "path": ".github/workflows/ci.yaml", + "line": 39, + "author": "sourcery-ai[bot]", + "created_at": "2026-03-01T11:38:24Z", + "id": null + } + ], + "github_review_id": 3871953393 +} \ No newline at end of file