# Guidad Felsökning — CI på egna runners i klustret. # # Samma syntax som GitHub Actions men körs av Gitea Actions-runners på # vår egen EKS. Inget externt beroende: koden, bygget och registret # ligger i vår AWS-miljö. # # .github/workflows/ tillhör Semantika och rörs inte. name: Guidad Felsökning on: push: paths: ['felsokning/**', '.gitea/workflows/felsokning.yml'] pull_request: paths: ['felsokning/**'] workflow_dispatch: inputs: bildtagg: description: 'Bildtagg att driftsätta (commit-SHA från publiceringen)' required: true type: string jobs: test-och-bygg: runs-on: felsokning defaults: run: working-directory: felsokning/app steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 22 } - run: npm ci --no-audit --no-fund - run: npx vitest run - run: npm run typkontroll - run: npx eslint src/felsokning src/pages/felsokning src/test --ext .ts,.tsx - run: npm run build tjanster: runs-on: felsokning steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 22 } - run: npm install --no-audit --no-fund working-directory: felsokning/services/plattform - run: npx eslint . --ext .mjs working-directory: felsokning/services # Hela flödet mot riktig Postgres: organisationer, roller, # append-only-triggern, isolering, delning, bilagor. - run: sudo apt-get update && sudo apt-get install -y postgresql - run: sudo bash integrationstest.sh working-directory: felsokning/services/plattform - run: npx swagger-cli validate felsokning/services/plattform/openapi.yaml working-directory: . terraform: runs-on: felsokning defaults: run: working-directory: felsokning/infra/terraform steps: - uses: actions/checkout@v4 - uses: hashicorp/setup-terraform@v3 with: { terraform_version: 1.9.8 } - run: terraform fmt -check -recursive - run: terraform init -backend=false -input=false - run: terraform validate # Leverantörskedjan. 53 direkta klientberoenden utan SBOM eller # skanning var ett fynd i revisionen (QUALITET m-5): de flesta # OEM-baslinjer för leverantörssäkerhet kräver båda. leverantorskedja: runs-on: felsokning steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 22 } - run: npm ci --no-audit --no-fund working-directory: felsokning/app # Kända sårbarheter stoppar bygget från "high" och uppåt. Lägre # nivåer rapporteras men fäller inte — annars slutar folk läsa. - run: npm audit --audit-level=high working-directory: felsokning/app - run: npm audit working-directory: felsokning/app continue-on-error: true # SBOM i CycloneDX, arkiverad per bygge. Utan den går det inte att # svara på "påverkas vi av den här sårbarheten" utan att gissa. - run: npx --yes @cyclonedx/cyclonedx-npm@latest --output-file sbom-klient.json working-directory: felsokning/app - run: npm install --no-audit --no-fund && npx --yes @cyclonedx/cyclonedx-npm@latest --output-file ../sbom-plattform.json working-directory: felsokning/services/plattform - uses: actions/upload-artifact@v4 with: name: sbom-${{ gitea.sha }} path: | felsokning/app/sbom-klient.json felsokning/services/sbom-plattform.json retention-days: 400 # M-5: en säkerhetskopia som aldrig återställts är en förhoppning. # Larmet visar att backup sker, inte att den går att återställa. aterstallning: runs-on: felsokning steps: - uses: actions/checkout@v4 - run: sudo apt-get update && sudo apt-get install -y postgresql - run: sudo bash aterstallningstest.sh working-directory: felsokning/services/plattform # Bygger och publicerar till vårt eget ECR. Bara på main och bara när # kontrollerna ovan gått igenom. publicera: needs: [test-och-bygg, tjanster, terraform, leverantorskedja, aterstallning] if: gitea.ref == 'refs/heads/main' runs-on: felsokning permissions: id-token: write steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ vars.BYGG_ROLL_ARN }} aws-region: ${{ vars.AWS_REGION }} - uses: aws-actions/amazon-ecr-login@v2 id: ecr - name: Bygg och publicera env: REGISTER: ${{ steps.ecr.outputs.registry }} TAGG: ${{ gitea.sha }} run: | # Klientens API-adress bakas in vid bygget (Vite), så bilden är # miljöbunden. docker build -t "$REGISTER/guidad-felsokning-web:$TAGG" \ --build-arg VITE_PLATTFORM_URL="https://${{ vars.DOMAN }}" \ --build-arg VITE_AI_ORKESTER_URL="https://${{ vars.DOMAN }}" \ felsokning/app # Byggkontexten är felsokning/services så båda tjänsterna når # den delade observationsmodulen utan att den dupliceras. docker build -t "$REGISTER/guidad-felsokning-plattform:$TAGG" \ -f felsokning/services/plattform/Dockerfile felsokning/services docker build -t "$REGISTER/guidad-felsokning-ai-orkester:$TAGG" \ -f felsokning/services/ai-orkester/Dockerfile felsokning/services for bild in web plattform ai-orkester; do docker push "$REGISTER/guidad-felsokning-$bild:$TAGG" done # Driftsättning är ett eget, manuellt steg: en bild i registret är inte # samma sak som en bild som kör. Rollback = kör igen med tidigare tagg. driftsatt: if: gitea.event_name == 'workflow_dispatch' runs-on: felsokning environment: produktion permissions: id-token: write defaults: run: working-directory: felsokning/infra/terraform steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ vars.DRIFT_ROLL_ARN }} aws-region: ${{ vars.AWS_REGION }} - run: aws eks update-kubeconfig --name ${{ vars.KLUSTER }} - uses: hashicorp/setup-terraform@v3 with: { terraform_version: 1.9.8 } - run: terraform init -input=false - run: terraform apply -input=false -auto-approve -var bildtagg=${{ inputs.bildtagg }} - run: terraform output karta