name: CodeQL # Stub workflow — CodeQL Action is structurally incompatible with Gitea # Actions (post-2026-05-06 SCM migration off GitHub). # # Why this is a stub, not a real CodeQL run: # # 1. github/codeql-action/init@v4 hits api.github.com endpoints # (CodeQL CLI bundle download + query-pack registry + telemetry) # that Gitea 1.22.x does NOT proxy. The act_runner has # GITHUB_SERVER_URL=https://git.moleculesai.app correctly set # (per saved memory feedback_act_runner_github_server_url and # /config.yaml on the operator host), but the Gitea API surface # simply does not implement the codeql-action bundle endpoints. # Observed in run 1d/3101 (2026-05-07): "::error::404 page not # found" inside the Initialize CodeQL step, before any analysis. # # 2. PR #35 attempted to mark `continue-on-error: true` at the JOB # level (correct YAML structure). Gitea 1.22.6 does NOT propagate # job-level continue-on-error to the commit-status API — every # matrix leg still posts `failure` to the status surface, which # keeps OVERALL=failure on every push to main + staging and # blocks visual auto-promote signals (#156). # # 3. Hongming policy decision (2026-05-07, task #156): CodeQL is # ADVISORY, not blocking, on Gitea Actions. We do not block PR # merge or staging→main promotion on CodeQL findings until we # have a Gitea-compatible static-analysis pipeline. # # What this stub preserves: # # - Workflow name `CodeQL` (referenced by auto-promote-staging.yml # line 67 as a workflow_run gate — must stay stable). # - Job name template `Analyze (${{ matrix.language }})` and the # 3-leg matrix (go, javascript-typescript, python). Branch # protection / required-check parity (#144) keys on these # exact context names. # - merge_group + push + pull_request + schedule triggers, so the # merge-queue check name still resolves (per saved memory # feedback_branch_protection_check_name_parity). # # Re-enabling real analysis (future work): # # - Option A: self-hosted Semgrep / OpenGrep via a custom action # that doesn't hit api.github.com. Tracked behind #156 follow-up. # - Option B: Sonatype Nexus IQ or similar, called from a step # that uses the Gitea-issued token only. # - Option C: re-host this workflow on a small GitHub mirror used # ONLY for SAST (push-mirrored from Gitea). Acceptable trade-off # if/when payment is restored on a non-suspended GitHub org — # but per saved memory feedback_no_single_source_of_truth, we # should design for multi-vendor backup, not GitHub-only SAST. # # Until one of those lands, this stub keeps commit-status green so # the auto-promote chain isn't permanently red on a tool we cannot # actually run. # # Security policy: ADVISORY. We accept the residual risk of un-scanned # pushes during this window. Compensating controls in place: # - secret-scan.yml runs on every push (active, blocks on hits) # - block-internal-paths.yml blocks forbidden file paths # - lint-curl-status-capture.yml catches one specific class of bug # - branch-protection-drift.yml + the merge_group required-checks # parity keep the gate surface stable # These are not equivalent to CodeQL coverage. Status of the # replacement plan is tracked in #156. on: push: branches: [main, staging] pull_request: branches: [main, staging] # Required so the matrix legs emit a real result on the queued # commit instead of a false-green when merge queue is enabled. # Per saved memory feedback_branch_protection_check_name_parity: # path-filtered / matrix workflows MUST emit the protected name # via a job that always runs. merge_group: types: [checks_requested] schedule: # Weekly heartbeat. Cheap on a stub (the no-op job is ~5s) but # keeps the workflow visible in Gitea's Actions UI so the next # operator notices it's a stub instead of a missing surface. - cron: '30 1 * * 0' # Workflow-level concurrency: only one stub run per branch/PR at a # time. cancel-in-progress: false because a quick follow-up push # shouldn't kill an in-flight run — even though the stub is fast, # the contract should match a real CodeQL run for when we re-enable. concurrency: group: codeql-${{ github.ref }} cancel-in-progress: false permissions: actions: read contents: read # No security-events: write — we don't call the upload API anyway, # GHAS isn't on Gitea. jobs: analyze: # Job NAME shape is load-bearing — auto-promote-staging.yml + # branch protection both key on `Analyze (${{ matrix.language }})`. # Do NOT rename without coordinating both surfaces. name: Analyze (${{ matrix.language }}) runs-on: ubuntu-latest timeout-minutes: 5 strategy: fail-fast: false matrix: language: [go, javascript-typescript, python] steps: # Single-step stub: log the policy decision + emit success. # Exit 0 explicitly so the commit-status API records `success` # for each of the three matrix legs. - name: CodeQL stub (advisory, non-blocking on Gitea) shell: bash run: | set -euo pipefail cat <