Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 3 additions & 18 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ jobs:
with:
fetch-depth: 0

- name: Cache Bun dependencies
id: cache
uses: actions/cache@v5
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-build-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-build-

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
Expand All @@ -39,15 +30,6 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile

- name: Cache nx build cache
id: cache-nx
uses: actions/cache@v5
with:
path: node_modules/.cache/nx
key: ${{ runner.os }}-nx-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-nx-

- name: Setup version
run: bun run postinstall

Expand Down Expand Up @@ -93,6 +75,9 @@ jobs:
url: ${{ secrets.STATUS_URL }}
data: '{ "chat_url": "${{ secrets.CHAT_URL }}", "name": "${{ github.repository }}", "commit": "${{ github.sha }}", "pipeline_name": "backoffice", "branch": "${{ github.ref }}", "status": "processing", "url": "https://github.com/${{ github.repository }}/runs/${{ github.run_id }}" }'

# Do not restore an Nx cache for this build. Nx does not hash the
# gitignored src/env/version.ts, so a cached build could deploy
# the version info of an earlier commit.
- name: Build application
run: bun run build -- --verbose --configuration=${{ steps.build_ext.outputs.configuration }}

Expand Down
18 changes: 6 additions & 12 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
name: "Code scanning - action"

on:
# Pull requests are scanned by the pull_request trigger. Match the BUILD
# branches so that a pull request push is not scanned twice.
push:
branches: [develop, release/**, rc/**, release]
pull_request:
schedule:
- cron: '0 10 * * 4'
Expand All @@ -10,7 +13,7 @@ jobs:
CodeQL-Build:

runs-on: ubuntu-latest
timeout-minutes: 3
timeout-minutes: 10

steps:
- name: Checkout repository
Expand All @@ -28,16 +31,7 @@ jobs:
- name: Initialize CodeQL
uses: github/codeql-action/init@v3

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.11'

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Setup version
run: bun run postinstall

# JavaScript and TypeScript extraction reads the source files only, so the
# dependencies are not installed.
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
78 changes: 36 additions & 42 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ name: TEST
on:
pull_request:
branches: [develop]
paths-ignore:
- 'docs/**'
- '**/*.md'
workflow_call:

# Cancel superseded runs of a pull request. BUILD calls this workflow for
# pushes; those runs get a unique group, so they never queue or cancel.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 3
steps:
- uses: actions/checkout@v4

- name: Cache Bun dependencies
id: cache
uses: actions/cache@v5
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-build-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-build-

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
Expand All @@ -38,15 +38,6 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Cache Bun dependencies
id: cache
uses: actions/cache@v5
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-build-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-build-

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
Expand All @@ -55,14 +46,14 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile

# Nx skips the tests when their inputs match a cached run.
- name: Cache nx build cache
id: cache-nx
uses: actions/cache@v5
with:
path: node_modules/.cache/nx
key: ${{ runner.os }}-nx-${{ hashFiles('**/bun.lock') }}
path: .nx/cache
key: ${{ runner.os }}-nx-test-${{ github.sha }}
restore-keys: |
${{ runner.os }}-nx-
${{ runner.os }}-nx-test-

- name: Setup version
run: bun run postinstall
Expand All @@ -73,18 +64,13 @@ jobs:
e2e-test:
runs-on: ubuntu-latest
timeout-minutes: 25
env:
# Pull requests to develop and pushes to develop run Chromium only.
# Other branches run every browser.
CHROMIUM_ONLY: ${{ github.base_ref == 'develop' || github.ref == 'refs/heads/develop' }}
steps:
- uses: actions/checkout@v6

- name: Cache Bun dependencies
id: cache
uses: actions/cache@v5
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-build-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-build-

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
Expand All @@ -93,23 +79,31 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile

- name: Cache nx build cache
id: cache-nx
uses: actions/cache@v5
with:
path: node_modules/.cache/nx
key: ${{ runner.os }}-nx-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-nx-

- name: Setup version
run: bun run postinstall

- name: Get Playwright version
id: playwright
run: echo "version=$(bunx playwright --version | awk '{print $2}')" >> "$GITHUB_OUTPUT"

- name: Cache Playwright browsers
id: playwright-cache
uses: actions/cache@v5
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ steps.playwright.outputs.version }}-${{ env.CHROMIUM_ONLY == 'true' && 'chromium' || 'all' }}

- name: Install Playwright browsers
run: bunx playwright install --with-deps
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: bunx playwright install --with-deps ${{ env.CHROMIUM_ONLY == 'true' && 'chromium' || '' }}

# The cache holds the browsers only. The system packages still need to be installed.
- name: Install Playwright system dependencies
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: bunx playwright install-deps ${{ env.CHROMIUM_ONLY == 'true' && 'chromium' || '' }}

- name: Run E2E tests
run: bunx nx e2e e2e ${{ (github.base_ref == 'develop' || github.ref == 'refs/heads/develop') && '-- --project=chromium --project=mobile-chrome' || '' }}
run: bunx nx e2e e2e ${{ env.CHROMIUM_ONLY == 'true' && '-- --project=chromium --project=mobile-chrome' || '' }}

- name: Upload Playwright report
uses: actions/upload-artifact@v4
Expand Down
3 changes: 3 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions config/build-icon-fonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@

ROOT = Path(__file__).resolve().parent.parent
SOURCE = ROOT / "node_modules/material-symbols"
DESTINATION = ROOT / "public/assets"
# The fonts are bundled through src/fonts/material-symbols.css. The license
# stays in public/assets so that it ships with the app.
DESTINATION = ROOT / "src/fonts"
LICENSE_DESTINATION = ROOT / "public/assets"

for style in ("rounded", "outlined", "sharp"):
name = f"material-symbols-{style}.woff2"
font = TTFont(SOURCE / name, recalcTimestamp=False)
# Keep optical sizing. The app uses normal weight and unfilled icons.
instantiateVariableFont(font, {"wght": 400, "FILL": 0, "GRAD": 0}, inplace=True)
# The app does not set font-variation-settings, so pin every axis to its
# default: 24px optical size, normal weight, unfilled, no grade.
instantiateVariableFont(
font, {"opsz": 24, "wght": 400, "FILL": 0, "GRAD": 0}, inplace=True
)
font.save(DESTINATION / name)
print(f"{name}: {(DESTINATION / name).stat().st_size:,} bytes")

copyfile(SOURCE / "LICENSE", DESTINATION / "material-symbols-LICENSE.txt")
copyfile(SOURCE / "LICENSE", LICENSE_DESTINATION / "material-symbols-LICENSE.txt")
18 changes: 12 additions & 6 deletions docs/bundle-size.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ service worker manifest as well. They can add downloads outside that budget.

## Icon fonts

The fonts in `public/assets` retain all icon names, including names supplied by
the server. They use weight 400, fill 0, and grade 0. Optical sizing remains
variable. The source is `material-symbols` 0.39.3, with its license copied beside
the fonts.
The fonts in `src/fonts` retain all icon names, including names supplied by
the server. They use optical size 24, weight 400, fill 0, and grade 0. The app
does not set `font-variation-settings`. The source is `material-symbols` 0.39.3.
The build bundles the fonts through `src/fonts/material-symbols.css` with hashed
names. The license is in `public/assets`.

After updating that package, regenerate the fonts and review the rendered icons:
After updating `material-symbols`, regenerate the fonts and review the rendered icons:

```sh
python3 -m venv /tmp/backoffice-font-tools
Expand All @@ -27,14 +28,19 @@ python3 -m venv /tmp/backoffice-font-tools
Normal builds use the checked-in fonts and do not require Python or network access
to generate them. Do not add the original variable fonts to the build asset list.

Roboto comes from `@fontsource-variable/roboto` and Fira Code from `firacode`.
The `styles` list in `project.json` bundles their CSS. Use the font family
`'Roboto Variable'` for Roboto.

## Editors and highlighting

Settings and diff editors call `loadMonaco()` before using its API. The loader
shares concurrent requests, has a 30-second timeout, and permits retry. Components
must check whether they were destroyed before creating an editor after the load.

`markdown-languages.ts` lists the existing web languages and aliases explicitly.
Only `github-dark` is packaged. Add new language loaders there. Importing the
Only `github-dark` is packaged. Shiki uses the JavaScript regex engine, so the
Oniguruma wasm is not downloaded. Add new language loaders there. Importing the
Shiki web preset at runtime also brings its unused theme registry into the build.

## Themes and caching
Expand Down
5 changes: 5 additions & 0 deletions e2e/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ const baseURL = process.env['BASE_URL'] || 'http://localhost:4200';
export default defineConfig({
...nxE2EPreset(__filename, { testDir: './src' }),

/* The preset uses 1 worker on CI. Each page has its own mock backend, so
tests can run in parallel. GitHub runners have 4 vCPUs; keep one free
for the dev server. */
workers: process.env['CI'] ? 3 : undefined,

/* Test timeout - increase for mock mode as it may need longer to initialize */
timeout: 60000,

Expand Down
1 change: 1 addition & 0 deletions ngsw-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"resources": {
"files": [
"/assets/**",
"/media/**",
"/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"
]
}
Expand Down
9 changes: 6 additions & 3 deletions nx.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"defaultBase": "trunk",
"defaultBase": "develop",
"cacheDirectory": ".nx/cache",
"namedInputs": {
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": [
Expand All @@ -9,9 +10,11 @@
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
"!{projectRoot}/tsconfig.spec.json",
"!{projectRoot}/src/test-setup.[jt]s"
"!{projectRoot}/src/test-setup.[jt]s",
"!{projectRoot}/docs/**/*",
"!{projectRoot}/user-stories/**/*"
],
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
"sharedGlobals": []
},
"targetDefaults": {
"@angular/build:application": {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"start": "nx serve",
"build": "nx build",
"test": "nx test",
"test:ci": "nx test backoffice --runInBand",
"test:ci": "nx test backoffice",
"lint": "nx lint backoffice",
"e2e": "nx e2e backoffice"
},
Expand Down Expand Up @@ -40,6 +40,7 @@
"@angular/material": "22.1.8",
"@angular/pwa": "22.1.9",
"@eslint/js": "^9.8.0",
"@fontsource-variable/roboto": "^5.3.0",
"@ngneat/spectator": "^22.1.0",
"@nx/angular": "23.3.0",
"@nx/devkit": "23.3.0",
Expand Down
Loading
Loading