Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f817725
chore(ci): add concurrency groups to workflows
mregni Jul 24, 2026
dc8cff8
chore(ci): trim redundant pr triggers and fold version job into test job
mregni Jul 24, 2026
231ea35
chore(ci): skip security scans for docs-only changes
mregni Jul 24, 2026
ec41d32
fix(ci): remove shell interpolation of secrets and outputs in workflows
mregni Jul 24, 2026
d4e1a32
chore(ci): tighten dependency scan scope and failure behavior
mregni Jul 24, 2026
4cacecd
refactor(ci): move image-heavy scans off the PR path
mregni Jul 24, 2026
65c02bd
refactor(ci): drive nightly ZAP scan from OpenAPI spec
mregni Jul 24, 2026
cf77e96
chore(ci): add nightly Docker Scout and informational dependency audit
mregni Jul 24, 2026
95bc76b
chore(ci): enable CodeQL security-extended suite
mregni Jul 24, 2026
628f2d5
fix(ci): repair nightly image push and Azure image pull
mregni Jul 24, 2026
173d084
fix(ci): drop invalid log retention on ephemeral scan workspace
mregni Jul 24, 2026
5cec9a7
fix(ci): fail health wait fast and keep Azure evidence on failure
mregni Jul 24, 2026
4d91915
chore(ci): drop ZAP SARIF upload the scan never produces
mregni Aug 1, 2026
4c16416
chore(ci): tag security-scan Azure resources with app name
mregni Aug 1, 2026
4e510bc
fix(ci): run scan database as sidecar next to the app
mregni Aug 1, 2026
9ffa5af
fix(ci): remove shell interpolation of secrets and outputs in publish…
mregni Aug 6, 2026
c6fb528
chore(ci): pin trivy action and gate publish on concurrency and code …
mregni Aug 6, 2026
c3d14e3
ci: run pr checks on every pull request so they can be required
mregni Aug 6, 2026
077e5f8
fix(ci): key publish concurrency on event so manual releases are not …
mregni Aug 6, 2026
2083441
chore(ci): drop unused registry variables from the ci workflow
mregni Aug 6, 2026
898978d
chore: retrigger ci after github actions outage
mregni Aug 6, 2026
28d6a8f
fix(ci): stop the backend scan failing on the frontend esproj
mregni Aug 6, 2026
79a0279
fix(ci): pin third-party actions to commit shas
mregni Aug 6, 2026
7ebcf1f
fix(ci): pin first-party actions to commit shas as well
mregni Aug 6, 2026
2b6000e
fix(ci): pin the sonarscanner version
mregni Aug 7, 2026
78f13f3
chore(ci): treat the sonar project key and organization as configuration
mregni Aug 7, 2026
a1b9fcd
fix(ci): let sonarcloud report its own quality gate
mregni Aug 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: "BoardGameTracker CodeQL Config"

queries:
- uses: security-extended

query-filters:
- exclude:
id: cs/log-forging
Expand Down
86 changes: 32 additions & 54 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,36 @@ on:
pull_request:
branches:
- master
paths-ignore:
- "docs/**"
- ".github/workflows/docs.yml"

env:
REGISTRY: ${{ vars.DOCKER_REGISTRY || 'docker.io' }}
IMAGE_NAME: ${{ vars.DOCKER_IMAGE_NAME || 'uping/boardgametracker' }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
version:
name: Calculate Version
test-and-analyze:
name: Test and SonarCloud Analysis
runs-on: ubuntu-latest
env:
SONAR_SCANNER_VERSION: "11.2.1"
SONAR_PROJECT_KEY: mregni_BoardGameTracker
SONAR_ORGANIZATION: uping
permissions:
contents: read
outputs:
version: ${{ steps.versioning.outputs.version }}
pull-requests: write
checks: write
steps:
- name: Harden runner
uses: step-security/harden-runner@v2
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
fetch-depth: 0

- name: Git Semantic Version
uses: PaulHatch/semantic-version@v6.0.3
uses: PaulHatch/semantic-version@502226b17e3e242e4befd0a45690fcbb27dd1373 # v6.0.3
id: versioning
with:
enable_prerelease_mode: true
Expand All @@ -41,68 +42,48 @@ jobs:
version_format: "${major}.${minor}.${patch}-beta"
debug: true

test-and-analyze:
name: Test and SonarCloud Analysis
runs-on: ubuntu-latest
needs: [version]
permissions:
contents: read
pull-requests: write
checks: write
steps:
- name: Harden runner
uses: step-security/harden-runner@v2
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Set up JDK 17
uses: actions/setup-java@v5
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5
with:
java-version: 17
distribution: 'zulu'

- name: Setup dotnet v8
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5
with:
dotnet-version: "8.x"

- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
with:
package_json_file: boardgametracker.client/package.json

- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: "20.x"
cache: 'pnpm'
cache-dependency-path: boardgametracker.client/pnpm-lock.yaml

- name: Cache SonarCloud packages
uses: actions/cache@v5
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar

- name: Cache SonarCloud scanner
id: cache-sonar-scanner
uses: actions/cache@v5
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
with:
path: ./.sonar/scanner
key: ${{ runner.os }}-sonar-scanner
restore-keys: ${{ runner.os }}-sonar-scanner
key: ${{ runner.os }}-sonar-scanner-${{ env.SONAR_SCANNER_VERSION }}

- name: Install SonarCloud scanner
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
run: |
mkdir -p ./.sonar/scanner
dotnet tool update dotnet-sonarscanner --tool-path ./.sonar/scanner
dotnet tool update dotnet-sonarscanner --tool-path ./.sonar/scanner --version "$SONAR_SCANNER_VERSION"

- name: Install .NET dependencies
run: dotnet restore ./BoardGameTracker.sln
Expand All @@ -111,23 +92,20 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_PROJECT_KEY: ${{ secrets.SONAR_PROJECT_KEY }}
SONAR_ORGANIZATION: ${{ secrets.SONAR_ORGANIZATION }}
VERSION: ${{ steps.versioning.outputs.version }}
run: |
./.sonar/scanner/dotnet-sonarscanner begin \
/k:"${{ env.SONAR_PROJECT_KEY }}" \
/o:"${{ env.SONAR_ORGANIZATION }}" \
/k:"$SONAR_PROJECT_KEY" \
/o:"$SONAR_ORGANIZATION" \
/d:sonar.host.url="https://sonarcloud.io" \
/d:sonar.token="${{ env.SONAR_TOKEN }}" \
/v:"${{ needs.version.outputs.version }}" \
/d:sonar.token="$SONAR_TOKEN" \
/v:"$VERSION" \
/d:sonar.cs.opencover.reportsPaths="TestResults/**/coverage.opencover.xml" \
/d:sonar.cs.vstest.reportsPaths="TestResults/*.trx" \
/d:sonar.javascript.lcov.reportPaths="coverage/lcov.info" \
/d:sonar.testExecutionReportPaths="boardgametracker.client/coverage/sonar-report.xml" \
/d:sonar.exclusions="**/node_modules/**,**/dist/**,**/build/**,**/coverage/**,**/TestResults/**,**/obj/**,**/bin/**,**/Migrations/**,**/routeTree.gen.ts" \
/d:sonar.coverage.exclusions="**/BoardGameTracker.Host/**/*.cs,**/BoardGameTracker.Core/Datastore/**/*.cs,**/ViewModels/**/*.cs,**/Entities/**/*.cs,**/routeTree.gen.ts,**/tailwind.config.js,**/node_modules/**" \
/d:sonar.qualitygate.wait=true \
/d:sonar.qualitygate.timeout=300 \
/d:sonar.issue.ignore.multicriteria=e1 \
/d:sonar.issue.ignore.multicriteria.e1.ruleKey=githubactions:S7637 \
/d:sonar.issue.ignore.multicriteria.e1.resourceKey="**/.github/**"
Expand Down Expand Up @@ -175,7 +153,7 @@ jobs:
sed -i "s|path=\"src/|path=\"$(pwd)/src/|g" coverage/sonar-report.xml

- name: Publish .NET test results
uses: EnricoMi/publish-unit-test-result-action@v2
uses: EnricoMi/publish-unit-test-result-action@d0a4676d0e0b938bc201470d88276b7c74c712b3 # v2
if: always()
with:
files: TestResults/**/*.trx
Expand All @@ -186,11 +164,11 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ./.sonar/scanner/dotnet-sonarscanner end /d:sonar.token="${{ env.SONAR_TOKEN }}"
run: ./.sonar/scanner/dotnet-sonarscanner end /d:sonar.token="$SONAR_TOKEN"
if: env.SONAR_TOKEN != ''

- name: Upload test results
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: test-results
path: |
Expand All @@ -200,7 +178,7 @@ jobs:
if: success() || failure()

- name: Code Coverage Report
uses: danielpalme/ReportGenerator-GitHub-Action@v5.5.10
uses: danielpalme/ReportGenerator-GitHub-Action@049f7ec958c672fd31d5cc1cb01622dc8d2e23ab # v5.5.10
with:
reports: "TestResults/**/coverage.opencover.xml;boardgametracker.client/coverage/lcov.info"
targetdir: "coveragereport"
Expand All @@ -213,7 +191,7 @@ jobs:
run: cat coveragereport/SummaryGithub.md >> $GITHUB_STEP_SUMMARY

- name: Add Coverage PR Comment
uses: marocchino/sticky-pull-request-comment@v3
uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3
with:
recreate: true
path: coveragereport/SummaryGithub.md
12 changes: 8 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ on:
schedule:
- cron: '15 7 * * 4'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze (${{ matrix.language }})
Expand All @@ -31,21 +35,21 @@ jobs:

steps:
- name: Harden runner
uses: step-security/harden-runner@v2
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2
with:
egress-policy: audit

- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Initialize CodeQL
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
config-file: ./.github/codeql/codeql-config.yml

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4
with:
category: "/language:${{ matrix.language }}"
16 changes: 8 additions & 8 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,28 @@ jobs:
working-directory: docs
steps:
- name: Harden runner
uses: step-security/harden-runner@v2
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
with:
package_json_file: docs/package.json

- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: 22
cache: pnpm
cache-dependency-path: docs/pnpm-lock.yaml

- name: Setup Pages
id: pages
uses: actions/configure-pages@v6
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6

- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
Expand All @@ -56,7 +56,7 @@ jobs:
VITE_BASE_PATH: ${{ steps.pages.outputs.base_path }}/

- name: Upload artifact
uses: actions/upload-pages-artifact@v4
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4
with:
path: docs/dist

Expand All @@ -71,10 +71,10 @@ jobs:
needs: build
steps:
- name: Harden runner
uses: step-security/harden-runner@v2
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2
with:
egress-policy: audit

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5
23 changes: 13 additions & 10 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ name: PR Quality
on:
pull_request:
branches: [master]
types: [opened, synchronize, reopened, edited, labeled, unlabeled]
types: [opened, synchronize, reopened, edited]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
labeler:
Expand All @@ -14,31 +18,30 @@ jobs:
pull-requests: write
steps:
- name: Harden runner
uses: step-security/harden-runner@v2
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Apply file-based labels
uses: actions/labeler@v6
uses: actions/labeler@b8dd2d9be0f68b860e7dae5dae7d772984eacd6d # v6
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/labeler.yml

- name: Remove old size labels
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
PR_NUMBER=${{ github.event.pull_request.number }}
REPO=${{ github.repository }}
for LABEL in "size/XS" "size/S" "size/M" "size/L" "size/XL"; do
gh api "repos/$REPO/issues/$PR_NUMBER/labels/$LABEL" -X DELETE 2>/dev/null || true
gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/labels/$LABEL" -X DELETE 2>/dev/null || true
done

- name: Label PR by size
uses: codelytv/pr-size-labeler@v1
uses: codelytv/pr-size-labeler@095a41fca88b8764fd9e008ad269bcdb82bb38b9 # v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
xs_label: "size/XS"
Expand All @@ -61,12 +64,12 @@ jobs:
permissions: {}
steps:
- name: Harden runner
uses: step-security/harden-runner@v2
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2
with:
egress-policy: audit

- name: Validate PR title
uses: amannn/action-semantic-pull-request@v6
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand Down
Loading
Loading