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
14 changes: 10 additions & 4 deletions .github/workflows/publish-api-types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,22 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Setup pnpm
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0

- name: Setup Node
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 24
registry-url: https://registry.npmjs.org
cache: npm
cache-dependency-path: packages/api-types/package-lock.json
cache: pnpm
cache-dependency-path: pnpm-lock.yaml

- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile

- name: Build types
run: npm run build
run: pnpm build

# The same input must give the same files, so a run that changes nothing publishes nothing (the version is the only thing that may differ)
- name: Compare with the published package
Expand Down Expand Up @@ -85,6 +88,9 @@ jobs:
npm version "$base.$GITHUB_RUN_NUMBER" --no-git-tag-version
echo "Publishing $(node -p "require('./package.json').version")"

# npm, not pnpm, on purpose: trusted publishing (OIDC token exchange) and provenance are implemented by the npm CLI (11.5.1+, which Node 24
# ships), and pnpm publish would only hand the job over to it. Nothing in this package depends on pnpm-only publish features (no workspace: or
# catalog: specifiers), so the tarball is identical.
- name: Publish
if: steps.compare.outputs.changed == 'true'
run: npm publish --access public
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Homestead.json
Homestead.yaml
npm-debug.log
pnpm-debug.log
yarn-error.log
public/storage
storage/media-library
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Browser sessions use `SESSION_DRIVER=database` with the table `luna_sessions` (c
Winterchilla kept the tables consistent with ActiveRecord callbacks; Luna repeats the ones that touch data: `render_notes` (before every save of an appearance, `App\Utils\AppearanceNotes`, a `saving` event on `Appearance`: sanitized HTML, `>>123` Derpibooru links, `S1E3` episode links in the Friendship is Magic guide, `Movie#3`, `#123` appearance links, `\#`; the stored `notes_rend` is what both front ends show), `assign_order` (useful links via `eloquent-sortable`, color groups and colors in their controllers, appearances), `deleteVerifications` (`BlockedEmail::record` deletes the address's pending verifications), `make_related_entries` of point grants (`PcgPointGrant::record`) and the search index updates for pinning, deleting and saving (`AppearanceIndex`). Not repeated on purpose: removing cutie mark, sprite and rendered image files of `fs/` (Luna keeps its files in medialibrary, they are removed with the model) and Winterchilla's `CachedDeviation` rows (Luna caches deviations in Laravel's cache). Test: `ModelEventParityTest`.

### The OpenAPI document is committed
`docs/openapi/api-docs.json` is a copy of the generated document, kept in source control. `packages/api-types` builds the npm package `@went.tf/mlp-vectorclub-api-types` from it, and the `Publish API types` workflow publishes a new version whenever the file changes on `main` (trusted publishing, no token), which Celestia installs. `php artisan l5-swagger:generate` refreshes it by hand (the listener in `AppServiceProvider` calls `php artisan openapi:sync`, not on the server or in tests), `php artisan openapi:sync --check` fails when it is stale and `OpenApiDocumentTest` runs that check, so commit the file with every change to an annotation. After changing the API, push Luna first, wait for the publish, then raise the dependency in Celestia.
`docs/openapi/api-docs.json` is a copy of the generated document, kept in source control. `packages/api-types` builds the npm package `@went.tf/mlp-vectorclub-api-types` from it, and the `Publish API types` workflow publishes a new version whenever the file changes on `main` (trusted publishing, no token), which Celestia installs. The Node side uses pnpm (`pnpm-workspace.yaml` covers the root and `packages/api-types`, one `pnpm-lock.yaml`, `minimumReleaseAge` of 14 days, `packageManager` in the root `package.json`); the workflow installs with `pnpm install --frozen-lockfile`, builds with `pnpm build` and publishes with `npm publish` (the npm CLI does the OIDC/provenance part). `deploy.conf` runs `pnpm install --frozen-lockfile --prod --filter .` as the deploy user. `php artisan l5-swagger:generate` refreshes it by hand (the listener in `AppServiceProvider` calls `php artisan openapi:sync`, not on the server or in tests), `php artisan openapi:sync --check` fails when it is stale and `OpenApiDocumentTest` runs that check, so commit the file with every change to an annotation. After changing the API, push Luna first, wait for the publish, then raise the dependency in Celestia.

### The generated OpenAPI document is what Celestia builds against
Celestia generates its types from Luna's `/generated/api-docs.json`, not from Winterchilla's `api.json` (Winterchilla's contract is a design reference). The response schemas shared with the contract live in `app/OpenApi/ContractSchemas.php` (generated once from the contract, now maintained by hand). `python3 scripts/validate-responses.py [base url]` calls every GET operation against a running server (the contract server on :8766) and validates the response bodies against the schemas the document declares, it must report 0 problems; run it after changing a response shape or an annotation. `GenerateEnumDocblocks` still contains old copies of some schema docblocks as templates.
Expand Down
16 changes: 9 additions & 7 deletions deploy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Ported from this repo's old setup/post-receive.sh (a hand-rolled hook on
# a non-bare `production` remote with receive.denyCurrentBranch=updateInstead).
# Same steps: composer install as www-data, artisan optimize, migrate,
# conditional npm install based on whether package-lock.json changed,
# conditional pnpm install based on whether pnpm-lock.yaml changed,
# artisan commit:clear (flushes a redis-backed cache) and
# l5-swagger:generate (regenerates OpenAPI docs) on every deploy. No
# service restart for the app itself (no SSR process); the queue worker (setup/luna-horizon.service)
Expand Down Expand Up @@ -95,17 +95,19 @@ deploy_build() {
changed_files=$(git --git-dir="$GIT_DIR" diff --name-only "$oldrev" "$newrev")
fi

if [[ -z "$changed_files" ]] || grep -q "^package-lock\.json" <<< "$changed_files"; then
if [[ -z "$changed_files" ]] || grep -qE "^(pnpm-lock\.yaml|pnpm-workspace\.yaml|package\.json)" <<< "$changed_files"; then
# As the deploy user, not www-data: node_modules is owned by it (www-data only ever reads
# svgo from there), and as www-data npm can't even replace its own .package-lock.json,
# which failed every deploy that touched package-lock.json (or had no changed-file list).
if npm install --omit=dev --no-save; then
echo "git-deploy: npm install OK"
# svgo from there), and as www-data the install can't write to it, which used to fail every
# deploy that touched the lockfile (or had no changed-file list). Needs pnpm on the deploy
# user's PATH (corepack enable, the version comes from packageManager in package.json).
# CI=true lets pnpm replace the old npm-made node_modules without a TTY prompt. --filter . keeps it to the root project: packages/api-types is only built in CI.
if CI=true pnpm install --frozen-lockfile --prod --filter .; then
echo "git-deploy: pnpm install OK"
else
FAILED=1
fi
else
echo "git-deploy: skipping npm install, lockfile not modified"
echo "git-deploy: skipping pnpm install, lockfile not modified"
fi

if sudo -u www-data php artisan commit:clear; then
Expand Down
Loading
Loading