Skip to content

feat: backend split — TaskBackend/ChatBackend interfaces and backends config map #441

feat: backend split — TaskBackend/ChatBackend interfaces and backends config map

feat: backend split — TaskBackend/ChatBackend interfaces and backends config map #441

Workflow file for this run

name: CI / Build and Push
on:
push:
branches: [main]
paths-ignore:
- "README.md"
- "CLAUDE.md"
- "config.yaml.example"
- "docs/**"
- "LICENSE"
pull_request:
branches: [main]
paths-ignore:
- "README.md"
- "CLAUDE.md"
- "config.yaml.example"
- "docs/**"
- "LICENSE"
workflow_dispatch:
jobs:
go-checks:
if: github.event_name != 'push'
runs-on: self-hosted
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: Prepare web/dist placeholder for go:embed
run: mkdir -p web/dist && touch web/dist/.gitkeep
- name: go vet
run: go vet ./...
- name: go test
run: go test ./...
- name: go test -race -short
run: go test -race -short ./...
env:
CGO_ENABLED: "1"
- name: golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.11.4
frontend-checks:
if: github.event_name != 'push'
runs-on: self-hosted
defaults:
run:
working-directory: web
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: "20"
- name: npm ci
run: npm ci
- name: npm run lint
run: npm run lint
- name: npm run test
run: npm run test --if-present
- name: npm run build
run: npm run build
- name: npm audit
run: npm audit --audit-level=high
govulncheck:
if: github.event_name != 'push'
runs-on: self-hosted
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: Prepare web/dist placeholder for go:embed
run: mkdir -p web/dist && touch web/dist/.gitkeep
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
# Fails only on symbol-level findings (your code actually calls the
# vulnerable symbol) that also have an upstream fix available.
# Module/package-level findings without a callable trace are noise from
# transitive deps and don't block CI.
- name: Run govulncheck (fail only on callable, fixable findings)
run: |
set -euo pipefail
govulncheck -format=json ./... > /tmp/vuln.json 2>&1 || true
FIXABLE=$(jq -s '[.[] | select(.finding != null
and (.finding.fixed_version // "") != ""
and (.finding.trace | any((.function // "") != "")))] | length' /tmp/vuln.json)
echo "callable + fixable findings: ${FIXABLE}"
govulncheck ./... || true
if [ "${FIXABLE:-0}" -gt 0 ]; then
echo "::error::Callable, fixable vulnerabilities detected. See output above."
exit 1
fi
echo "No callable, fixable vulnerabilities. Remaining findings are uncalled by this code or have no upstream fix."
hadolint:
if: github.event_name != 'push'
runs-on: self-hosted
steps:
- uses: actions/checkout@v6
- name: Hadolint
uses: hadolint/hadolint-action@v3.3.0
with:
dockerfile: Dockerfile
shellcheck:
if: github.event_name != 'push'
runs-on: self-hosted
steps:
- uses: actions/checkout@v6
- name: ShellCheck
uses: ludeeus/action-shellcheck@2.0.0
with:
scandir: scripts
image-scan:
if: github.event_name != 'push'
runs-on: self-hosted
steps:
- uses: actions/checkout@v6
- name: Prepare web/dist placeholder for go:embed
run: mkdir -p web/dist && touch web/dist/.gitkeep
- name: Build image for scan
run: docker build -t contextmatrix:scan .
- name: Trivy image scan
uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: contextmatrix:scan
format: table
severity: CRITICAL,HIGH
exit-code: "1"
ignore-unfixed: true
vuln-type: os,library
scanners: vuln
- name: Clean up scan image
if: always()
run: docker rmi contextmatrix:scan || true
build:
runs-on: self-hosted
needs: [go-checks, frontend-checks, govulncheck, hadolint, shellcheck, image-scan]
if: |
always() &&
(github.event_name == 'push' || github.event_name == 'workflow_dispatch') &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled')
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Set image tag
run: |
SHORT_SHA="${GITHUB_SHA::7}"
echo "SHORT_SHA=${SHORT_SHA}" >> "$GITHUB_ENV"
if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then
BRANCH_SLUG=$(echo "${GITHUB_REF_NAME}" | tr '[:upper:]' '[:lower:]' | sed 's|[^a-z0-9._-]|-|g' | cut -c1-50)
echo "IMAGE_TAG=${BRANCH_SLUG}-${SHORT_SHA}" >> "$GITHUB_ENV"
echo "PUSH_LATEST=false" >> "$GITHUB_ENV"
else
echo "IMAGE_TAG=${SHORT_SHA}" >> "$GITHUB_ENV"
echo "PUSH_LATEST=true" >> "$GITHUB_ENV"
fi
- name: Set version info
run: |
echo "BUILD_TIME=$(date -u '+%Y-%m-%d %H:%M')" >> "$GITHUB_ENV"
VERSION=$(git describe --tags --exact-match 2>/dev/null || true)
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
- name: Build image
run: |
TAGS="-t ${{ vars.REGISTRY }}/contextmatrix:${IMAGE_TAG}"
if [ "${PUSH_LATEST}" = "true" ]; then
TAGS="${TAGS} -t ${{ vars.REGISTRY }}/contextmatrix:latest"
fi
docker build \
--build-arg VERSION="${VERSION}" \
--build-arg GIT_COMMIT="${SHORT_SHA}" \
--build-arg BUILD_TIME="${BUILD_TIME}" \
${TAGS} \
.
- name: Push image
run: |
docker push ${{ vars.REGISTRY }}/contextmatrix:${IMAGE_TAG}
if [ "${PUSH_LATEST}" = "true" ]; then
docker push ${{ vars.REGISTRY }}/contextmatrix:latest
fi
- name: Clean up
if: always()
run: docker image prune -f