Nereus/.forgejo/workflows/pipeline.yml
Fi3w0 12ac14f709
Some checks failed
CI and deploy / verify (push) Successful in 2m13s
CI and deploy / publish (push) Successful in 37s
CI and deploy / deploy (push) Failing after 3s
CI and deploy / mirror (push) Has been skipped
fix(ci): use a valid mirror toggle
2026-08-28 01:04:26 +02:00

229 lines
8.7 KiB
YAML

name: CI and deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
verify:
runs-on: docker
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Scan secrets
run: |
docker run --rm -v "$PWD:/repo" \
ghcr.io/gitleaks/gitleaks:v8.30.1 \
detect --source /repo --config /repo/.gitleaks.toml --redact -v
- name: Test API
run: |
docker run --rm -v "$PWD/apps/api:/src" -w /src golang:1.26 \
bash -ec 'go vet ./... && go test -race ./...'
- name: Test load generator
run: |
docker run --rm -v "$PWD/apps/loadgen:/src" -w /src golang:1.26 \
bash -ec 'go vet ./... && go test -race ./... && test "$(wc -l < main.go)" -lt 200'
- name: Lint Go
run: |
docker run --rm -v "$PWD:/repo" -w /repo/apps/api \
golangci/golangci-lint:v2.12.2 golangci-lint run
docker run --rm -v "$PWD:/repo" -w /repo/apps/loadgen \
golangci/golangci-lint:v2.12.2 golangci-lint run
- name: Check reachable Go vulnerabilities
run: |
docker run --rm -v "$PWD/apps/api:/src" -w /src golang:1.26 \
bash -ec 'go run golang.org/x/vuln/cmd/govulncheck@v1.7.0 ./...'
docker run --rm -v "$PWD/apps/loadgen:/src" -w /src golang:1.26 \
bash -ec 'go run golang.org/x/vuln/cmd/govulncheck@v1.7.0 ./...'
- name: Check frontend and shell syntax
run: |
docker run --rm -v "$PWD:/repo" -w /repo node:24-alpine \
node --check apps/web/app.js
docker run --rm -v "$PWD:/repo" -w /repo bash:5.3 \
bash -ec 'for file in scripts/k3d/lab.sh scripts/provision/bootstrap.sh scripts/provision/lab.sh; do bash -n "$file"; done'
- name: Validate Terraform
run: |
for stack in terraform/infra terraform/platform
do
docker run --rm -v "$PWD:/work" -w "/work/$stack" \
hashicorp/terraform:1.15.9 fmt -check
docker run --rm -v "$PWD:/work" -w "/work/$stack" \
hashicorp/terraform:1.15.9 init -backend=false -lockfile=readonly
docker run --rm -v "$PWD:/work" -w "/work/$stack" \
hashicorp/terraform:1.15.9 validate
done
- name: Validate Compose and Kubernetes configuration
env:
CLUSTER_API_UPSTREAM: 192.0.2.1:8080
NEREUS_HOST: nereus.example.test
run: |
docker compose -f compose.yaml config -q
docker compose -f build/compose.mini.yaml config -q
for path in \
deploy/base \
deploy/overlays/dev \
deploy/overlays/prod \
deploy/rollouts \
deploy/observability
do
docker run --rm -v "$PWD:/work" -w /work \
registry.k8s.io/kubectl:v1.33.4 kustomize "$path" >/dev/null
done
- name: Scan configuration
run: |
docker run --rm -v "$PWD:/repo" -w /repo aquasec/trivy:0.74.0 \
config --severity HIGH,CRITICAL --exit-code 1 \
--skip-dirs .git --skip-dirs terraform .
publish:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: verify
runs-on: docker
env:
API_IMAGE: git.fiwlabs.dev/fiwdev/nereus-api:${{ github.sha }}
LOADGEN_IMAGE: git.fiwlabs.dev/fiwdev/nereus-loadgen:${{ github.sha }}
WEB_IMAGE: git.fiwlabs.dev/fiwdev/nereus-web:${{ github.sha }}
DOCKER_CONFIG: ${{ github.workspace }}/.ci/docker
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Log in to registry
env:
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
run: |
install -d -m 0700 "$DOCKER_CONFIG"
printf '%s' "$REGISTRY_PASSWORD" | \
docker login git.fiwlabs.dev --username "$REGISTRY_USERNAME" --password-stdin
- name: Build and push images
run: |
docker build -f build/api.Dockerfile \
--build-arg "APP_VERSION=${{ github.sha }}" \
-t "$API_IMAGE" .
docker build -f build/loadgen.Dockerfile -t "$LOADGEN_IMAGE" .
docker build -f build/web.Dockerfile -t "$WEB_IMAGE" .
for image in "$API_IMAGE" "$LOADGEN_IMAGE" "$WEB_IMAGE"
do
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:0.74.0 image --severity HIGH,CRITICAL \
--ignore-unfixed --exit-code 1 "$image"
done
docker push "$API_IMAGE"
docker push "$LOADGEN_IMAGE"
docker push "$WEB_IMAGE"
- name: Remove registry credentials
if: always()
run: rm -rf .ci
deploy:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: publish
runs-on: docker
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Prepare cluster access
env:
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
run: |
install -d -m 0700 .ci
printf '%s' "$KUBECONFIG_B64" | base64 -d >.ci/kubeconfig
chmod 0600 .ci/kubeconfig
printf '%s' "$REGISTRY_PASSWORD" | \
docker --config "$PWD/.ci/docker" login git.fiwlabs.dev \
--username "$REGISTRY_USERNAME" --password-stdin
- name: Apply and verify rollout
run: |
kube() {
docker run --rm -i --network host \
-v "$PWD:/work" -w /work \
registry.k8s.io/kubectl:v1.33.4 \
--kubeconfig=/work/.ci/kubeconfig "$@"
}
kube create namespace nereus --dry-run=client -o yaml | kube apply -f -
kube create secret generic nereus-registry \
--namespace nereus \
--type kubernetes.io/dockerconfigjson \
--from-file=.dockerconfigjson=/work/.ci/docker/config.json \
--dry-run=client -o yaml | kube apply -f -
kube apply -k deploy/secrets
kube wait sealedsecret.bitnami.com/nereus-db --namespace nereus \
--for=condition=Synced --timeout=2m
kube get secret nereus-db --namespace nereus >/dev/null
kube apply -k deploy/observability
# Set the built tag before applying. Applying the overlay first would
# roll out its pinned 0.1.0 tag and then roll out a second time on the
# patch, running the pre-promotion analysis against the wrong image.
install -d .ci/release
cat >.ci/release/kustomization.yaml <<'EOF'
resources:
- ../../deploy/overlays/prod
images:
- name: git.fiwlabs.dev/fiwdev/nereus-api
newTag: ${{ github.sha }}
- name: git.fiwlabs.dev/fiwdev/nereus-loadgen
newTag: ${{ github.sha }}
EOF
kube apply -k .ci/release
kube rollout status deployment/nereus-loadgen --namespace nereus --timeout=5m
kube rollout status deployment/nereus-loadgen-preview --namespace nereus --timeout=5m
kube wait rollout.argoproj.io/nereus-api --namespace nereus \
--for=jsonpath='{.status.phase}'=Healthy --timeout=10m
kube get rollout.argoproj.io/nereus-api --namespace nereus
- name: Remove cluster credentials
if: always()
run: rm -rf .ci
mirror:
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && vars.MIRROR_ENABLED == 'true'
needs: deploy
runs-on: docker
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Push main to GitHub
env:
GITHUB_MIRROR_SSH_KEY: ${{ secrets.GITHUB_MIRROR_SSH_KEY }}
run: |
test -n "$GITHUB_MIRROR_SSH_KEY"
install -d -m 0700 .ci/mirror
printf '%s\n' "$GITHUB_MIRROR_SSH_KEY" >.ci/mirror/id_ed25519
chmod 0600 .ci/mirror/id_ed25519
cat >.ci/mirror/known_hosts <<'EOF'
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
EOF
GIT_SSH_COMMAND="ssh -i $PWD/.ci/mirror/id_ed25519 -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$PWD/.ci/mirror/known_hosts" \
git push git@github.com:Fi3w0/Nereus.git HEAD:main
- name: Remove GitHub credentials
if: always()
run: rm -rf .ci