diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index b1d67b0..1143472 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -93,8 +93,8 @@ jobs: run: go build ./... working-directory: backend - go-vet: - name: Go vet + go-vet-dev: + name: Go vet (dev) needs: [go-build] runs-on: ubuntu-latest defaults: @@ -114,7 +114,7 @@ jobs: path: | ~/go/pkg/mod ~/.cache/go-build - key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-vet + key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-vet-dev restore-keys: | ${{ runner.os }}-go- @@ -127,6 +127,36 @@ jobs: run: go vet -tags "test,dev" ./... working-directory: backend + go-vet-prod: + name: Go vet (prod) + needs: [go-build] + runs-on: ubuntu-latest + defaults: + run: + shell: sh + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.26" + cache: false + + - name: Cache Go modules + uses: actions/cache@v4 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-vet-prod + restore-keys: | + ${{ runner.os }}-go- + + - name: Fix node toolcache path for Post-step cleanup + run: | + mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin + ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node + - name: Vet (prod tags) run: go vet -tags "test,!dev" ./... working-directory: backend @@ -167,8 +197,8 @@ jobs: golangci-lint run ./... working-directory: backend - go-staticcheck: - name: Staticcheck + go-staticcheck-dev: + name: Staticcheck (dev) needs: [go-build] runs-on: ubuntu-latest defaults: @@ -188,7 +218,7 @@ jobs: path: | ~/go/pkg/mod ~/.cache/go-build - key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-staticcheck + key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-staticcheck-dev restore-keys: | ${{ runner.os }}-go- @@ -203,13 +233,8 @@ jobs: staticcheck -tags "test,dev" ./... working-directory: backend - - name: Staticcheck (prod tags) - run: | - staticcheck -tags "test,!dev" ./... - working-directory: backend - - go-gosec: - name: Security scan (gosec) + go-staticcheck-prod: + name: Staticcheck (prod) needs: [go-build] runs-on: ubuntu-latest defaults: @@ -229,7 +254,43 @@ jobs: path: | ~/go/pkg/mod ~/.cache/go-build - key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-gosec + key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-staticcheck-prod + restore-keys: | + ${{ runner.os }}-go- + + - name: Fix node toolcache path for Post-step cleanup + run: | + mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin + ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node + + - name: Staticcheck (prod tags) + run: | + go install honnef.co/go/tools/cmd/staticcheck@latest + staticcheck -tags "test,!dev" ./... + working-directory: backend + + go-gosec-dev: + name: Security scan (dev) + needs: [go-build] + runs-on: ubuntu-latest + defaults: + run: + shell: sh + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.26" + cache: false + + - name: Cache Go modules + uses: actions/cache@v4 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-gosec-dev restore-keys: | ${{ runner.os }}-go- @@ -244,8 +305,39 @@ jobs: gosec -severity medium -tags "test,dev" ./... working-directory: backend + go-gosec-prod: + name: Security scan (prod) + needs: [go-build] + runs-on: ubuntu-latest + defaults: + run: + shell: sh + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.26" + cache: false + + - name: Cache Go modules + uses: actions/cache@v4 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: ${{ runner.os }}-go-${{ hashFiles('backend/go.sum') }}-gosec-prod + restore-keys: | + ${{ runner.os }}-go- + + - name: Fix node toolcache path for Post-step cleanup + run: | + mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin + ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node + - name: gosec (prod tags) run: | + go install github.com/securego/gosec/v2/cmd/gosec@latest gosec -severity medium -tags "test,!dev" ./... working-directory: backend @@ -290,7 +382,7 @@ jobs: test: name: Tests (${{ matrix.label }}) - needs: [go-vet, go-lint, go-staticcheck, go-gosec, go-mod-tidy, vulns] + needs: [go-vet-dev, go-vet-prod, go-lint, go-staticcheck-dev, go-staticcheck-prod, go-gosec-dev, go-gosec-prod, go-mod-tidy, vulns] runs-on: ubuntu-latest defaults: run: @@ -379,7 +471,7 @@ jobs: race: name: Race (${{ matrix.label }}) - needs: [go-vet, go-lint, go-staticcheck, go-gosec, go-mod-tidy, vulns] + needs: [go-vet-dev, go-vet-prod, go-lint, go-staticcheck-dev, go-staticcheck-prod, go-gosec-dev, go-gosec-prod, go-mod-tidy, vulns] runs-on: ubuntu-latest defaults: run: @@ -573,6 +665,54 @@ jobs: console.log('All overrides appear necessary'); " + frontend-deps-major: + name: Frontend major deps (warn only) + needs: [frontend-deps] + runs-on: ubuntu-latest + defaults: + run: + shell: sh + steps: + - uses: actions/checkout@v4 + + - name: Fix node toolcache path for Post-step cleanup + run: | + mkdir -p /opt/hostedtoolcache/node/22.23.1/x64/bin + ln -sf /usr/local/bin/node /opt/hostedtoolcache/node/22.23.1/x64/bin/node + + - name: Restore npm dependencies + uses: actions/cache@v4 + with: + path: | + ~/.npm + frontend/node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('frontend/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-npm- + + - name: Install dependencies + run: cd frontend && npm ci + + - name: Check for major updates (non-blocking) + run: | + cd frontend && npm outdated --json 2>&1 | node -e " + const chunks = []; + process.stdin.on('data', c => chunks.push(c)); + process.stdin.on('end', () => { + const raw = Buffer.concat(chunks).toString().trim(); + if (!raw) { console.log('No dependencies to check'); process.exit(0); } + const data = JSON.parse(raw); + const major = Object.entries(data).filter(([_, v]) => v.wanted !== v.latest); + if (major.length) { + console.log('Major (out-of-range) updates available — review carefully:'); + major.forEach(([k, v]) => console.log(' ' + k + ': ' + v.current + ' (wanted: ' + v.wanted + ') -> latest: ' + v.latest)); + } else { + console.log('All dependencies within semver range, no major updates'); + } + process.exit(0); + }); + " + knip: name: Knip needs: [frontend-deps]