ci(test): add Swagger endpoint tests workflow #193
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: License Report Workflow | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref_name || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| files-changed: | |
| name: detect what files changed | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 3 | |
| outputs: | |
| licenses-frontend: ${{ steps.changes.outputs.licenses-frontend }} | |
| licenses-backend: ${{ steps.changes.outputs.licenses-backend }} | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout repository | |
| uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 | |
| - name: Check for file changes | |
| uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 | |
| id: changes | |
| with: | |
| filters: .github/config/.files.yaml | |
| generate-frontend-license-report: | |
| if: needs.files-changed.outputs.licenses-frontend == 'true' | |
| name: Generate Frontend License Report | |
| needs: files-changed | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| repository-projects: write # Required for enabling automerge | |
| steps: | |
| - name: Harden Runner | |
| uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout PR head (default) | |
| uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup GitHub App Bot | |
| if: (github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false)) && github.actor != 'dependabot[bot]' | |
| id: setup-bot | |
| uses: ./.github/actions/setup-bot | |
| with: | |
| app-id: ${{ secrets.GH_APP_ID }} | |
| private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| - name: Checkout BASE branch (safe script) | |
| if: github.event_name == 'pull_request' | |
| uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 | |
| with: | |
| ref: ${{ github.event.pull_request.base.sha }} | |
| path: base | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Set up Node.js | |
| uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 | |
| with: | |
| node-version: "22" | |
| cache: "npm" | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install frontend dependencies | |
| working-directory: frontend | |
| env: | |
| NPM_CONFIG_IGNORE_SCRIPTS: "true" | |
| run: npm ci --ignore-scripts --audit=false --fund=false | |
| - name: Generate frontend license report (internal PR) | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false | |
| working-directory: frontend | |
| env: | |
| PR_IS_FORK: "false" | |
| run: npm run generate-licenses | |
| - name: Generate frontend license report (fork PRs, pinned) | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true | |
| env: | |
| NPM_CONFIG_IGNORE_SCRIPTS: "true" | |
| working-directory: frontend | |
| run: | | |
| mkdir -p src/assets | |
| npx --yes license-report --only=prod --output=json > src/assets/3rdPartyLicenses.json | |
| - name: Postprocess with project script (BASE version) | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true | |
| env: | |
| PR_IS_FORK: "true" | |
| run: | | |
| node base/frontend/scripts/generate-licenses.js \ | |
| --input frontend/src/assets/3rdPartyLicenses.json | |
| - name: Copy postprocessed artifacts back (fork PRs) | |
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true | |
| run: | | |
| mkdir -p frontend/src/assets | |
| if [ -f "base/frontend/src/assets/3rdPartyLicenses.json" ]; then | |
| cp base/frontend/src/assets/3rdPartyLicenses.json frontend/src/assets/3rdPartyLicenses.json | |
| fi | |
| if [ -f "base/frontend/src/assets/license-warnings.json" ]; then | |
| cp base/frontend/src/assets/license-warnings.json frontend/src/assets/license-warnings.json | |
| fi | |
| - name: Check for license warnings | |
| run: | | |
| if [ -f "frontend/src/assets/license-warnings.json" ]; then | |
| echo "LICENSE_WARNINGS_EXIST=true" >> $GITHUB_ENV | |
| else | |
| echo "LICENSE_WARNINGS_EXIST=false" >> $GITHUB_ENV | |
| fi | |
| # PR Event: Check licenses and comment on PR | |
| - name: Delete previous license check comments | |
| if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) && github.actor != 'dependabot[bot]' | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| with: | |
| github-token: ${{ steps.setup-bot.outputs.token }} | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const prNumber = context.issue.number; | |
| // Get all comments on the PR | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner, | |
| repo, | |
| issue_number: prNumber, | |
| per_page: 100 | |
| }); | |
| // Filter for license check comments | |
| const licenseComments = comments.filter(comment => | |
| comment.body.includes('## ✅ Frontend License Check Passed') || | |
| comment.body.includes('## ❌ Frontend License Check Failed') | |
| ); | |
| // Delete old license check comments | |
| for (const comment of licenseComments) { | |
| console.log(`Deleting old license check comment: ${comment.id}`); | |
| await github.rest.issues.deleteComment({ | |
| owner, | |
| repo, | |
| comment_id: comment.id | |
| }); | |
| } | |
| - name: Summarize results (fork PRs) | |
| if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true) || github.actor == 'dependabot[bot]' | |
| run: | | |
| { | |
| echo "## Frontend License Check" | |
| echo "" | |
| if [ "${LICENSE_WARNINGS_EXIST}" = "true" ]; then | |
| echo "❌ **Failed** – incompatible or unknown licenses found." | |
| if [ -f "frontend/src/assets/license-warnings.json" ]; then | |
| echo "" | |
| echo "### Warnings" | |
| jq -r '.warnings[] | "- \(.message)"' frontend/src/assets/license-warnings.json || true | |
| fi | |
| else | |
| echo "✅ **Passed** – no license warnings detected." | |
| fi | |
| echo "" | |
| echo "_Note: This is a fork PR. PR comments are disabled; use this summary._" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Comment on PR - License Check Results | |
| if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) && github.actor != 'dependabot[bot]' | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| with: | |
| github-token: ${{ steps.setup-bot.outputs.token }} | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const prNumber = context.issue.number; | |
| const hasWarnings = process.env.LICENSE_WARNINGS_EXIST === 'true'; | |
| let commentBody; | |
| if (hasWarnings) { | |
| // Read warnings file to get specific issues | |
| const fs = require('fs'); | |
| let warningDetails = ''; | |
| try { | |
| const warnings = JSON.parse(fs.readFileSync('frontend/src/assets/license-warnings.json', 'utf8')); | |
| warningDetails = warnings.warnings.map(w => `- ${w.message}`).join('\n'); | |
| } catch (e) { | |
| warningDetails = 'Unable to read warning details'; | |
| } | |
| commentBody = `## ❌ Frontend License Check Failed | |
| The frontend license check has detected compatibility warnings that require review: | |
| ${warningDetails} | |
| **Action Required:** Please review these licenses to ensure they are acceptable for your use case before merging. | |
| _This check will fail the PR until license issues are resolved._`; | |
| } else { | |
| commentBody = `## ✅ Frontend License Check Passed | |
| All frontend licenses have been validated and no compatibility warnings were detected. | |
| The frontend license report has been updated successfully.`; | |
| } | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number: prNumber, | |
| body: commentBody | |
| }); | |
| - name: Fail workflow if license warnings exist (PR only) | |
| if: github.event_name == 'pull_request' && env.LICENSE_WARNINGS_EXIST == 'true' | |
| run: | | |
| echo "❌ License warnings detected. Failing the workflow." | |
| exit 1 | |
| # Push Event: Commit license files and create PR | |
| - name: Commit changes (Push only) | |
| if: github.event_name == 'push' | |
| run: | | |
| git add frontend/src/assets/3rdPartyLicenses.json | |
| # Note: Do NOT commit license-warnings.json - it's only for PR review | |
| git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV | |
| - name: Prepare PR body (Push only) | |
| if: github.event_name == 'push' | |
| run: | | |
| PR_BODY="Auto-generated by ${{ steps.setup-bot.outputs.app-slug }}[bot] | |
| This PR updates the frontend license report based on changes to package.json dependencies." | |
| if [ "${{ env.LICENSE_WARNINGS_EXIST }}" = "true" ]; then | |
| PR_BODY="$PR_BODY | |
| ## ⚠️ License Compatibility Warnings | |
| The following licenses may require review for corporate compatibility: | |
| $(cat frontend/src/assets/license-warnings.json | jq -r '.warnings[].message') | |
| Please review these licenses to ensure they are acceptable for your use case." | |
| fi | |
| echo "PR_BODY<<EOF" >> $GITHUB_ENV | |
| echo "$PR_BODY" >> $GITHUB_ENV | |
| echo "EOF" >> $GITHUB_ENV | |
| - name: Create Pull Request (Push only) | |
| id: cpr | |
| if: github.event_name == 'push' && env.CHANGES_DETECTED == 'true' | |
| uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 | |
| with: | |
| token: ${{ steps.setup-bot.outputs.token }} | |
| commit-message: "Update Frontend 3rd Party Licenses" | |
| committer: ${{ steps.setup-bot.outputs.committer }} | |
| author: ${{ steps.setup-bot.outputs.committer }} | |
| signoff: true | |
| branch: update-frontend-3rd-party-licenses | |
| base: main | |
| title: "Update Frontend 3rd Party Licenses" | |
| body: ${{ env.PR_BODY }} | |
| labels: Licenses,github-actions,frontend | |
| draft: false | |
| delete-branch: true | |
| sign-commits: true | |
| - name: Enable Pull Request Automerge (Push only) | |
| if: github.event_name == 'push' && steps.cpr.outputs.pull-request-operation == 'created' && env.LICENSE_WARNINGS_EXIST == 'false' | |
| run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}" | |
| env: | |
| GH_TOKEN: ${{ steps.setup-bot.outputs.token }} | |
| - name: Add review required label (Push only) | |
| if: github.event_name == 'push' && steps.cpr.outputs.pull-request-operation == 'created' && env.LICENSE_WARNINGS_EXIST == 'true' | |
| run: gh pr edit "${{ steps.cpr.outputs.pull-request-number }}" --add-label "license-review-required" | |
| env: | |
| GH_TOKEN: ${{ steps.setup-bot.outputs.token }} | |
| generate-backend-license-report: | |
| if: needs.files-changed.outputs.licenses-backend == 'true' | |
| needs: files-changed | |
| name: Generate Backend License Report | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| repository-projects: write # Required for enabling automerge | |
| steps: | |
| - name: Harden Runner | |
| uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout repository | |
| uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup GitHub App Bot | |
| if: (github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false)) && github.actor != 'dependabot[bot]' | |
| id: setup-bot | |
| uses: ./.github/actions/setup-bot | |
| with: | |
| app-id: ${{ secrets.GH_APP_ID }} | |
| private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} | |
| - name: Set up JDK 21 | |
| uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 | |
| with: | |
| java-version: "21" | |
| distribution: "temurin" | |
| - name: Check licenses and generate report | |
| id: license-check | |
| run: | | |
| ./gradlew clean checkLicense generateLicenseReport || echo "LICENSE_CHECK_FAILED=true" >> $GITHUB_ENV | |
| env: | |
| DISABLE_ADDITIONAL_FEATURES: false | |
| STIRLING_PDF_DESKTOP_UI: true | |
| - name: Check for license compatibility issues | |
| run: | | |
| if [ -f build/reports/dependency-license/dependencies-without-allowed-license.json ] && \ | |
| jq '.dependenciesWithoutAllowedLicenses | length > 0' build/reports/dependency-license/dependencies-without-allowed-license.json | grep -q true; then | |
| echo "LICENSE_WARNINGS_EXIST=true" >> $GITHUB_ENV | |
| else | |
| echo "LICENSE_WARNINGS_EXIST=false" >> $GITHUB_ENV | |
| fi | |
| if: always() | |
| - name: Upload artifact on license issues | |
| if: env.LICENSE_WARNINGS_EXIST == 'true' | |
| uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 | |
| with: | |
| name: backend-dependencies-without-allowed-license.json | |
| path: build/reports/dependency-license/dependencies-without-allowed-license.json | |
| - name: Move license file | |
| if: env.LICENSE_CHECK_FAILED != 'true' && env.LICENSE_WARNINGS_EXIST == 'false' | |
| run: | | |
| mkdir -p app/core/src/main/resources/static | |
| cp build/reports/dependency-license/index.json app/core/src/main/resources/static/3rdPartyLicenses.json | |
| - name: Delete previous backend license check comments | |
| if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) && github.actor != 'dependabot[bot]' | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| with: | |
| github-token: ${{ steps.setup-bot.outputs.token }} | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const prNumber = context.issue.number; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner, | |
| repo, | |
| issue_number: prNumber, | |
| per_page: 100 | |
| }); | |
| const backendLicenseComments = comments.filter(comment => | |
| comment.body.includes('## ✅ Backend License Check Passed') || | |
| comment.body.includes('## ❌ Backend License Check Failed') | |
| ); | |
| for (const comment of backendLicenseComments) { | |
| console.log(`Deleting old backend license comment: ${comment.id}`); | |
| await github.rest.issues.deleteComment({ | |
| owner, | |
| repo, | |
| comment_id: comment.id | |
| }); | |
| } | |
| - name: Comment on PR - Backend License Check Results | |
| if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) && github.actor != 'dependabot[bot]' | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 | |
| with: | |
| github-token: ${{ steps.setup-bot.outputs.token }} | |
| script: | | |
| const hasWarnings = process.env.LICENSE_WARNINGS_EXIST === 'true'; | |
| const fs = require('fs'); | |
| let warningDetails = ''; | |
| if (hasWarnings) { | |
| try { | |
| const warningsFile = 'build/reports/dependency-license/dependencies-without-allowed-license.json'; | |
| if (fs.existsSync(warningsFile)) { | |
| const data = JSON.parse(fs.readFileSync(warningsFile, 'utf8')); | |
| if (data.length > 0) { | |
| warningDetails = data.map(dep => `- **${dep.moduleName}@${dep.moduleVersion}** – ${dep.moduleLicenses.map(l => l.licenseName).join(', ')}`).join('\n'); | |
| } | |
| } | |
| } catch (e) { | |
| warningDetails = 'Unable to parse warning details.'; | |
| } | |
| } | |
| let commentBody; | |
| if (hasWarnings) { | |
| commentBody = `## ❌ Backend License Check Failed | |
| The backend license check has detected dependencies with incompatible or unallowed licenses: | |
| ${warningDetails || 'See uploaded artifact for details.'} | |
| **Action Required:** Please review these licenses and resolve before merging. | |
| _This check will fail the PR until license issues are resolved._`; | |
| } else { | |
| commentBody = `## ✅ Backend License Check Passed | |
| All backend dependencies have valid and allowed licenses. | |
| The backend license report has been updated successfully.`; | |
| } | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: commentBody | |
| }); | |
| - name: Fail workflow if license warnings exist (PR only) | |
| if: github.event_name == 'pull_request' && env.LICENSE_WARNINGS_EXIST == 'true' | |
| run: | | |
| echo "❌ Backend license warnings detected. Failing the workflow." | |
| exit 1 | |
| - name: Commit changes (push only) | |
| if: github.event_name == 'push' && env.LICENSE_WARNINGS_EXIST == 'false' | |
| run: | | |
| git config user.name "${{ steps.setup-bot.outputs.committer }}" | |
| git config user.email "${{ steps.setup-bot.outputs.committer-email || '[email protected]' }}" | |
| git add app/core/src/main/resources/static/3rdPartyLicenses.json | |
| git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV | |
| - name: Prepare PR body (push only) | |
| if: github.event_name == 'push' && env.CHANGES_DETECTED == 'true' | |
| run: | | |
| PR_BODY="Auto-generated by ${{ steps.setup-bot.outputs.app-slug }}[bot] | |
| This PR updates the backend license report based on dependency changes." | |
| if [ "${{ env.LICENSE_WARNINGS_EXIST }}" = "true" ]; then | |
| PR_BODY="$PR_BODY | |
| ## ⚠️ License Compatibility Warnings | |
| Incompatible licenses detected – manual review required before merge." | |
| fi | |
| echo "PR_BODY<<EOF" >> $GITHUB_ENV | |
| echo "$PR_BODY" >> $GITHUB_ENV | |
| echo "EOF" >> $GITHUB_ENV | |
| - name: Create Pull Request (push only) | |
| if: github.event_name == 'push' && env.CHANGES_DETECTED == 'true' | |
| id: cpr | |
| uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 | |
| with: | |
| token: ${{ steps.setup-bot.outputs.token }} | |
| commit-message: "Update Backend 3rd Party Licenses" | |
| committer: ${{ steps.setup-bot.outputs.committer }} | |
| author: ${{ steps.setup-bot.outputs.committer }} | |
| signoff: true | |
| branch: update-backend-3rd-party-licenses | |
| base: main | |
| title: "Update Backend 3rd Party Licenses" | |
| body: ${{ env.PR_BODY }} | |
| labels: Licenses,github-actions,backend | |
| delete-branch: true | |
| sign-commits: true | |
| - name: Enable Pull Request Automerge (push only, no warnings) | |
| if: github.event_name == 'push' && steps.cpr.outputs.pull-request-operation == 'created' && env.LICENSE_WARNINGS_EXIST == 'false' | |
| run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}" | |
| env: | |
| GH_TOKEN: ${{ steps.setup-bot.outputs.token }} | |
| - name: Add review required label (push only, with warnings) | |
| if: github.event_name == 'push' && steps.cpr.outputs.pull-request-operation == 'created' && env.LICENSE_WARNINGS_EXIST == 'true' | |
| run: gh pr edit "${{ steps.cpr.outputs.pull-request-number }}" --add-label "license-review-required" | |
| env: | |
| GH_TOKEN: ${{ steps.setup-bot.outputs.token }} |