Skip to content

feat(platform): a SPA's /api reaches a protected sibling through the gateway, and a sibling's wiring comes from the design #769

feat(platform): a SPA's /api reaches a protected sibling through the gateway, and a sibling's wiring comes from the design

feat(platform): a SPA's /api reaches a protected sibling through the gateway, and a sibling's wiring comes from the design #769

Workflow file for this run

name: CI
on:
pull_request:
push:
branches: [main]
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
verify:
name: build, test, lint
runs-on: ubuntu-latest
# Normal runs are ~8 min; this ceiling catches a hung test instead of letting
# it run to the GitHub 6h limit (a past run burned 76 min this way).
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
# setup-go caches the Go module + build caches (keyed on go.sum) by default.
- uses: actions/setup-go@v5
with:
go-version-file: go.work
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Enable corepack (pnpm)
run: corepack enable
# Resolve paths consumed by the cache steps below (as step outputs so the
# workflow linter can see them), and put the Go tool bin on PATH.
- name: Resolve tool paths + PATH
id: paths
run: |
GOBIN="$(go env GOPATH)/bin"
echo "$GOBIN" >> "$GITHUB_PATH"
echo "go-bin=$GOBIN" >> "$GITHUB_OUTPUT"
echo "pnpm-store=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
# ── Caches ──────────────────────────────────────────────────────────────
# pnpm content-addressable store, keyed on the lockfile.
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ steps.paths.outputs.pnpm-store }}
key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: pnpm-${{ runner.os }}-
# golangci-lint binary — lets us skip `make tools` (~1 min) on a hit. Keyed
# on the Makefile, which pins GOLANGCI_VERSION + GO_TOOLCHAIN.
- name: Cache golangci-lint binary
id: cache-golangci-bin
uses: actions/cache@v4
with:
path: ${{ steps.paths.outputs.go-bin }}/golangci-lint
key: golangci-bin-${{ runner.os }}-${{ hashFiles('Makefile') }}
# golangci-lint analysis cache — speeds the lint run itself.
- name: Cache golangci-lint analysis
uses: actions/cache@v4
with:
path: ~/.cache/golangci-lint
key: golangci-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
restore-keys: golangci-cache-${{ runner.os }}-
# Turborepo cache — unchanged TS packages replay from cache instead of
# re-running typecheck/build/test/lint. github.sha keeps each run's cache
# fresh; restore-keys seeds it from the most recent prior run.
- name: Cache turbo
uses: actions/cache@v4
with:
path: .turbo
key: turbo-${{ runner.os }}-${{ github.sha }}
restore-keys: turbo-${{ runner.os }}-
- name: Install dependencies
run: make install
- name: Install pinned Go tools (golangci-lint)
if: steps.cache-golangci-bin.outputs.cache-hit != 'true'
run: make tools
- name: go.sum consistency check
run: |
for d in $(go list -m -f '{{.Dir}}'); do
echo ">> go mod tidy -diff $d"
(cd "$d" && go mod tidy -diff)
done
- name: Typecheck
run: make typecheck
- name: Build
run: make build
- name: Test
run: make test
- name: Contract codegen freshness (aep-api)
run: make -C services/aep-api gen-api-check
- name: Dead-code gate (aep-api)
run: make -C services/aep-api deadcode-check
- name: Dead-code gate (TS — agents + playground)
run: make deadcode-ts-check
- name: Lint
run: make lint
- name: License header check
run: make license-check
# ── The `bal library` tool ──────────────────────────────────────────────────
# A job of its own rather than steps in `verify`: the toolchain is JDK 21 +
# Gradle, which nothing else in this repo needs, and a red Java suite should
# read as a red Java suite. The tool's source used to live in a repository of
# its own and carried this workflow there; it came along when the source moved
# in, minus the release half, which the tool's upstream repo still owns.
bal-library-tool:
name: bal library tool — build, test, coverage
runs-on: ubuntu-latest
# Normal runs are ~2 min. The ceiling catches a hung test rather than letting
# it run to GitHub's 6h limit.
timeout-minutes: 15
defaults:
run:
working-directory: packages/bal-library-tool
# Gradle reads these two names to reach ballerina-platform's GitHub Packages,
# which is the only place `org.ballerinalang:ballerina-cli` is published. A
# repo-scoped GITHUB_TOKEN suffices, so there is no secret to provision —
# rationale in runners/remote-worker/design/decisions/ADR-0008.
env:
packageUser: ${{ github.actor }}
packagePAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
cache: gradle
# The tests are OFFLINE by construction — the corpus is recorded payloads
# and the cache seam is `DocsCache.NULL`, so no test reaches the network or
# a real $HOME. Ballerina itself is therefore not needed to run them; it is
# needed only to package the tool, which `make-dist.sh` does.
- name: Test
run: ./gradlew :native:test --no-daemon
# The floors are 80% instruction / 70% branch, declared in
# native/build.gradle. Coverage here is a floor, not a score to chase: the
# register's fix sites are read once, deep in a payload walk, and a line
# nothing executes is a line whose fix nothing will verify.
- name: Coverage floors
run: ./gradlew :native:jacocoTestCoverageVerification --no-daemon
# `make-dist.sh` and not `:native:jar`, because the distribution is what the
# runner image's first stage builds — this is the path release depends on,
# so it is the path CI exercises.
- name: Package the tool distribution
run: ./make-dist.sh
# Repo-relative: `defaults.run.working-directory` reaches `run` steps only.
- name: Upload test report on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: bal-library-tool-test-report
path: packages/bal-library-tool/native/build/reports/tests/test
retention-days: 7