Merge dev into feat/native-apps

Brings the native apps branch up to dev (NestJS-only server, MikroORM
repositories, tracked sessions, per-domain locales, the lint ratchets) and
ports its new code onto that architecture:

- server: /api/auth/native moves onto injected services. The session is
  minted by the auth domain's new LoginSessionService (login bookkeeping and
  SessionsService.issue in one transaction), the one-time codes live behind a
  NativeHandoffStore port with a capped in-memory implementation that drops
  expired codes on write instead of running a timer, both routes declare
  response contracts, and the exchange answers { success: true }. Unit and
  e2e suites run on createTestModule and the ORM factories.
- shared: native strings for az, et, sk and th, native wired into every
  locale, the address placeholder as a full URL.
- client: the account and export changes go into dev's shared hooks
  (useAccountSettings, useTripExport), the native server card is a
  desktop/phone pair on useNativeServer, the hand-off call moves out of the
  page hook into native/, best-effort native failures go through
  reportError instead of the console, and the address screen is known to
  knip and lint:i18n-keys.
- package-lock.json regenerated on Linux.
This commit is contained in:
Maurice
2026-10-25 17:04:15 +01:00
11842 changed files with 1361077 additions and 180501 deletions
+71
View File
@@ -0,0 +1,71 @@
# Version updates, weekly, into dev. Minor and patch bumps of one ecosystem
# arrive as a single grouped PR; a major bump gets a PR of its own so its
# breaking notes are read on their own.
#
# Security updates are a repository setting, not part of this file, and
# GitHub opens them against the default branch whatever target-branch says.
# enforce-target-branch.yml moves those onto dev.
#
# Every PR runs test.yml like any other, so ci-ok decides whether it can
# merge. Dependabot runs get no Actions secrets, so s3-contract and the Sonar
# scan skip themselves on these PRs and ci-ok counts the skip as passed.
version: 2
updates:
# The root lockfile covers the client, server and shared workspaces.
- package-ecosystem: npm
directory: /
target-branch: dev
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 5
commit-message:
prefix: chore(deps)
prefix-development: chore(deps-dev)
groups:
npm-minor-and-patch:
update-types: [minor, patch]
# plugin-sdk is standalone with a lockfile of its own and ships to npm.
- package-ecosystem: npm
directory: /plugin-sdk
target-branch: dev
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 3
commit-message:
prefix: chore(plugin-sdk)
prefix-development: chore(plugin-sdk)
groups:
plugin-sdk-minor-and-patch:
update-types: [minor, patch]
# Keeps the SHA pins of third-party actions current, comment included.
- package-ecosystem: github-actions
directory: /
target-branch: dev
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 3
commit-message:
prefix: ci
groups:
actions-minor-and-patch:
update-types: [minor, patch]
# The Dockerfile's base images. The Node major follows .nvmrc and the
# engines ranges, so it moves by hand, together with them.
- package-ecosystem: docker
directory: /
target-branch: dev
schedule:
interval: weekly
day: monday
open-pull-requests-limit: 3
commit-message:
prefix: chore(docker)
ignore:
- dependency-name: node
update-types: [version-update:semver-major]
@@ -10,10 +10,11 @@ permissions:
jobs:
close-stale:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- name: Close stale invalid-title issues
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const badTitles = [
@@ -11,10 +11,11 @@ permissions:
jobs:
close-stale:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- name: Close stale wrong-base-branch PRs
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const { data: pulls } = await github.rest.pulls.list({
+3 -2
View File
@@ -10,10 +10,11 @@ permissions:
jobs:
check-title:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- name: Flag or redirect issue
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const title = context.payload.issue.title.trim();
+62 -21
View File
@@ -1,5 +1,11 @@
name: Build & Push Docker Image (Prerelease)
# The canary. Dispatched by hand, usually on dev, it builds the dispatched
# commit as <next minor or major>-pre.N, publishes :VERSION, :MAJOR-pre and
# :latest-pre, and tags the commit. Nothing moves :latest. Like the stable
# release it refuses a commit whose ci-ok is not green. docker.yml with
# bump=auto later finalizes the line once main carries it.
on:
workflow_dispatch:
inputs:
@@ -11,6 +17,7 @@ on:
permissions:
contents: write
checks: read
concurrency:
group: prerelease-build
@@ -19,23 +26,41 @@ concurrency:
jobs:
version-bump:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 120
outputs:
version: ${{ steps.bump.outputs.VERSION }}
sha: ${{ steps.bump.outputs.SHA }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
# The dev push, the main push and any manual run each leave a ci-ok on
# this commit. scripts/ci/ci-ok-verdict.mjs counts the newest attempt of
# each, refuses while one is still going, and requires the one that
# finished last to be green, so a later green run supersedes a flaky or
# cancelled one. It prints the link of every run it counted.
- name: Require a green ci-ok on the commit being built
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
sha="$(git rev-parse HEAD)"
runs="$RUNNER_TEMP/ci-ok-runs.json"
gh api "repos/$GITHUB_REPOSITORY/commits/$sha/check-runs?check_name=ci-ok&filter=all&per_page=100" > "$runs"
node scripts/ci/ci-ok-verdict.mjs "$runs" "$sha"
- name: Determine prerelease version
id: bump
env:
BUMP_INPUT: ${{ inputs.bump || 'auto' }}
run: |
git fetch --tags
# Capture the exact commit we're building so build/merge jobs are pinned to it
echo "SHA=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SHA=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
# Get latest stable tag (exclude prerelease tags)
STABLE_TAG=$(git tag -l 'v[0-9]*.[0-9]*.[0-9]*' | grep -v '\-pre\.' | sort -V | tail -1)
@@ -43,14 +68,12 @@ jobs:
STABLE="${STABLE:-0.0.0}"
echo "Latest stable: $STABLE"
IFS='.' read -r MAJOR MINOR PATCH <<< "$STABLE"
IFS='.' read -r MAJOR MINOR _ <<< "$STABLE"
# Detect any in-flight major prerelease (v(MAJOR+1).0.0-pre.*). Stay on that line if found.
NEXT_MAJOR="$((MAJOR + 1)).0.0"
MAJOR_PRE_EXISTS=$(git tag -l "v${NEXT_MAJOR}-pre.*" | head -1)
BUMP_INPUT="${{ github.event.inputs.bump || 'auto' }}"
if [ "$BUMP_INPUT" = "major" ] || { [ "$BUMP_INPUT" = "auto" ] && [ -n "$MAJOR_PRE_EXISTS" ]; }; then
TARGET="$NEXT_MAJOR"
else
@@ -63,38 +86,47 @@ jobs:
N=$(( ${LAST_N:-0} + 1 ))
NEW_VERSION="${TARGET}-pre.${N}"
echo "VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "$STABLE → $NEW_VERSION"
echo "VERSION=$NEW_VERSION" >> "$GITHUB_OUTPUT"
echo "$STABLE to $NEW_VERSION"
build:
runs-on: ${{ matrix.runner }}
timeout-minutes: 120
needs: version-bump
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
runner: ubuntu-24.04
- platform: linux/arm64
runner: ubuntu-24.04-arm
steps:
- name: Prepare platform tag-safe name
run: echo "PLATFORM_PAIR=$(echo ${{ matrix.platform }} | sed 's|/|-|g')" >> $GITHUB_ENV
env:
PLATFORM: ${{ matrix.platform }}
run: echo "PLATFORM_PAIR=${PLATFORM//\//-}" >> "$GITHUB_ENV"
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: ${{ needs.version-bump.outputs.sha }}
- uses: docker/setup-buildx-action@v3
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- uses: docker/login-action@v3
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Image metadata
id: meta
run: |
echo "revision=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
echo "created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
platforms: ${{ matrix.platform }}
@@ -102,6 +134,9 @@ jobs:
no-cache: true
build-args: |
APP_VERSION=${{ needs.version-bump.outputs.version }}
labels: |
org.opencontainers.image.revision=${{ steps.meta.outputs.revision }}
org.opencontainers.image.created=${{ steps.meta.outputs.created }}
- name: Export digest
run: |
@@ -110,7 +145,7 @@ jobs:
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
@@ -118,26 +153,27 @@ jobs:
retention-days: 1
merge:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 120
needs: [version-bump, build]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: ${{ needs.version-bump.outputs.sha }}
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Download build digests
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*
# Deliberately NOT merged: the per-platform folder names are what lets
# the manifest below be assembled in a fixed order.
- uses: docker/setup-buildx-action@v3
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- uses: docker/login-action@v3
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -163,7 +199,12 @@ jobs:
digests+=("mauriceboe/trek@sha256:$(basename "$f")")
done
done
# The labels live on each platform image; the index gets the ones a
# client reads before it picks a platform (#1498).
docker buildx imagetools create \
--annotation "index:org.opencontainers.image.source=https://github.com/liketrek/TREK" \
--annotation "index:org.opencontainers.image.version=$VERSION" \
--annotation "index:org.opencontainers.image.licenses=AGPL-3.0-only" \
-t "mauriceboe/trek:latest-pre" \
-t "mauriceboe/trek:$MAJOR_TAG" \
-t "mauriceboe/trek:$VERSION" \
@@ -186,7 +227,7 @@ jobs:
run: |
KEEP=20
VERSION="${{ needs.version-bump.outputs.version }}"
BASE_VERSION="$(echo "$VERSION" | sed 's/-pre\..*//')"
BASE_VERSION="${VERSION%%-pre.*}"
git fetch --tags
# Sort by numeric prerelease N (field after -pre.) to get correct ascending order
mapfile -t ALL_TAGS < <(git tag -l "v${BASE_VERSION}-pre.*" | awk -F'-pre\\.' '{print $2" "$0}' | sort -n | awk '{print $2}')
+123 -50
View File
@@ -1,10 +1,24 @@
name: Build & Push Docker Image
# The stable release. Dispatched by hand on main, it:
# 1. refuses to run unless ci-ok passed on the main commit it releases,
# 2. works out the version from the tags and the bump input, commits the
# bump to package.json, the lockfile and Chart.yaml, tags it and pushes,
# 3. builds both platforms from exactly that bump commit (never from
# whatever main points to by then) and publishes :VERSION,
# :MAJOR.MINOR, :MAJOR and :latest,
# 4. publishes the Helm chart from the same commit.
#
# Big or risky changes go out as a prerelease first (docker-dev.yml, tagged
# :latest-pre and :<next>-pre.N); bump=auto here then finalizes that line.
# Without a prerelease in flight there is no default: the run stops until
# someone picks patch, minor or major.
on:
workflow_dispatch:
inputs:
bump:
description: 'Force bump line (auto = patch/finalize as today)'
description: 'auto finalizes the prerelease in flight; otherwise pick patch, minor or major'
type: choice
options: [auto, patch, minor, major]
default: auto
@@ -15,6 +29,7 @@ on:
permissions:
contents: write
checks: read
concurrency:
group: stable-build
@@ -23,39 +38,65 @@ concurrency:
jobs:
version-bump:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 120
outputs:
version: ${{ steps.bump.outputs.VERSION }}
sha: ${{ steps.bump.outputs.SHA }}
steps:
- uses: actions/create-github-app-token@v1
- name: Release from main only
if: github.ref != 'refs/heads/main'
run: |
echo "::error::Dispatch this workflow on main, not on $GITHUB_REF."
exit 1
- uses: actions/create-github-app-token@v3
id: app-token
with:
app-id: ${{ secrets.RELEASE_APP_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
token: ${{ steps.app-token.outputs.token }}
# The dev push, the main push and any manual run each leave a ci-ok on
# this commit. scripts/ci/ci-ok-verdict.mjs counts the newest attempt of
# each, refuses while one is still going, and requires the one that
# finished last to be green, so a later green run supersedes a flaky or
# cancelled one. It prints the link of every run it counted.
- name: Require a green ci-ok on the commit being released
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
sha="$(git rev-parse HEAD)"
runs="$RUNNER_TEMP/ci-ok-runs.json"
gh api "repos/$GITHUB_REPOSITORY/commits/$sha/check-runs?check_name=ci-ok&filter=all&per_page=100" > "$runs"
node scripts/ci/ci-ok-verdict.mjs "$runs" "$sha"
- name: Determine bump type and update version
id: bump
env:
BUMP_INPUT: ${{ inputs.bump || 'auto' }}
CONFIRM_MAJOR: ${{ inputs.confirm_major }}
run: |
set -eu
git fetch --tags
# Derive version from git tags — no package.json dependency
# Derive version from git tags, no package.json dependency
STABLE_TAG=$(git tag -l 'v[0-9]*.[0-9]*.[0-9]*' | grep -v '\-pre\.' | sort -V | tail -1)
STABLE="${STABLE_TAG#v}"
STABLE="${STABLE:-0.0.0}"
PRE_TAG=$(git tag -l 'v*-pre.*' | sort -V | tail -1)
BUMP_INPUT="${{ github.event.inputs.bump || 'auto' }}"
IFS='.' read -r MAJOR MINOR PATCH <<< "$STABLE"
if [ "$BUMP_INPUT" = "major" ]; then
if [ "${{ github.event.inputs.confirm_major }}" != "MAJOR" ]; then
if [ "$CONFIRM_MAJOR" != "MAJOR" ]; then
echo "::error::confirm_major must equal 'MAJOR' to cut a major release"
exit 1
fi
@@ -68,79 +109,96 @@ jobs:
NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
BUMP="patch"
else
# auto: finalize in-flight prerelease if one exists, else patch
# auto finalizes the in-flight prerelease and nothing else. It used
# to fall back to a patch, which would have shipped any change,
# however big, as a patch nobody chose.
PRE_BASE=""
if [ -n "$PRE_TAG" ]; then
PRE_BASE="${PRE_TAG#v}"
PRE_BASE="${PRE_BASE%-pre.*}"
PRE_MAJOR="$(echo "$PRE_BASE" | cut -d. -f1)"
# Refuse to auto-finalize a major bump — it bypasses confirm_major
if [ "$PRE_MAJOR" -gt "$MAJOR" ]; then
echo "::error::In-flight prerelease $PRE_TAG is a major bump ($STABLE → $PRE_BASE). Use bump=major with confirm_major=MAJOR to finalize."
exit 1
fi
# If prerelease base is strictly greater than stable, finalize it
HIGHEST=$(printf '%s\n' "$PRE_BASE" "$STABLE" | sort -V | tail -1)
if [ "$HIGHEST" = "$PRE_BASE" ] && [ "$PRE_BASE" != "$STABLE" ]; then
NEW_VERSION="$PRE_BASE"
BUMP="finalize"
else
PATCH=$((PATCH + 1))
NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
BUMP="patch"
fi
else
PATCH=$((PATCH + 1))
NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
BUMP="patch"
fi
HIGHEST=$(printf '%s\n' "$PRE_BASE" "$STABLE" | sort -V | tail -1)
if [ -z "$PRE_BASE" ] || [ "$HIGHEST" != "$PRE_BASE" ] || [ "$PRE_BASE" = "$STABLE" ]; then
echo "::error::No prerelease above $STABLE is in flight, so bump=auto has nothing to finalize. Dispatch again with bump=patch, minor or major."
exit 1
fi
PRE_MAJOR="$(echo "$PRE_BASE" | cut -d. -f1)"
# Refuse to auto-finalize a major bump, it would bypass confirm_major
if [ "$PRE_MAJOR" -gt "$MAJOR" ]; then
echo "::error::In-flight prerelease $PRE_TAG is a major bump ($STABLE to $PRE_BASE). Use bump=major with confirm_major=MAJOR to finalize."
exit 1
fi
NEW_VERSION="$PRE_BASE"
BUMP="finalize"
fi
# Patch releases have carried migrations before, so this only warns:
# whoever pinned :MAJOR.MINOR gets this schema change too.
if [ "$BUMP" = "patch" ] && [ -n "$STABLE_TAG" ] \
&& [ -n "$(git diff --name-only --diff-filter=A "$STABLE_TAG" HEAD -- server/src/db/migrations/)" ]; then
echo "::warning::$NEW_VERSION is a patch release that adds database migrations."
fi
echo "Bump type: $BUMP"
echo "VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "$STABLE → $NEW_VERSION ($BUMP)"
echo "VERSION=$NEW_VERSION" >> "$GITHUB_OUTPUT"
echo "$STABLE to $NEW_VERSION ($BUMP)"
# Update all workspace + root package.json files and the root lockfile in one shot
npm version "$NEW_VERSION" --workspaces --include-workspace-root --no-git-tag-version
sed -i "s/^version: .*/version: $NEW_VERSION/" charts/trek/Chart.yaml
sed -i "s/^appVersion: .*/appVersion: \"$NEW_VERSION\"/" charts/trek/Chart.yaml
# Commit and tag
# Commit and tag. The push fast-forwards main from the commit ci-ok
# was checked on, so it fails rather than release past anything that
# landed on main in the meantime.
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add package.json package-lock.json server/package.json client/package.json shared/package.json charts/trek/Chart.yaml
git commit -m "chore: bump version to $NEW_VERSION [skip ci]"
git tag -a "v$NEW_VERSION" -m "v$NEW_VERSION"
git push origin main --follow-tags
git push origin HEAD:main --follow-tags
# build, merge and release-helm check out exactly this commit.
echo "SHA=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
build:
runs-on: ${{ matrix.runner }}
timeout-minutes: 120
needs: version-bump
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
runner: ubuntu-24.04
- platform: linux/arm64
runner: ubuntu-24.04-arm
steps:
- name: Prepare platform tag-safe name
run: echo "PLATFORM_PAIR=$(echo ${{ matrix.platform }} | sed 's|/|-|g')" >> $GITHUB_ENV
env:
PLATFORM: ${{ matrix.platform }}
run: echo "PLATFORM_PAIR=${PLATFORM//\//-}" >> "$GITHUB_ENV"
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: main
ref: ${{ needs.version-bump.outputs.sha }}
- uses: docker/setup-buildx-action@v3
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- uses: docker/login-action@v3
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Image metadata
id: meta
run: |
echo "revision=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
echo "created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
platforms: ${{ matrix.platform }}
@@ -148,6 +206,9 @@ jobs:
no-cache: true
build-args: |
APP_VERSION=${{ needs.version-bump.outputs.version }}
labels: |
org.opencontainers.image.revision=${{ steps.meta.outputs.revision }}
org.opencontainers.image.created=${{ steps.meta.outputs.created }}
- name: Export digest
run: |
@@ -156,7 +217,7 @@ jobs:
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: /tmp/digests/*
@@ -164,24 +225,25 @@ jobs:
retention-days: 1
merge:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 120
needs: [version-bump, build]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: main
ref: ${{ needs.version-bump.outputs.sha }}
- name: Download build digests
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*
# Deliberately NOT merged: the per-platform folder names are what lets
# the manifest below be assembled in a fixed order.
- uses: docker/setup-buildx-action@v3
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- uses: docker/login-action@v3
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -192,6 +254,10 @@ jobs:
set -euo pipefail
VERSION="${{ needs.version-bump.outputs.version }}"
MAJOR_TAG="$(echo "$VERSION" | cut -d. -f1)"
# :MAJOR.MINOR takes the patches of one minor line and nothing else,
# the conservative pin for an install that wants to wait out a
# release that migrates.
MINOR_TAG="$(echo "$VERSION" | cut -d. -f1-2)"
# amd64 first, always. This used to be a glob over hash-named files, so
# the order changed from one release to the next: 3.4.1 listed amd64
# first and 4.0.0 listed arm64 first. Clients that read the first entry
@@ -207,9 +273,15 @@ jobs:
digests+=("mauriceboe/trek@sha256:$(basename "$f")")
done
done
# The labels live on each platform image; the index gets the ones a
# client reads before it picks a platform (#1498).
docker buildx imagetools create \
--annotation "index:org.opencontainers.image.source=https://github.com/liketrek/TREK" \
--annotation "index:org.opencontainers.image.version=$VERSION" \
--annotation "index:org.opencontainers.image.licenses=AGPL-3.0-only" \
-t "mauriceboe/trek:latest" \
-t "mauriceboe/trek:$MAJOR_TAG" \
-t "mauriceboe/trek:$MINOR_TAG" \
-t "mauriceboe/trek:$VERSION" \
"${digests[@]}"
@@ -217,16 +289,17 @@ jobs:
run: docker buildx imagetools inspect mauriceboe/trek:latest
release-helm:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 120
needs: version-bump
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: main
ref: ${{ needs.version-bump.outputs.sha }}
- name: Publish Helm chart
uses: stefanprodan/helm-gh-pages@v1.7.0
uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 # v1.7.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
charts_dir: charts
+9 -8
View File
@@ -7,7 +7,8 @@ on:
jobs:
check-target:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 45
permissions:
pull-requests: write
issues: write
@@ -15,7 +16,7 @@ jobs:
steps:
- name: Flag or clear wrong base branch
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const base = context.payload.pull_request.base.ref;
@@ -68,12 +69,12 @@ jobs:
return;
}
// Dependabot cannot be pointed at dev. `target-branch` in dependabot.yml
// applies to version updates only; security updates always open against
// the default branch, and security updates are all this repository gets
// (there is no dependabot.yml). Labelling them meant close-stale-wrong-branch
// shut them 24 hours later, which is how 13 of them died. Retarget instead:
// a bot cannot click "Edit" the way the comment below asks a human to.
// Dependabot's security updates cannot be pointed at dev. `target-branch`
// in .github/dependabot.yml applies to version updates only; security
// updates always open against the default branch. Labelling them meant
// close-stale-wrong-branch shut them 24 hours later, which is how 13 of
// them died. Retarget instead: a bot cannot click "Edit" the way the
// comment below asks a human to.
if (context.payload.pull_request.user.login === 'dependabot[bot]') {
try {
await github.rest.pulls.update({
+14 -8
View File
@@ -9,29 +9,34 @@ concurrency:
jobs:
lint:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 45
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '24'
node-version-file: .nvmrc
- name: Install dependencies
run: npm install
- name: Run lint & format check
# Both are check-only: lint used to run eslint --fix, which rewrote the
# files before format:check looked at them, so neither could fail on
# formatting. lint:format holds every file outside
# scripts/format-baseline.json to Prettier; the list only shrinks.
id: checks
continue-on-error: true
run: |
cd shared
npm run lint
npm run format:check
npm run lint:format
- name: Comment on PR if checks failed
if: steps.checks.outcome == 'failure'
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
await github.rest.issues.createComment({
@@ -45,8 +50,9 @@ jobs:
'',
'```bash',
'cd shared',
'npm run lint',
'npm run format',
'npm run lint:fix',
'npx prettier --write <file> # each file lint:format names',
'npm run lint:format -- --update # when a listed file is formatted now',
'```',
'',
'Then commit and push the changes.',
+5 -5
View File
@@ -32,14 +32,14 @@ concurrency:
jobs:
android:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
node-version-file: .nvmrc
cache: npm
- uses: actions/setup-java@v5
@@ -49,7 +49,7 @@ jobs:
cache: gradle
- name: Install
run: npm ci --workspace shared && npm ci --workspace client
run: npm ci --workspace=shared --workspace=client
- name: Build shared
run: npm run build --workspace=shared
@@ -76,11 +76,11 @@ jobs:
- uses: actions/setup-node@v6
with:
node-version: 24
node-version-file: .nvmrc
cache: npm
- name: Install
run: npm ci --workspace shared && npm ci --workspace client
run: npm ci --workspace=shared --workspace=client
- name: Build shared
run: npm run build --workspace=shared
+7 -6
View File
@@ -15,17 +15,18 @@ permissions:
jobs:
publish:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 45
defaults:
run:
working-directory: plugin-sdk
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
# 22 matches the TREK server runtime and has node:sqlite, which the
# dev-server tests exercise.
node-version: 22
# The Node the TREK image runs the plugins on. It has the node:sqlite
# the dev-server tests exercise.
node-version-file: .nvmrc
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm publish
+52 -9
View File
@@ -1,12 +1,27 @@
name: Security Scan
# Neither job is a required check. What they report depends on the advisory
# databases as much as on the change: a CVE published overnight would turn
# every open PR red at once, including the ones that cannot fix it. The
# security floors that hold the fixes live in the root package.json's
# overrides, which a regenerated lockfile keeps.
#
# - npm-audit reads the lockfile only, so it runs in seconds on every PR
# and push into dev and main. It audits what the image installs (the
# server and shared workspaces without dev dependencies) and the
# standalone plugin-sdk.
# - scout scans the built image, base image packages included. It needs
# the Docker Hub login, so it runs on PRs and pushes into main only and
# skips fork PRs. Whether the image builds at all is test.yml's
# docker-image job, which a red scan cannot hide.
on:
pull_request:
branches: [main]
branches: [main, dev]
push:
branches: [main]
branches: [main, dev]
permissions:
contents: read
pull-requests: write
concurrency:
@@ -14,29 +29,57 @@ concurrency:
cancel-in-progress: true
jobs:
npm-audit:
name: npm audit
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
# The client's dependencies end up in a browser bundle, not in the
# image, and are audited by hand until maplibre-gl's fix (a major) lands.
- name: Audit the image's runtime dependencies
run: npm audit --package-lock-only --omit=dev --audit-level=high --workspace=server --workspace=shared
- name: Audit trek-plugin-sdk
working-directory: plugin-sdk
run: npm audit --package-lock-only --omit=dev --audit-level=high
scout:
# Docker Hub secrets are not exposed to pull requests from forks, so the
# Scout login can never succeed there.
if: github.repository == 'liketrek/TREK' && github.event.pull_request.head.repo.fork != true
runs-on: ubuntu-latest
if: >-
github.repository == 'liketrek/TREK'
&& github.event.pull_request.head.repo.fork != true
&& (github.base_ref == 'main' || github.ref == 'refs/heads/main')
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: docker/setup-buildx-action@v3
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- uses: docker/build-push-action@v5
- uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
push: false
load: true
tags: trek:scan
- uses: docker/login-action@v3
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: docker/scout-action@v1
- uses: docker/scout-action@221e7f4860634eeb1579e3bd7ca232e577bd1864 # v1.26.0
with:
command: cves
image: trek:scan
+990 -176
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -18,10 +18,11 @@ concurrency:
jobs:
deploy:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Publish to GitHub wiki
uses: Andrew-Chen-Wang/github-wiki-action@v5
uses: Andrew-Chen-Wang/github-wiki-action@1bbb4280446f9630e8e21a18012cbacf3b0f992e # v5.0.6
with:
strategy: clone