Convert all rspace-core-model string literals to i18n catalogue keys #3327
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: Lint and Test | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| workflow_dispatch: | |
| inputs: | |
| frontend_tests: | |
| description: 'Run TypeScript/Vitest tests' | |
| type: boolean | |
| default: false | |
| fast_java_tests: | |
| description: 'Run fast Java tests' | |
| type: boolean | |
| default: false | |
| full_java_tests: | |
| description: 'Run all Java tests' | |
| type: boolean | |
| default: false | |
| run_build: | |
| description: 'Run build' | |
| type: boolean | |
| default: false | |
| java_vendor: | |
| description: 'Java vendor Maven toolchain' | |
| type: string | |
| default: 'temurin' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| env: | |
| RS_FILE_BASE: /tmp/${{ github.ref_name }}-filestore | |
| CI: "true" | |
| jobs: | |
| changed-files: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| frontend: ${{ steps.filter.outputs.frontend }} | |
| java: ${{ steps.filter.outputs.java }} | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| persist-credentials: false | |
| - uses: dorny/paths-filter@v4.0.2 | |
| id: filter | |
| with: | |
| filters: | | |
| frontend: | |
| - 'src/main/webapp/ui/**/*.{js,jsx,ts,tsx}' | |
| - 'src/main/webapp/ui/**/*.{css,json}' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - 'pnpm-workspace.yaml' | |
| - '.github/workflows/**' | |
| java: | |
| - 'src/main/java/**' | |
| - 'src/test/java/**' | |
| - 'src/main/resources/**' | |
| - 'src/test/resources/**' | |
| - 'src/main/webapp/WEB-INF/**' | |
| - 'pom.xml' | |
| fast-junit-tests: | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| permissions: | |
| contents: read | |
| checks: write | |
| pull-requests: write | |
| strategy: | |
| matrix: | |
| java-version: [17] | |
| if: | | |
| (github.event_name == 'push' && github.ref_name == 'main') || | |
| inputs.fast_java_tests || | |
| needs.changed-files.outputs.java == 'true' | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Set up JDK | |
| uses: actions/setup-java@v5.4.0 | |
| with: | |
| distribution: ${{ inputs.java_vendor || 'temurin' }} | |
| java-version: ${{ matrix.java-version }} | |
| cache: maven | |
| - name: Setup filestore | |
| run: | | |
| rm -rf $RS_FILE_BASE | |
| mkdir -p $RS_FILE_BASE | |
| - name: Seed dev deployment.properties | |
| run: | | |
| cp -f src/main/resources/deployments/dev/deployment.properties.example \ | |
| src/main/resources/deployments/dev/deployment.properties | |
| - name: Run fast tests | |
| run: | | |
| # ponytail: forkCount=2 is conservative; raise it / isolate RS_FILE_BASE per fork (${surefire.forkNumber}) if file-collision flakiness appears | |
| ./mvnw clean test -U -Dfast=true -DforkCount=2 -DreuseForks=true -DRS_FILE_BASE=${RS_FILE_BASE} \ | |
| -Djava-version=${{ matrix.java-version }} \ | |
| -Djava-vendor=${{ inputs.java_vendor || 'temurin' }} | |
| - name: Publish test results | |
| uses: EnricoMi/publish-unit-test-result-action@v2.24.0 | |
| if: | | |
| always() && | |
| ( | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) | |
| with: | |
| comment_mode: off | |
| files: target/surefire-reports/*.xml | |
| frontend-checks: | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| if: | | |
| (github.event_name == 'push' && github.ref_name == 'main') || | |
| github.event_name == 'pull_request' || | |
| inputs.frontend_tests || | |
| needs.changed-files.outputs.frontend == 'true' | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6.0.9 | |
| with: | |
| run_install: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6.4.0 | |
| with: | |
| node-version: '24' | |
| cache: 'pnpm' | |
| cache-dependency-path: pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| # Biome lint + format check over the changed JS/TS/CSS frontend, run | |
| # before tsc. lint:ci uses --error-on-warnings --diagnostic-level=info, so | |
| # any Biome info/warning/error fails the run. | |
| - name: Biome lint and format check | |
| run: pnpm run lint:ci | |
| # Runs even when the Biome check above failed (`!cancelled()`) so a Biome | |
| # failure never hides a TypeScript failure; the job still fails if either | |
| # step fails. | |
| - name: TypeScript check | |
| if: ${{ !cancelled() }} | |
| run: | | |
| pnpm exec tsc --version | |
| pnpm run tsc | |
| # Verify the i18n catalogs are in sync with the code (extract --ci fails if | |
| # any key was added/removed/reordered without regenerating the catalogs) | |
| # and pass the i18next lint rules. Runs even if earlier steps failed so an | |
| # i18n drift is never hidden behind a Biome/tsc failure. | |
| - name: i18n catalog check | |
| if: ${{ !cancelled() }} | |
| run: | | |
| pnpm run i18n:check | |
| pnpm run i18n:lint | |
| backend-checks: | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| permissions: | |
| contents: read | |
| strategy: | |
| matrix: | |
| java-version: [17] | |
| if: | | |
| (github.event_name == 'push' && github.ref_name == 'main') || | |
| github.event_name == 'pull_request' || | |
| inputs.fast_java_tests || | |
| needs.changed-files.outputs.java == 'true' | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Set up JDK | |
| uses: actions/setup-java@v5.4.0 | |
| with: | |
| distribution: ${{ inputs.java_vendor || 'temurin' }} | |
| java-version: ${{ matrix.java-version }} | |
| cache: maven | |
| # Fail the build if any Java file is not Spotless-formatted. This is an | |
| # independent job from frontend-checks, so it runs in parallel and a | |
| # Spotless failure here fails the overall CI run without stopping the | |
| # frontend checks (and vice versa). | |
| # -DspotlessStrict adds the CleanThat checks. Plain spotless:apply will not | |
| # fix those; use `./mvnw -DspotlessStrict spotless:apply`. | |
| - name: Spotless check | |
| run: | | |
| ./mvnw -q spotless:check -DspotlessStrict \ | |
| -Djava-version=${{ matrix.java-version }} \ | |
| -Djava-vendor=${{ inputs.java_vendor || 'temurin' }} | |
| vitest-tests: | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| permissions: | |
| contents: read | |
| checks: write | |
| pull-requests: write | |
| env: | |
| # ponytail: shard count is a plain number, not a matrix-generating step; | |
| # bump both this and the matrix.shard list below together to rescale. | |
| VITEST_SHARD_COUNT: 2 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2] | |
| if: | | |
| (github.event_name == 'push' && github.ref_name == 'main') || | |
| inputs.frontend_tests || | |
| needs.changed-files.outputs.frontend == 'true' | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6.0.9 | |
| with: | |
| run_install: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6.4.0 | |
| with: | |
| node-version: '24' | |
| cache: 'pnpm' | |
| cache-dependency-path: pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| # Two CLI gotchas: (1) --reporter replaces (not extends) the reporters | |
| # configured in vite.config.ts, so default/junit/blob must all be listed | |
| # explicitly — default for readable CI logs, junit for the per-shard | |
| # check below, blob for the coverage merge in vitest-coverage-report. | |
| # (2) no `--` before the flags: pnpm forwards a literal `--` into the | |
| # command instead of stripping it like npm does, which makes vitest | |
| # silently discard everything after it and fall back to an unsharded run. | |
| - name: Run Vitest tests | |
| run: | | |
| pnpm run test --shard=${{ matrix.shard }}/${{ env.VITEST_SHARD_COUNT }} \ | |
| --reporter=default --reporter=junit --reporter=blob --coverage | |
| - name: Upload blob report | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@v7.0.1 | |
| with: | |
| name: vitest-blob-report-${{ matrix.shard }} | |
| path: src/main/webapp/ui/.vitest-reports/* | |
| include-hidden-files: true | |
| retention-days: 1 | |
| - name: Publish test results | |
| uses: EnricoMi/publish-unit-test-result-action@v2.24.0 | |
| if: | | |
| always() && | |
| ( | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) | |
| with: | |
| check_name: Vitest Tests (shard ${{ matrix.shard }}) | |
| comment_mode: off | |
| files: src/main/webapp/ui/junit.xml | |
| # Merges the per-shard coverage data (carried inside the blob reports | |
| # uploaded above) into one report via Vitest's own --merge-reports. Test | |
| # results are NOT merged this way: --merge-reports with the junit reporter | |
| # currently emits an empty (tests="0") report (vitest-dev/vitest#9674, open | |
| # upstream), so each shard's JUnit result is published separately instead | |
| # (see the vitest-tests job above). | |
| vitest-coverage-report: | |
| runs-on: ubuntu-latest | |
| needs: [changed-files, vitest-tests] | |
| if: | | |
| !cancelled() && | |
| ( | |
| (github.event_name == 'push' && github.ref_name == 'main') || | |
| inputs.frontend_tests || | |
| needs.changed-files.outputs.frontend == 'true' | |
| ) | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6.0.9 | |
| with: | |
| run_install: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6.4.0 | |
| with: | |
| node-version: '24' | |
| cache: 'pnpm' | |
| cache-dependency-path: pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Download blob reports | |
| uses: actions/download-artifact@v8.0.1 | |
| with: | |
| path: src/main/webapp/ui/.vitest-reports | |
| pattern: vitest-blob-report-* | |
| merge-multiple: true | |
| - name: Merge coverage report | |
| run: cd src/main/webapp/ui && npx vitest --merge-reports --reporter=default --coverage | |
| - name: Upload merged coverage report | |
| uses: actions/upload-artifact@v7.0.1 | |
| with: | |
| name: vitest-coverage-report | |
| path: src/main/webapp/ui/coverage | |
| retention-days: 14 | |
| # Vitest Browser Mode component tests (successors to the former Playwright-CT | |
| # suite). Each browser runs as its own matrix leg via VITEST_BROWSERS so a | |
| # failure is attributable to one engine and the legs don't contend for | |
| # resources (running all three in one process is contention-prone). | |
| browser-tests: | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| permissions: | |
| contents: read | |
| checks: write | |
| pull-requests: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| browser: [ chromium, firefox, webkit ] | |
| if: | | |
| (github.event_name == 'push' && github.ref_name == 'main') || | |
| inputs.frontend_tests || | |
| needs.changed-files.outputs.frontend == 'true' | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6.0.9 | |
| with: | |
| run_install: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6.4.0 | |
| with: | |
| node-version: '24' | |
| cache: 'pnpm' | |
| cache-dependency-path: pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| # The Vitest browser provider drives real Playwright browsers, so the | |
| # browser binaries still need installing (just the one for this leg). | |
| - name: Install Playwright browser | |
| run: pnpm exec playwright install --with-deps ${{ matrix.browser }} | |
| - name: Run Vitest browser-mode tests | |
| env: | |
| VITEST_BROWSERS: ${{ matrix.browser }} | |
| run: pnpm run test-browser | |
| - name: Publish test results | |
| uses: EnricoMi/publish-unit-test-result-action@v2.24.0 | |
| if: | | |
| always() && | |
| ( | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) | |
| with: | |
| check_name: Browser Tests (${{ matrix.browser }}) | |
| comment_mode: off | |
| files: src/main/webapp/ui/browser-junit-${{ matrix.browser }}.xml | |
| # Bundle-size comparison: build the frontend on both the PR and the base | |
| # branch, then diff the two stats.json files and post the result as a PR | |
| # comment. Restricted to same-repo PRs because posting the comment needs a | |
| # writable GITHUB_TOKEN, which fork PRs do not receive. Each build produces | |
| # src/main/webapp/ui/dist/stats.json via the vite-bundle-analyzer plugin | |
| # (enabled by FRONTEND_BUILD_STATS, see pnpm run build:stats). | |
| bundle-size-pr: | |
| name: Bundle size (PR) | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| permissions: | |
| contents: read | |
| if: | | |
| github.event_name == 'pull_request' && | |
| github.event.pull_request.head.repo.full_name == github.repository && | |
| needs.changed-files.outputs.frontend == 'true' | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6.0.9 | |
| with: | |
| run_install: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6.4.0 | |
| with: | |
| node-version: '24' | |
| cache: 'pnpm' | |
| cache-dependency-path: pnpm-lock.yaml | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build with bundle stats | |
| run: pnpm run build:stats | |
| - name: Upload PR bundle stats | |
| uses: actions/upload-artifact@v7.0.1 | |
| with: | |
| name: bundle-stats-pr | |
| path: src/main/webapp/ui/dist/stats.json | |
| if-no-files-found: error | |
| retention-days: 1 | |
| bundle-size-base: | |
| name: Bundle size (base) | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| permissions: | |
| contents: read | |
| if: | | |
| github.event_name == 'pull_request' && | |
| github.event.pull_request.head.repo.full_name == github.repository && | |
| needs.changed-files.outputs.frontend == 'true' | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| ref: ${{ github.base_ref }} | |
| persist-credentials: false | |
| # The base branch may predate the pnpm migration (no root pnpm-lock.yaml or | |
| # build:stats script). There is nothing to build in that case, so detect it | |
| # and skip the build; the report job tolerates a missing base artifact and | |
| # simply omits the comparison. Once the migration lands on the base branch | |
| # this guard becomes a no-op and the comparison runs normally. | |
| - name: Check base branch supports bundle stats | |
| id: base-support | |
| run: | | |
| if [ -f pnpm-lock.yaml ] && [ -f package.json ] && grep -q '"build:stats"' package.json; then | |
| echo "supported=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "supported=false" >> "$GITHUB_OUTPUT" | |
| echo "Base branch lacks pnpm bundle-stats tooling; skipping base build." | |
| fi | |
| - name: Setup pnpm | |
| if: steps.base-support.outputs.supported == 'true' | |
| uses: pnpm/action-setup@v6.0.9 | |
| with: | |
| run_install: false | |
| - name: Setup Node.js | |
| if: steps.base-support.outputs.supported == 'true' | |
| uses: actions/setup-node@v6.4.0 | |
| with: | |
| node-version: '24' | |
| cache: 'pnpm' | |
| cache-dependency-path: pnpm-lock.yaml | |
| - name: Install dependencies | |
| if: steps.base-support.outputs.supported == 'true' | |
| run: pnpm install --frozen-lockfile | |
| - name: Build with bundle stats | |
| if: steps.base-support.outputs.supported == 'true' | |
| run: pnpm run build:stats | |
| - name: Upload base bundle stats | |
| if: steps.base-support.outputs.supported == 'true' | |
| uses: actions/upload-artifact@v7.0.1 | |
| with: | |
| name: bundle-stats-base | |
| path: src/main/webapp/ui/dist/stats.json | |
| if-no-files-found: error | |
| retention-days: 1 | |
| bundle-size-report: | |
| name: Bundle size report | |
| runs-on: ubuntu-latest | |
| needs: [bundle-size-pr, bundle-size-base] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| steps: | |
| - name: Download PR bundle stats | |
| uses: actions/download-artifact@v8.0.1 | |
| with: | |
| name: bundle-stats-pr | |
| path: pr | |
| # The base artifact is absent when the base branch predates the pnpm | |
| # migration (see bundle-size-base). Tolerate that and skip the comparison. | |
| - name: Download base bundle stats | |
| id: download-base | |
| continue-on-error: true | |
| uses: actions/download-artifact@v8.0.1 | |
| with: | |
| name: bundle-stats-base | |
| path: base | |
| - name: Compare bundle size and comment | |
| if: steps.download-base.outcome == 'success' && hashFiles('base/stats.json') != '' | |
| uses: wojtekmaj/vite-compare-bundle-size@v1.2.1 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| current-stats-json-path: pr/stats.json | |
| base-stats-json-path: base/stats.json | |
| title: Frontend bundle size change | |
| # The bundle is hundreds of chunks; only list assets that actually | |
| # changed (added/removed/bigger/smaller) and omit the unchanged list. | |
| describe-assets: changed-only | |
| # The slow DB-backed suite is split into two jobs that run on parallel runners: | |
| # - spring-tests: runs the `test` phase (pure-unit + Spring-transactional tests) | |
| # - integration-tests: runs only the `integration-test` phase via -DskipUnitTests=true | |
| # Their union equals a full `mvn verify`. Both jobs run drop-recreate-db independently. | |
| # ponytail: this doubles DB schema-init cost (each job runs drop-recreate-db); a | |
| # pre-seeded DB image (planned) would remove that overhead. | |
| spring-tests: | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| permissions: | |
| contents: read | |
| checks: write | |
| pull-requests: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| java-version: [17] | |
| mariadb-version: ['10.11', '12.3'] | |
| if: | | |
| (github.event_name == 'push' && github.ref_name == 'main') || | |
| (github.event_name == 'pull_request' && needs.changed-files.outputs.java == 'true') || | |
| inputs.full_java_tests | |
| services: | |
| db: | |
| image: mariadb:${{ matrix.mariadb-version }} | |
| env: | |
| MARIADB_ROOT_PASSWORD: rspacedbpwd | |
| MARIADB_DATABASE: rspace | |
| MARIADB_USER: rspacedbuser | |
| MARIADB_PASSWORD: rspacedbpwd | |
| ports: | |
| - 3306:3306 | |
| options: >- | |
| --tmpfs /var/lib/mysql:rw,noexec,nosuid,size=2g | |
| --health-cmd="healthcheck.sh --connect --innodb_initialized" | |
| --health-interval=5s | |
| --health-timeout=5s | |
| --health-retries=40 | |
| --health-start-period=30s | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Set up JDK | |
| uses: actions/setup-java@v5.4.0 | |
| with: | |
| distribution: ${{ inputs.java_vendor || 'temurin' }} | |
| java-version: ${{ matrix.java-version }} | |
| cache: maven | |
| - name: Configure MariaDB | |
| run: | | |
| mysql -h127.0.0.1 -uroot -prspacedbpwd <<'SQL' | |
| SET GLOBAL character_set_server = 'utf8mb4'; | |
| SET GLOBAL collation_server = 'utf8mb4_unicode_ci'; | |
| SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; | |
| GRANT CREATE, DROP ON *.* TO 'rspacedbuser'@'%'; | |
| -- scratch database for the HibernateTest-based model tests, which | |
| -- manage their own schema and skip when it is not available | |
| CREATE DATABASE IF NOT EXISTS hibtest; | |
| GRANT ALL ON hibtest.* TO 'rspacedbuser'@'%'; | |
| FLUSH PRIVILEGES; | |
| SQL | |
| - name: Setup filestore | |
| run: | | |
| rm -rf $RS_FILE_BASE | |
| mkdir -p $RS_FILE_BASE | |
| - name: Seed dev deployment.properties | |
| run: | | |
| cp -f src/main/resources/deployments/dev/deployment.properties.example \ | |
| src/main/resources/deployments/dev/deployment.properties | |
| - name: Run Spring tests | |
| run: | | |
| ./mvnw clean test -Denvironment=drop-recreate-db \ | |
| -Djava-version=${{ matrix.java-version }} \ | |
| -Djava-vendor=${{ inputs.java_vendor || 'temurin' }} \ | |
| -Djavax.xml.accessExternalDTD=all \ | |
| -Dlog4j2.configurationFile=log4j2-dev.xml \ | |
| -Djdbc.db.maven=rspace \ | |
| -Djdbc.url=jdbc:mysql://localhost:3306/rspace \ | |
| -Dmaven.test.failure.ignore=false \ | |
| -DRS.devlogLevel=INFO \ | |
| -DRS_FILE_BASE=${RS_FILE_BASE} | |
| - name: Publish test results | |
| uses: EnricoMi/publish-unit-test-result-action@v2.24.0 | |
| if: | | |
| always() && | |
| ( | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) | |
| with: | |
| check_name: Spring Tests (MariaDB ${{ matrix.mariadb-version }}) | |
| comment_mode: off | |
| files: target/surefire-reports/*.xml | |
| integration-tests: | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| permissions: | |
| contents: read | |
| checks: write | |
| pull-requests: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| java-version: [17] | |
| mariadb-version: ['10.11', '12.3'] | |
| if: | | |
| (github.event_name == 'push' && github.ref_name == 'main') || | |
| (github.event_name == 'pull_request' && needs.changed-files.outputs.java == 'true') || | |
| inputs.full_java_tests | |
| services: | |
| db: | |
| image: mariadb:${{ matrix.mariadb-version }} | |
| env: | |
| MARIADB_ROOT_PASSWORD: rspacedbpwd | |
| MARIADB_DATABASE: rspace | |
| MARIADB_USER: rspacedbuser | |
| MARIADB_PASSWORD: rspacedbpwd | |
| ports: | |
| - 3306:3306 | |
| options: >- | |
| --tmpfs /var/lib/mysql:rw,noexec,nosuid,size=2g | |
| --health-cmd="healthcheck.sh --connect --innodb_initialized" | |
| --health-interval=5s | |
| --health-timeout=5s | |
| --health-retries=40 | |
| --health-start-period=30s | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Set up JDK | |
| uses: actions/setup-java@v5.4.0 | |
| with: | |
| distribution: ${{ inputs.java_vendor || 'temurin' }} | |
| java-version: ${{ matrix.java-version }} | |
| cache: maven | |
| - name: Configure MariaDB | |
| run: | | |
| mysql -h127.0.0.1 -uroot -prspacedbpwd <<'SQL' | |
| SET GLOBAL character_set_server = 'utf8mb4'; | |
| SET GLOBAL collation_server = 'utf8mb4_unicode_ci'; | |
| SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; | |
| GRANT CREATE, DROP ON *.* TO 'rspacedbuser'@'%'; | |
| FLUSH PRIVILEGES; | |
| SQL | |
| - name: Setup filestore | |
| run: | | |
| rm -rf $RS_FILE_BASE | |
| mkdir -p $RS_FILE_BASE | |
| - name: Seed dev deployment.properties | |
| run: | | |
| cp -f src/main/resources/deployments/dev/deployment.properties.example \ | |
| src/main/resources/deployments/dev/deployment.properties | |
| - name: Run integration tests | |
| run: | | |
| ./mvnw clean integration-test -DskipUnitTests=true -Denvironment=drop-recreate-db \ | |
| -Djava-version=${{ matrix.java-version }} \ | |
| -Djava-vendor=${{ inputs.java_vendor || 'temurin' }} \ | |
| -Djavax.xml.accessExternalDTD=all \ | |
| -Dlog4j2.configurationFile=log4j2-dev.xml \ | |
| -Dsurefire.rerunFailingTestsCount=1 \ | |
| -Djdbc.db.maven=rspace \ | |
| -Djdbc.url=jdbc:mysql://localhost:3306/rspace \ | |
| -Dmaven.test.failure.ignore=false \ | |
| -DRS.devlogLevel=INFO \ | |
| -DRS_FILE_BASE=${RS_FILE_BASE} | |
| - name: Publish test results | |
| uses: EnricoMi/publish-unit-test-result-action@v2.24.0 | |
| if: | | |
| always() && | |
| ( | |
| github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) | |
| with: | |
| check_name: Integration Tests (MariaDB ${{ matrix.mariadb-version }}) | |
| comment_mode: off | |
| files: target/surefire-reports/*.xml | |
| # WAR build with the production frontend bundle, tests skipped. Replaces the | |
| # Jenkins "Build feature branch" stage. Needs both the JDK and Node/pnpm | |
| # because -DgenerateReactDist runs the Vite production build into the WAR. | |
| build: | |
| runs-on: ubuntu-latest | |
| needs: changed-files | |
| if: | | |
| github.event_name == 'pull_request' || | |
| inputs.run_build || | |
| needs.changed-files.outputs.frontend == 'true' || | |
| needs.changed-files.outputs.java == 'true' | |
| strategy: | |
| matrix: | |
| java-version: [17] | |
| steps: | |
| - uses: actions/checkout@v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Set up JDK | |
| uses: actions/setup-java@v5.4.0 | |
| with: | |
| distribution: ${{ inputs.java_vendor || 'temurin' }} | |
| java-version: ${{ matrix.java-version }} | |
| cache: maven | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6.0.9 | |
| with: | |
| run_install: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6.4.0 | |
| with: | |
| node-version: '24' | |
| cache: 'pnpm' | |
| cache-dependency-path: pnpm-lock.yaml | |
| - name: Setup filestore | |
| run: | | |
| rm -rf $RS_FILE_BASE | |
| mkdir -p $RS_FILE_BASE | |
| - name: Seed dev deployment.properties | |
| run: | | |
| cp -f src/main/resources/deployments/dev/deployment.properties.example \ | |
| src/main/resources/deployments/dev/deployment.properties | |
| - name: Build project | |
| run: | | |
| ./mvnw clean package -DskipTests=true -DgenerateReactDist -DrenameResourcesMD5=true \ | |
| -Denvironment=keepdbintact -Dspring.profiles.active=prod -DRS.logLevel=INFO \ | |
| -Djava-version=${{ matrix.java-version }} -Djava-vendor=${{ inputs.java_vendor || 'temurin' }} \ | |
| -Dliquibase.context=run,dev-test -DpropertyFileDirPlaceholder=\$\{propertyFileDir\} |