mirror of
https://github.com/zadam/trilium.git
synced 2026-09-13 18:46:08 +05:00
640 lines
24 KiB
YAML
640 lines
24 KiB
YAML
name: Dev
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- standalone
|
|
- "release/*"
|
|
pull_request:
|
|
branches:
|
|
- main
|
|
- standalone
|
|
- "release/*"
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
GHCR_REGISTRY: ghcr.io
|
|
DOCKERHUB_REGISTRY: docker.io
|
|
IMAGE_NAME: ${{ github.repository}}
|
|
TEST_TAG: ${{ github.repository}}:test
|
|
|
|
permissions:
|
|
pull-requests: write # for PR comments
|
|
|
|
jobs:
|
|
# Decides which of the two heavyweight suites a given push/PR can actually
|
|
# affect. Both suites also run the shared trilium-core spec set, so anything
|
|
# under that package (or the workspace roots) has to trigger both.
|
|
changes:
|
|
name: Detect affected suites
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
server: ${{ steps.filter.outputs.server }}
|
|
standalone: ${{ steps.filter.outputs.standalone }}
|
|
ckeditor5: ${{ steps.filter.outputs.ckeditor5 }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
|
|
id: filter
|
|
with:
|
|
filters: |
|
|
# Workspace-wide inputs: these change how anything installs or builds.
|
|
# Kept as its own anchor so the ckeditor5 filter can pick it up
|
|
# without inheriting the much wider trilium-core closure below.
|
|
workspace: &workspace
|
|
- 'pnpm-lock.yaml'
|
|
- 'pnpm-workspace.yaml'
|
|
- 'package.json'
|
|
- 'tsconfig*.json'
|
|
- '.npmrc'
|
|
- '.nvmrc'
|
|
# pnpm-workspace.yaml patches @excalidraw/excalidraw, so editing a
|
|
# patch changes what actually gets installed.
|
|
- 'patches/**'
|
|
- '.github/workflows/dev.yml'
|
|
# apps/server and apps/standalone each include
|
|
# ../../packages/trilium-core/src/**/*.spec.ts in their vitest
|
|
# `include` — the standalone suite exists precisely to re-run that
|
|
# set under happy-dom + sql.js — so both need core and everything
|
|
# core pulls in. turndown-plugin-gfm is here because trilium-core
|
|
# depends on it; it is not a direct dependency of either app.
|
|
core: &core
|
|
- 'packages/trilium-core/**'
|
|
- 'packages/commons/**'
|
|
- 'packages/turndown-plugin-gfm/**'
|
|
- 'packages/trilium-backup-container/**'
|
|
- 'packages/highlightjs/**'
|
|
server:
|
|
- *workspace
|
|
- *core
|
|
- 'apps/server/**'
|
|
# Widest closure in the repo: apps/standalone depends on eight
|
|
# workspace packages. It reaches into apps/client too, but only
|
|
# through ../../client/src/index.js, which main.spec.ts mocks — no
|
|
# client code executes in this suite, so apps/client is left out.
|
|
standalone:
|
|
- *workspace
|
|
- *core
|
|
- 'apps/standalone/**'
|
|
- 'packages/ckeditor5/**'
|
|
- 'packages/codemirror/**'
|
|
- 'packages/share-theme/**'
|
|
- 'packages/splitjs/**'
|
|
# Narrowest closure of the three: the aggregate depends only on
|
|
# commons. Note this filter does not guard the t()/translation-key
|
|
# contract — apps/client/src/services/i18n.spec.ts reads
|
|
# packages/ckeditor5/src off disk to enforce that, and it runs in
|
|
# test_dev, which is ungated.
|
|
ckeditor5:
|
|
- *workspace
|
|
- 'packages/ckeditor5/**'
|
|
- 'packages/commons/**'
|
|
|
|
test_dev:
|
|
name: Test development
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout the repository
|
|
uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
- name: Set up node & dependencies
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
cache: "pnpm"
|
|
- run: pnpm install --frozen-lockfile
|
|
|
|
- name: Typecheck
|
|
run: pnpm typecheck
|
|
|
|
- name: Run the repo-script tests
|
|
run: pnpm scripts:test
|
|
|
|
- name: Run the client-side tests
|
|
id: test-client
|
|
run: pnpm run --filter=client test --coverage
|
|
|
|
- name: Upload client test report
|
|
uses: actions/upload-artifact@v7
|
|
if: always()
|
|
with:
|
|
name: client-test-report
|
|
path: apps/client/test-output/vitest/html/
|
|
retention-days: 30
|
|
|
|
- name: Upload client coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-client.outcome == 'success' }}
|
|
with:
|
|
files: apps/client/test-output/vitest/coverage/lcov.info
|
|
flags: client
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload client test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-client.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: apps/client/test-output/vitest/junit.xml
|
|
flags: client
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Run the desktop tests
|
|
id: test-desktop
|
|
run: pnpm run --filter=desktop test --coverage
|
|
|
|
- name: Upload desktop coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-desktop.outcome == 'success' }}
|
|
with:
|
|
files: apps/desktop/test-output/vitest/coverage/lcov.info
|
|
flags: desktop
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload desktop test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-desktop.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: apps/desktop/test-output/vitest/junit.xml
|
|
flags: desktop
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Run the commons tests
|
|
id: test-commons
|
|
run: pnpm run --filter=commons test --coverage
|
|
|
|
- name: Upload commons coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-commons.outcome == 'success' }}
|
|
with:
|
|
files: packages/commons/test-output/vitest/coverage/lcov.info
|
|
flags: commons
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload commons test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-commons.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: packages/commons/test-output/vitest/junit.xml
|
|
flags: commons
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Run the codemirror tests
|
|
id: test-codemirror
|
|
run: pnpm run --filter=codemirror test --coverage
|
|
|
|
- name: Upload codemirror coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-codemirror.outcome == 'success' }}
|
|
with:
|
|
files: packages/codemirror/test-output/vitest/coverage/lcov.info
|
|
flags: codemirror
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload codemirror test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-codemirror.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: packages/codemirror/test-output/vitest/junit.xml
|
|
flags: codemirror
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Run the highlightjs tests
|
|
id: test-highlightjs
|
|
run: pnpm run --filter=highlightjs test --coverage
|
|
|
|
- name: Upload highlightjs coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-highlightjs.outcome == 'success' }}
|
|
with:
|
|
files: packages/highlightjs/test-output/vitest/coverage/lcov.info
|
|
flags: highlightjs
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload highlightjs test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-highlightjs.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: packages/highlightjs/test-output/vitest/junit.xml
|
|
flags: highlightjs
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Run the pdfjs-viewer tests
|
|
id: test-pdfjs-viewer
|
|
run: pnpm run --filter=pdfjs-viewer test --coverage
|
|
|
|
- name: Upload pdfjs-viewer coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-pdfjs-viewer.outcome == 'success' }}
|
|
with:
|
|
files: packages/pdfjs-viewer/test-output/vitest/coverage/lcov.info
|
|
flags: pdfjs-viewer
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload pdfjs-viewer test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-pdfjs-viewer.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: packages/pdfjs-viewer/test-output/vitest/junit.xml
|
|
flags: pdfjs-viewer
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Run the rest of the tests
|
|
run: pnpm run --filter=\!client --filter=\!standalone --filter=\!server --filter=\!desktop --filter=\!commons --filter=\!ckeditor5 --filter=\!codemirror --filter=\!highlightjs --filter=\!pdfjs-viewer test
|
|
|
|
# The two suites below are split out of test_dev so they run concurrently with
|
|
# it (and each other) rather than queueing behind the client/package suites.
|
|
#
|
|
# Each job always starts and gates its *steps* on the filter, rather than
|
|
# carrying a job-level `if:`. A job skipped at the job level reports no result
|
|
# to a branch-protection required check, and propagates the skip through
|
|
# `needs:` to build_docker. Gating the steps keeps the job green and the
|
|
# dependency graph intact on a run that touches neither suite; the cost is one
|
|
# checkout on an unaffected run.
|
|
test_server:
|
|
name: Test server
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
env:
|
|
AFFECTED: ${{ needs.changes.outputs.server }}
|
|
steps:
|
|
- name: Checkout the repository
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
if: env.AFFECTED == 'true'
|
|
- name: Set up node & dependencies
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
cache: "pnpm"
|
|
- name: Install dependencies
|
|
if: env.AFFECTED == 'true'
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Run the server-side tests
|
|
id: test-server
|
|
if: env.AFFECTED == 'true'
|
|
run: pnpm run --filter=server test --coverage
|
|
|
|
- name: Upload server test report
|
|
uses: actions/upload-artifact@v7
|
|
if: ${{ !cancelled() && steps.test-server.outcome != 'skipped' }}
|
|
with:
|
|
name: server-test-report
|
|
path: apps/server/test-output/vitest/html/
|
|
retention-days: 30
|
|
|
|
- name: Upload server coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-server.outcome == 'success' }}
|
|
with:
|
|
files: apps/server/test-output/vitest/coverage/lcov.info
|
|
flags: server
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload server test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-server.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: apps/server/test-output/vitest/junit.xml
|
|
flags: server
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
test_standalone:
|
|
name: Test standalone
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
env:
|
|
AFFECTED: ${{ needs.changes.outputs.standalone }}
|
|
steps:
|
|
- name: Checkout the repository
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
if: env.AFFECTED == 'true'
|
|
- name: Set up node & dependencies
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
cache: "pnpm"
|
|
- name: Install dependencies
|
|
if: env.AFFECTED == 'true'
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Run the standalone tests
|
|
id: test-standalone
|
|
if: env.AFFECTED == 'true'
|
|
# Runs the same trilium-core spec set as the server suite, but in
|
|
# happy-dom + sql.js WASM via BrowserSqlProvider (see
|
|
# apps/standalone/src/test_setup.ts). Catches differences
|
|
# between the Node-side and browser-side runtimes.
|
|
run: pnpm run --filter=standalone test --coverage
|
|
|
|
- name: Upload standalone coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-standalone.outcome == 'success' }}
|
|
with:
|
|
files: apps/standalone/test-output/vitest/coverage/lcov.info
|
|
flags: standalone
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload standalone test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-standalone.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: apps/standalone/test-output/vitest/junit.xml
|
|
flags: standalone
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
# The two shards the suite was already split into now run as separate jobs
|
|
# rather than back-to-back in one step, and a merge job evaluates the coverage
|
|
# gate over the combined blob reports. Sharding exists for renderer memory, not
|
|
# speed (see the comment on the test step); running the shards concurrently is
|
|
# what makes it also a speedup.
|
|
test_ckeditor5:
|
|
name: Test CKEditor 5 (shard ${{ matrix.shard }})
|
|
runs-on: ubuntu-latest
|
|
needs: changes
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
shard: [1, 2]
|
|
env:
|
|
AFFECTED: ${{ needs.changes.outputs.ckeditor5 }}
|
|
steps:
|
|
- name: Checkout the repository
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
if: env.AFFECTED == 'true'
|
|
- name: Set up node & dependencies
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
cache: "pnpm"
|
|
- name: Install dependencies
|
|
if: env.AFFECTED == 'true'
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Install Playwright's Chromium
|
|
if: env.AFFECTED == 'true'
|
|
run: pnpm exec playwright install --with-deps chromium
|
|
|
|
- name: Run the CKEditor 5 aggregate tests
|
|
id: test-ckeditor5
|
|
if: env.AFFECTED == 'true'
|
|
# The suite drives a real headless Chromium through Playwright. When the browser session
|
|
# fails to start, vitest waits on it rather than erroring, so cap the step instead of
|
|
# letting it sit until the job's default timeout.
|
|
timeout-minutes: 15
|
|
run: |
|
|
# Browser mode keeps one page for the whole run, and v8 coverage data accumulates in it:
|
|
# measured locally, the heap reaches ~850MB by the 100th spec file with --coverage against
|
|
# ~240MB without it. That is where a CI runner's renderer gives out — the session either
|
|
# drops mid-run or stops responding. Each shard is ~60 files, peaking around 500MB. The
|
|
# thresholds are zeroed here and evaluated once over the merged report instead, so the
|
|
# gate still covers the whole suite rather than each shard separately.
|
|
pnpm run --filter=ckeditor5 test --shard=${{ matrix.shard }}/${{ strategy.job-total }} \
|
|
--reporter=blob --coverage \
|
|
--coverage.thresholds.lines=0 --coverage.thresholds.functions=0 \
|
|
--coverage.thresholds.branches=0 --coverage.thresholds.statements=0
|
|
|
|
# Vitest names blobs `.vitest/blob/blob-<index>-<count>.json`, so the two
|
|
# shards produce distinct filenames and merge-multiple cannot clobber them.
|
|
# That directory is dot-prefixed, and upload-artifact skips hidden paths
|
|
# unless told otherwise — without include-hidden-files it silently matches
|
|
# nothing.
|
|
- name: Upload the shard blob report
|
|
uses: actions/upload-artifact@v7
|
|
if: ${{ !cancelled() && steps.test-ckeditor5.outcome == 'success' }}
|
|
with:
|
|
name: ckeditor5-blob-${{ matrix.shard }}
|
|
path: packages/ckeditor5/.vitest/blob/
|
|
include-hidden-files: true
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
test_ckeditor5_merge:
|
|
name: CKEditor 5 coverage gate
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- changes
|
|
- test_ckeditor5
|
|
env:
|
|
AFFECTED: ${{ needs.changes.outputs.ckeditor5 }}
|
|
steps:
|
|
- name: Checkout the repository
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
if: env.AFFECTED == 'true'
|
|
- name: Set up node & dependencies
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
cache: "pnpm"
|
|
- name: Install dependencies
|
|
if: env.AFFECTED == 'true'
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Download the shard blob reports
|
|
if: env.AFFECTED == 'true'
|
|
uses: actions/download-artifact@v8
|
|
with:
|
|
pattern: ckeditor5-blob-*
|
|
merge-multiple: true
|
|
path: packages/ckeditor5/.vitest/blob
|
|
|
|
# Re-runs no tests; it replays the blobs to produce the junit and lcov
|
|
# output and to evaluate the package's real coverage thresholds over the
|
|
# whole suite.
|
|
- name: Merge the shard reports and evaluate the coverage gate
|
|
id: test-ckeditor5
|
|
if: env.AFFECTED == 'true'
|
|
run: pnpm run --filter=ckeditor5 test --mergeReports --coverage
|
|
|
|
- name: Upload ckeditor5 coverage to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-ckeditor5.outcome == 'success' }}
|
|
with:
|
|
files: packages/ckeditor5/test-output/vitest/coverage/lcov.info
|
|
flags: ckeditor5
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
- name: Upload ckeditor5 test results to Codecov
|
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
|
if: ${{ !cancelled() && steps.test-ckeditor5.outcome != 'skipped' }}
|
|
with:
|
|
report_type: test_results
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
files: packages/ckeditor5/test-output/vitest/junit.xml
|
|
flags: ckeditor5
|
|
disable_search: true
|
|
fail_ci_if_error: false
|
|
|
|
# Deliberately ungated: this validates that the client and server build and
|
|
# that the image assembles, none of which depends on a test outcome. Waiting
|
|
# for the suites put ~4m of Docker work in series behind the slowest of them
|
|
# for no signal. It now runs alongside them, so the workflow finishes with the
|
|
# longest test job rather than after it.
|
|
#
|
|
# The trade is that a push whose tests fail still spends runner time building
|
|
# images. That is the accepted cost of taking the Docker work off the critical
|
|
# path; the concurrency group above still cancels superseded runs.
|
|
build_docker:
|
|
name: Build Docker image
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
- name: Set up node & dependencies
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
cache: "pnpm"
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Update build info
|
|
run: pnpm run chore:update-build-info
|
|
- name: Trigger client build
|
|
run: pnpm client:build
|
|
env:
|
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
- name: Trigger server build
|
|
run: pnpm run server:build
|
|
- uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
|
|
- uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
|
with:
|
|
context: apps/server
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
test_docker:
|
|
name: Check Docker build
|
|
runs-on: ubuntu-latest
|
|
# Kept: build_docker populates the type=gha buildx cache this job reads. The
|
|
# two together (~4m) still finish well inside the slowest test job, so
|
|
# breaking the chain would buy nothing and would leave both jobs racing to
|
|
# write the same cache.
|
|
needs:
|
|
- build_docker
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
- dockerfile: Dockerfile.alpine
|
|
- dockerfile: Dockerfile
|
|
steps:
|
|
- name: Checkout the repository
|
|
uses: actions/checkout@v7
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
- name: Set up node & dependencies
|
|
uses: actions/setup-node@v7
|
|
with:
|
|
node-version: 24
|
|
cache: "pnpm"
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Update build info
|
|
run: pnpm run chore:update-build-info
|
|
- name: Trigger build
|
|
run: pnpm server:build
|
|
|
|
- name: Set IMAGE_NAME to lowercase
|
|
run: echo "IMAGE_NAME=${IMAGE_NAME,,}" >> $GITHUB_ENV
|
|
- name: Set TEST_TAG to lowercase
|
|
run: echo "TEST_TAG=${TEST_TAG,,}" >> $GITHUB_ENV
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
|
|
|
|
- name: Build and export to Docker
|
|
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
|
with:
|
|
context: apps/server
|
|
file: apps/server/${{ matrix.dockerfile }}
|
|
load: true
|
|
tags: ${{ env.TEST_TAG }}
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
|
|
- name: Validate container run output
|
|
run: |
|
|
CONTAINER_ID=$(docker run -d --log-driver=journald --rm --name trilium_local ${{ env.TEST_TAG }})
|
|
echo "Container ID: $CONTAINER_ID"
|
|
|
|
- name: Wait for the healthchecks to pass
|
|
uses: stringbean/docker-healthcheck-action@a958d329225ccbd485766815734e01c335e62bd4 # v3.0.0
|
|
with:
|
|
container: trilium_local
|
|
wait-time: 50
|
|
require-status: running
|
|
require-healthy: true
|
|
|
|
# Print the entire log of the container thus far, regardless if the healthcheck failed or succeeded
|
|
- name: Print entire log
|
|
if: always()
|
|
run: journalctl -u docker CONTAINER_NAME=trilium_local --no-pager
|