mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-12 23:31:02 +00:00
12e22c258a
A stable release without a dialect of its own now ships the one on main only while that one has 90 days left; dialect 0 or less stops the run before anything is committed, unless allow_stale_dialect is ticked. Fetching and checking moved into registration-dialect.yml, which never fails its caller and also type-checks the module under the strict config and lints it with --max-warnings 0, since the bump commit skips CI. The bump and everything after it run whatever became of the dialect job. Prereleases ask the issuer for a dialect of their -pre.N version and build it into the image without committing it. The release check reads the module token by token against an allowlist of keywords, globals and member names, refuses any assignment to a property, computed access and regular expressions, and names Object, JSON and defineProperty among the forbidden. The issuer's kitchen-sink sample is gone; the tests use a hand-written dialect instead.
143 lines
5.7 KiB
YAML
143 lines
5.7 KiB
YAML
name: Registration dialect
|
|
|
|
# Asks the TREK services issuer for the registration dialect of one version and
|
|
# checks it, for docker.yml (a stable release commits it with the version bump)
|
|
# and docker-dev.yml (a prerelease only builds it into its image).
|
|
#
|
|
# The issuer's answer runs here, in a job that holds no write token and keeps
|
|
# no git credentials; the token for the issuer is in the environment of the
|
|
# one step that fetches. The answer is held to what a dialect is
|
|
# (scripts/ci/check-registration-dialect.mjs), then type-checked and linted
|
|
# the way TREK's CI would see it once it is on main and dev. Only a module that
|
|
# passes all of it goes on, as the artifact `registration-dialect`; without
|
|
# one the caller decides what ships. This workflow never fails its caller.
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
version:
|
|
description: 'The version the dialect is for, X.Y.Z or X.Y.Z-pre.N'
|
|
type: string
|
|
required: true
|
|
ref:
|
|
description: 'The commit whose checker, types and lint config the dialect is checked with'
|
|
type: string
|
|
required: true
|
|
secrets:
|
|
TREK_DIALECT_TOKEN:
|
|
required: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
dialect:
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 20
|
|
# A failed or timed-out run leaves no artifact, which the caller already
|
|
# handles; it must not fail the release around it.
|
|
continue-on-error: true
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
persist-credentials: false
|
|
|
|
- uses: actions/setup-node@v6
|
|
with:
|
|
node-version-file: .nvmrc
|
|
cache: npm
|
|
cache-dependency-path: package-lock.json
|
|
|
|
# The only step that sees the token. The URL is fixed; the answer is
|
|
# bounded in time and size and goes to a file nothing runs yet.
|
|
- name: Fetch the dialect from the issuer
|
|
id: fetch
|
|
timeout-minutes: 3
|
|
env:
|
|
TREK_DIALECT_TOKEN: ${{ secrets.TREK_DIALECT_TOKEN }}
|
|
VERSION: ${{ inputs.version }}
|
|
run: |
|
|
set -uo pipefail
|
|
out="$RUNNER_TEMP/registration-dialect.ts"
|
|
if [ -z "${TREK_DIALECT_TOKEN:-}" ]; then
|
|
echo "::warning::TREK_DIALECT_TOKEN is not set; the issuer was not asked for a dialect for $VERSION."
|
|
exit 0
|
|
fi
|
|
status=$(curl --silent --show-error --proto '=https' --tlsv1.2 --max-time 30 --retry 2 --retry-delay 5 \
|
|
--max-filesize 262144 -H "Authorization: Bearer $TREK_DIALECT_TOKEN" -H 'Content-Type: application/json' \
|
|
--data "{\"version\":\"$VERSION\"}" -o "$out" -w '%{http_code}' https://places.liketrek.com/v1/dialects) \
|
|
|| status=000
|
|
if [ "$status" != 200 ] && [ "$status" != 201 ]; then
|
|
echo "::warning::The issuer handed out no registration dialect for $VERSION (HTTP $status)."
|
|
rm -f "$out"
|
|
exit 0
|
|
fi
|
|
if [ "$(wc -c < "$out")" -gt 262144 ]; then
|
|
echo "::warning::The issuer's registration dialect for $VERSION is larger than a dialect."
|
|
rm -f "$out"
|
|
exit 0
|
|
fi
|
|
echo "file=$out" >> "$GITHUB_OUTPUT"
|
|
|
|
# A module that computes for long is refused by the clock as well.
|
|
- name: Check the dialect
|
|
id: check
|
|
if: steps.fetch.outputs.file != ''
|
|
timeout-minutes: 2
|
|
env:
|
|
FILE: ${{ steps.fetch.outputs.file }}
|
|
VERSION: ${{ inputs.version }}
|
|
run: |
|
|
set -uo pipefail
|
|
if ! node scripts/ci/check-registration-dialect.mjs "$FILE" "$VERSION"; then
|
|
echo "::warning::The issuer's registration dialect for $VERSION failed its check."
|
|
exit 0
|
|
fi
|
|
echo "What changes against the dialect in the tree:"
|
|
git diff --no-index -- server/src/nest/service-identity/registration-dialect.ts "$FILE" || true
|
|
echo "ok=true" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Install the toolchain
|
|
if: steps.check.outputs.ok == 'true'
|
|
timeout-minutes: 8
|
|
run: |
|
|
npm ci --ignore-scripts --no-audit --no-fund
|
|
npm run build --workspace=shared
|
|
|
|
# The bump commit skips CI, so this is where the module meets the strict
|
|
# config (lint:strict lets a new file have no strict errors) and ESLint
|
|
# with --max-warnings 0 (lint:warnings starts a new file at none) before
|
|
# it lands on main.
|
|
- name: Type-check and lint the dialect
|
|
id: types
|
|
if: steps.check.outputs.ok == 'true'
|
|
timeout-minutes: 5
|
|
working-directory: server
|
|
env:
|
|
FILE: ${{ steps.fetch.outputs.file }}
|
|
VERSION: ${{ inputs.version }}
|
|
run: |
|
|
set -uo pipefail
|
|
cp "$FILE" src/nest/service-identity/registration-dialect.ts
|
|
printf '%s\n' '{"extends": "./tsconfig.strict.json", "include": [],' \
|
|
'"files": ["src/nest/service-identity/registration-dialect.ts"]}' > tsconfig.dialect-check.json
|
|
if ! npx tsc -p tsconfig.dialect-check.json --noEmit --pretty false; then
|
|
echo "::warning::The issuer's registration dialect for $VERSION does not type-check under the strict config."
|
|
exit 0
|
|
fi
|
|
if ! npx eslint --max-warnings 0 src/nest/service-identity/registration-dialect.ts; then
|
|
echo "::warning::The issuer's registration dialect for $VERSION does not pass ESLint."
|
|
exit 0
|
|
fi
|
|
echo "ok=true" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Hand the dialect on
|
|
if: steps.types.outputs.ok == 'true'
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: registration-dialect
|
|
path: ${{ steps.fetch.outputs.file }}
|
|
if-no-files-found: error
|
|
retention-days: 1
|