version: "1" name: orca-ci description: Orca — offline/CLI-first orchestration engine. Full release flow via CoreCI. # CoreCI configuration for orca. # # Each pipeline runs in an isolated container with the golang:1.25 toolchain. # All four pipelines (validate, build, test, release) must pass before a tag # can be published. The release pipeline is gated on the existence of a # semver tag (vX.Y.Z) and is the only pipeline that touches the Gitea API. # # P03 (v0.2) added three security-scanning stages to the `validate` pipeline: # - gosec (REQ-014, REQ-040) Static analysis for Go security smells # - govulncheck (REQ-014, REQ-027) Offline vuln scan of dependencies # - gitleaks (REQ-039) Pre-commit-style secret scan # v0.8 P03 added a requirements-hygiene stage: # - verify-reqs (REQ-060) ROADMAP COMPLETE ↔ REQUIREMENTS Complete # The `test` pipeline runs with -race (REQ-031). # See docs/security-scanning.md for operator-facing details. pipelines: validate: description: Validate Go toolchain, formatting, and security scans steps: - name: go-version image: golang:1.25.12 commands: - go version - gofmt -l . - go vet ./... - name: verify-reqs image: golang:1.25.12 commands: - make verify-reqs - name: gosec image: golang:1.25.12 commands: - go install github.com/securego/gosec/v2/cmd/gosec@v2.18.2 - gosec -fmt text -quiet ./... - name: govulncheck image: golang:1.25.12 env: # REQ-027: offline mode. GOFLAGS=-mod=mod ensures module mode; # GOVULNCHECK_DB (when present) overrides the bundled DB. GOFLAGS: -mod=mod commands: - go install golang.org/x/vuln/cmd/govulncheck@v1.1.3 - govulncheck -mode binary ./... - name: gitleaks image: golang:1.25.12 commands: - apk add --no-cache curl - sh -c "$(curl -fsSL https://github.com/gitleaks/gitleaks/releases/latest/download/install.sh)" - gitleaks detect --source . --config .gitleaks.toml --baseline-path .gitleaks-baseline.json --no-banner build: description: Build the orca binary with version injection steps: - name: build image: golang:1.25.12 env: VERSION: ${CI_COMMIT_TAG:-dev} GIT_COMMIT: ${CI_COMMIT_SHA} BUILD_TIME: ${CI_BUILD_TIME} commands: - | LDFLAGS="-s -w \ -X git.cloudinit.dev/coreci/orca/internal/cli.version=${VERSION} \ -X git.cloudinit.dev/coreci/orca/internal/cli.gitCommit=${GIT_COMMIT} \ -X git.cloudinit.dev/coreci/orca/internal/cli.buildTime=${BUILD_TIME}" go build -trimpath -ldflags="${LDFLAGS}" -o bin/orca ./cmd/orca - file bin/orca - ./bin/orca version test: description: Run all tests with race detection and coverage (REQ-031) steps: - name: test image: golang:1.25.12 commands: - go test -race -coverprofile=coverage.out ./... - go tool cover -func=coverage.out | tail -1 release: description: Full release flow — versioned build, tarball, changelog, Gitea release when: ref: "refs/tags/v*" steps: - name: build-artifact image: golang:1.25.12 env: VERSION: ${CI_COMMIT_TAG} GIT_COMMIT: ${CI_COMMIT_SHA} BUILD_TIME: ${CI_BUILD_TIME} commands: - | LDFLAGS="-s -w \ -X git.cloudinit.dev/coreci/orca/internal/cli.version=${VERSION} \ -X git.cloudinit.dev/coreci/orca/internal/cli.gitCommit=${GIT_COMMIT} \ -X git.cloudinit.dev/coreci/orca/internal/cli.buildTime=${BUILD_TIME}" go build -trimpath -ldflags="${LDFLAGS}" -o bin/orca ./cmd/orca - make changelog - tar -czf orca-${VERSION}-linux-amd64.tar.gz -C bin orca - sha256sum orca-${VERSION}-linux-amd64.tar.gz > SHA256SUMS - ls -lh orca-${VERSION}-linux-amd64.tar.gz SHA256SUMS - cat SHA256SUMS - name: gitea-release image: golang:1.25.12 env: GITEA_TOKEN: ${GITEA_TOKEN} VERSION: ${CI_COMMIT_TAG} commands: - apk add --no-cache curl tar python3 - sh -c "$(curl -fsSL https://gitea.com/gitea/tea/releases/latest/download/install.sh)" - tea releases create ${VERSION} --repo coreci/orca --title "Orca ${VERSION}" --note-file CHANGELOG.md --asset orca-${VERSION}-linux-amd64.tar.gz --asset SHA256SUMS - | # Verify assets are actually attached (REQ-097, gate C-21). # tea releases create has been observed to exit 0 without # attaching the asset in some versions. Verify via the API. ASSET_COUNT=$(curl -fsSL \ "https://git.cloudinit.dev/api/v1/repos/coreci/orca/releases/tags/${VERSION}" \ | python3 -c "import json,sys; r=json.load(sys.stdin); print(len(r.get('assets',[])))") echo "Release ${VERSION} has ${ASSET_COUNT} assets" if [ "${ASSET_COUNT}" -lt 2 ]; then echo "ERROR: Expected at least 2 assets (tarball + SHA256SUMS), got ${ASSET_COUNT}" echo "Attempting to attach assets manually..." TARBALL_URL=$(curl -fsSL \ "https://git.cloudinit.dev/api/v1/repos/coreci/orca/releases/tags/${VERSION}" \ | python3 -c "import json,sys; r=json.load(sys.stdin); print(r.get('id',''))") if [ -n "${TARBALL_URL}" ]; then curl -fsSL -X "POST" \ "https://git.cloudinit.dev/api/v1/repos/coreci/orca/releases/${TARBALL_URL}/assets?name=orca-${VERSION}-linux-amd64.tar.gz" \ -H "Authorization: token ${GITEA_TOKEN}" \ -F "attachment=@orca-${VERSION}-linux-amd64.tar.gz" curl -fsSL -X "POST" \ "https://git.cloudinit.dev/api/v1/repos/coreci/orca/releases/${TARBALL_URL}/assets?name=SHA256SUMS" \ -H "Authorization: token ${GITEA_TOKEN}" \ -F "attachment=@SHA256SUMS" fi fi - name: container-publish description: Build and publish OCI image to Gitea container registry (REQ-046) image: docker:24-cli env: GITEA_TOKEN: ${GITEA_TOKEN} VERSION: ${CI_COMMIT_TAG} GIT_COMMIT: ${CI_COMMIT_SHA} BUILD_TIME: ${CI_BUILD_TIME} commands: - docker build --build-arg VERSION=${VERSION} --build-arg GIT_COMMIT=${GIT_COMMIT} --build-arg BUILD_TIME=${BUILD_TIME} -t git.cloudinit.dev/coreci/orca:${VERSION} -t git.cloudinit.dev/coreci/orca:latest . - echo "${GITEA_TOKEN}" | docker login git.cloudinit.dev -u cloudinit-bot --password-stdin - docker push git.cloudinit.dev/coreci/orca:${VERSION} - docker push git.cloudinit.dev/coreci/orca:latest - docker logout git.cloudinit.dev