Files
unleash/.github/workflows/openapi-diff.yaml
T
Christopher Kolstad 78eb6ad911 task: migrate to pnpm (#11898)
Things worth noticing (+14075, -20262 most of this is due to yarn.lock
being deleted, and a new package manager tool being checked in)

## Code changes (actual changes to ts files)
### Not interesting
- being explicit about test imports in frontend rather than using
tsconfig globals to resolve `describe`, `it`, `test`, `expect` et al.
### Interesting
- Type signatures resolutions have changed a slightly bit, so some of
our Knex queries needed to be extracted for tsc to manage to type
analyse and pass type checking. All tests are green, so I'm assuming I
managed to reproduce the behaviour, in particular
src/lib/features/project/project-read-model.ts has some extra variables
to pass typechecking.


### Other considerations
- Do we still build the way we did? (pnpm pack produces the same
files/artifact as yarn pack)
- Will this merge cleanly with enterprise (which runs prepack)?

#### Known unknowns
- I've changed our vite.config.mts in frontend to use vite's own built
in tsconfigpaths, but Thomas pointed out that he tried that already and
ran into some issue when enterprise used the dependency, so we'll need
to double check that it works, and be ready to rollback to using the
deprecated plugin (and accept that vite gives us a warning that this is
now native functionality).

### Build failures
- Expected is openapi validation on main, we've changed to using pnpm
action rather than yarn action so it won't recognize yarn as a
packageManager on main
- dependency scanner, due to how pnpm resolves dependencies, we now have
a more direct dependencies, which our scanner apparently is scoring too
low for it to be OK with them. These were already a dependency, just
transitively rather than direct, so I'm comfortable with this.
2026-05-06 12:17:17 +02:00

229 lines
8.1 KiB
YAML

name: OpenAPI Diff
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
paths:
- src/lib/**
- .github/workflows/openapi-diff.yaml
workflow_dispatch:
inputs:
baseline_version:
description: 'Stable Unleash version or commit SHA to compare against (e.g. v6.9.3, or a commit SHA).'
required: true
jobs:
generate-openapi-stable:
name: Generate OpenAPI (stable)
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: postgres
POSTGRES_INITDB_ARGS: "--no-sync"
ports:
- 5432:5432
options: >-
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Determine baseline commit
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
git fetch origin "${{ github.event.pull_request.base.ref }}"
BASE_SHA=$(git merge-base "origin/${{ github.event.pull_request.base.ref }}" "${{ github.sha }}")
else
# workflow_dispatch: baseline_version is required
git fetch --tags origin
BASE_SHA=$(git rev-parse "${{ github.event.inputs.baseline_version }}")
fi
echo "BASE_SHA=$BASE_SHA" >> $GITHUB_ENV
- name: Checkout baseline commit
run: git checkout "${BASE_SHA}"
- uses: pnpm/action-setup@v5
- name: Install node
uses: actions/setup-node@v6
with:
node-version: 22.x
- name: Install dependencies
run: |
pnpm install --frozen-lockfile
- name: Start Unleash test instance
run: |
# fake frontend build
mkdir -p frontend/build
touch frontend/build/index.html
touch frontend/build/favicon.ico
# end fake frontend build
# start unleash in background
NODE_ENV=openapi pnpm dev:backend > /tmp/unleash-server.log 2>&1 &
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
DATABASE_SSL: 'false'
CHECK_VERSION: 'false'
- name: Wait for Unleash to be ready
run: |
for i in {1..30}; do
if curl -sf http://localhost:4242/health; then
echo "Unleash is up!";
exit 0
fi
echo "Waiting for Unleash... attempt $i";
sleep 2
done
echo "Unleash did not become ready in time."
cat /tmp/unleash-server.log
exit 1
- name: Download OpenAPI spec from baseline
run: curl -sSL -o openapi-stable.json "http://localhost:4242/docs/openapi.json"
- name: Upload openapi-stable.json
uses: actions/upload-artifact@v7
with:
name: openapi-stable
path: openapi-stable.json
generate-openapi-current:
name: Generate OpenAPI (current branch)
runs-on: ubuntu-latest
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: postgres
POSTGRES_INITDB_ARGS: "--no-sync"
# Set health checks to wait until postgres has started
ports:
- 5432:5432
options: >-
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- name: Install node
uses: actions/setup-node@v6
with:
node-version: 22.x
- name: Install dependencies
run: |
pnpm install --frozen-lockfile
- name: Start Unleash test instance
run: |
# fake frontend build
mkdir -p frontend/build
touch frontend/build/index.html
touch frontend/build/favicon.ico
# end fake frontend build
# start unleash in background
NODE_ENV=openapi pnpm dev:backend > /tmp/unleash-server.log 2>&1 &
env:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
DATABASE_SSL: 'false'
CHECK_VERSION: 'false'
- name: Wait for Unleash to be ready
run: |
for i in {1..30}; do
if curl -sf http://localhost:4242/health; then
echo "Unleash is up!";
exit 0
fi
echo "Waiting for Unleash... attempt $i";
sleep 2
done
echo "Unleash did not become ready in time."
cat /tmp/unleash-server.log
exit 1
- name: Download OpenAPI spec (current branch)
run: curl -sSL -o openapi-current.json http://localhost:4242/docs/openapi.json
- name: Upload openapi-current.json
uses: actions/upload-artifact@v7
with:
name: openapi-current
path: openapi-current.json
openapi-diff:
name: OpenAPI Diff
runs-on: ubuntu-latest
needs: [generate-openapi-current, generate-openapi-stable]
if: github.event_name == 'pull_request'
steps:
- name: Download openapi-current.json
uses: actions/download-artifact@v8
with:
name: openapi-current
- name: Download openapi-stable.json
uses: actions/download-artifact@v8
with:
name: openapi-stable
- name: Run OpenAPI diff
id: diff
run: |
docker run --rm -t -v $(pwd):/specs:ro tufin/oasdiff changelog --format markdown /specs/openapi-stable.json /specs/openapi-current.json > openapi-diff.txt || true
# then output in a format that is useful when you go inside the job output
docker run --rm -t -v $(pwd):/specs:ro tufin/oasdiff changelog --format githubactions /specs/openapi-stable.json /specs/openapi-current.json
- name: Show OpenAPI diff
if: github.event_name != 'pull_request'
run: cat openapi-diff.txt
- name: Comment on PR with OpenAPI diff
if: github.event_name == 'pull_request'
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const diff = fs.readFileSync('openapi-diff.txt', 'utf8');
const diffLines = diff.split('\n').filter(line => line.trim() !== '' && !line.startsWith('#')).length;
const marker = '[//]: # (OpenAPI diff - used to identify the comment)';
// Get all comments on the PR
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
});
// Find existing OpenAPI Diff comment
const existing = comments.find(c => c.body && c.body.includes(marker) && c.user.type === 'Bot');
let body;
if (diffLines > 300) {
body = `${marker} too long, check the this task output for details.`;
console.log(diff);
} else if (diffLines > 0) {
body = `${marker}\n${diff}`;
} else {
body = null;
}
if (body) {
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body,
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body,
});
}
} else {
console.log('No significant changes detected in OpenAPI spec.');
if (existing) {
await github.rest.issues.deleteComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
});
}
}