diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4956b9a..2072dc6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,33 +16,6 @@ jobs: # the workflow DRY. The composite action performs checkout, cache restore and # toolchain setup. - verify-generated-code: - # no need to depend on a separate setup job; the composite action runs in - # this job and restores caches/toolchain here. - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Setup Rust, checkout and restore caches - uses: ./.github/actions/setup-rust - - - name: generate entities from migration files - run: | - cd apps/cli - cargo run -- db:migrate_and_generate --output-path ../../public/database/src/generated/entities - - name: Check for uncommitted changes in /generated/ - run: | - if [[ -n $(git status --porcelain | grep '^ M .*\/generated\/') ]]; then - echo "Generated code is not up to date. Please run the code generation locally and commit the changes." - git status --porcelain | grep '^ M .*\/generated\/' - exit 1 - else - echo "Generated code is up to date." - fi - test: needs: frontend-build runs-on: ubuntu-latest @@ -94,7 +67,6 @@ jobs: - name: Check code formatting run: cargo fmt --all -- --check - test-frontend: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml new file mode 100644 index 0000000..207b978 --- /dev/null +++ b/.github/workflows/verify.yml @@ -0,0 +1,112 @@ +# this workflow verifies the generated code is up to date and valid + +name: Verify +on: + pull_request: + branches: + - master + push: + branches: + - master + + +jobs: + # setup is now handled by a composite action used by downstream jobs to keep + # the workflow DRY. The composite action performs checkout, cache restore and + # toolchain setup. + + verify-generated-code: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup Rust, checkout and restore caches + uses: ./.github/actions/setup-rust + + - name: generate entities from migration files + run: | + cd apps/cli + cargo run -- db:migrate_and_generate --output-path ../../public/database/src/generated/entities + - name: Check for uncommitted changes in /generated/ + run: | + if [[ -n $(git status --porcelain | grep '^ M .*\/generated\/') ]]; then + echo "Generated code is not up to date. Please run the code generation locally and commit the changes." + git status --porcelain | grep '^ M .*\/generated\/' + exit 1 + else + echo "Generated code is up to date." + fi + + verify-openapi-spec: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Check whether apps/api/src/routes changed + id: check_changes + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + BASE_SHA=${{ github.event.pull_request.base.sha }} + HEAD_SHA=${{ github.event.pull_request.head.sha }} + else + BASE_SHA=${{ github.event.before }} + HEAD_SHA=${{ github.sha }} + fi + + # Provide safe fallbacks when GitHub context values are empty (e.g. when using act) + if [ -z "$HEAD_SHA" ]; then + HEAD_SHA=$(git rev-parse --verify HEAD 2>/dev/null || echo "") + fi + + if [ -z "$BASE_SHA" ]; then + # Try the parent of HEAD, fall back to HEAD if unavailable + PREV=$(git rev-parse --verify "${HEAD_SHA}^" 2>/dev/null || true) + if [ -n "$PREV" ]; then + BASE_SHA=$PREV + else + BASE_SHA=$HEAD_SHA + fi + fi + + echo "Comparing $BASE_SHA..$HEAD_SHA" + CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" || true) + echo "$CHANGED_FILES" + + echo "$CHANGED_FILES" | grep -E '^(apps/api/src/routes/?|apps/api/swagger.json)' >/dev/null 2>&1 && echo "changed=true" >> $GITHUB_OUTPUT || echo "changed=false" >> $GITHUB_OUTPUT + + - name: Setup Rust, checkout and restore caches + if: steps.check_changes.outputs.changed == 'true' + uses: ./.github/actions/setup-rust + + - name: Generate dummy frontend build (to satisfy dependencies) + if: steps.check_changes.outputs.changed == 'true' + run: | + mkdir -p apps/frontend/build/client + echo "dummy file" > apps/frontend/build/client/dummy.txt + + - name: Generate OpenAPI spec + if: steps.check_changes.outputs.changed == 'true' + run: | + cd apps/api + cargo run -- generate:openapi --output-path ./swagger.json + + - name: Check for uncommitted changes in swagger.json + if: steps.check_changes.outputs.changed == 'true' + run: | + if [[ -n $(git status --porcelain | grep '^ M apps/api/swagger.json') ]]; then + echo "OpenAPI spec is not up to date. Please run the OpenAPI generation locally and commit the changes." + git status --porcelain | grep '^ M apps/api/swagger.json' + exit 1 + else + echo "OpenAPI spec is up to date." + fi + + - name: Skip OpenAPI generation (no relevant changes) + if: steps.check_changes.outputs.changed == 'false' + run: echo "No changes in apps/api/src/routes/ nor apps/api/swagger.json, skipping OpenAPI generation verification."