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
6 changes: 6 additions & 0 deletions .github/workflows/agent-verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ on:
permissions:
contents: read
pull-requests: read

# PR runs supersede each other; main runs always finish so every merged commit is verified.
concurrency:
group: agent-verification-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
verify:
name: agent verification contract
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/apps-api-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches: [main]
paths:
- "apps/api/**"
- "packages/**"
- ".github/workflows/apps-api-ci.yml"
pull_request:
branches: [main]
Expand All @@ -16,6 +17,7 @@ concurrency:

permissions:
contents: read
pull-requests: read

jobs:
validate:
Expand Down Expand Up @@ -85,6 +87,7 @@ jobs:
filters: |
code:
- 'apps/api/**'
- 'packages/**'
- '.github/workflows/apps-api-ci.yml'

- name: Set up Bun
Expand Down Expand Up @@ -122,13 +125,10 @@ jobs:
if: steps.filter.outputs.code == 'true'
run: bun run check

- name: Tests
if: steps.filter.outputs.code == 'true'
env:
REQUIRE_INTEGRATION_DB: "true"
run: bun run test

- name: Test coverage report
# One run: test:coverage runs the same suite as `bun run test` (same
# preload, NODE_ENV, LOG_LEVEL, and the same forbidden-warning-output
# gate) and adds the coverage floor.
- name: Tests and coverage
if: steps.filter.outputs.code == 'true'
env:
REQUIRE_INTEGRATION_DB: "true"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-api-openapi-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ concurrency:

permissions:
contents: read
pull-requests: read

jobs:
drift:
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/apps-api-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ on:
tags: ["v*.*.*"]
paths:
- "apps/api/**"
- "packages/**"
- ".github/workflows/apps-api-release.yml"

concurrency:
Expand Down Expand Up @@ -72,6 +73,8 @@ jobs:
with:
context: apps/api
file: apps/api/Dockerfile.prod
build-contexts: |
packages=packages
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-api-security-deps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ concurrency:

permissions:
contents: read
pull-requests: read
security-events: write

jobs:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-api-security-spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ on:

permissions:
contents: read
pull-requests: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-docs-linkcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ on:

permissions:
contents: read
pull-requests: read

concurrency:
group: apps-docs-linkcheck-docs-${{ github.ref }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-docs-security-deps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ concurrency:

permissions:
contents: read
pull-requests: read
security-events: write

jobs:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-site-security-deps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ concurrency:

permissions:
contents: read
pull-requests: read
security-events: write

jobs:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-site-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ concurrency:

permissions:
contents: read
pull-requests: read

jobs:
validate:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-ui-bundle-diff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
filters: |
ui:
- 'apps/ui/src/**'
- 'packages/**'
- 'apps/ui/package.json'
- 'apps/ui/bun.lock'
- 'apps/ui/vite.config.ts'
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/apps-ui-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ on:
branches: [main]
paths:
- "apps/ui/**"
- "packages/**"
- ".github/workflows/apps-ui-release.yml"

concurrency:
Expand Down Expand Up @@ -108,6 +109,8 @@ jobs:
with:
context: apps/ui
file: apps/ui/Dockerfile.prod
build-contexts: |
packages=packages
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-ui-security-deps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ concurrency:

permissions:
contents: read
pull-requests: read
security-events: write

jobs:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/apps-ui-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ concurrency:

permissions:
contents: read
pull-requests: read

jobs:
validate:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/infra-bootstrap-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

permissions:
contents: read
pull-requests: read

concurrency:
group: infra-bootstrap-validate-${{ github.ref }}
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/infra-compose-full-stack-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ on:
- "infra/compose/**"
- "apps/api/**"
- "apps/ui/**"
- "packages/**"
- ".github/workflows/infra-compose-full-stack-smoke.yml"
# Intentionally no `paths:` filter on pull_request: this job is a required
# check in branch protection, and a path-filtered workflow that never runs
Expand All @@ -35,6 +36,7 @@ concurrency:

permissions:
contents: read
pull-requests: read

jobs:
smoke:
Expand All @@ -58,6 +60,7 @@ jobs:
code:
- 'apps/api/**'
- 'apps/ui/**'
- 'packages/**'
- 'infra/compose/**'
- '.github/workflows/infra-compose-full-stack-smoke.yml'

Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/infra-compose-validate-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ on:
# lockfile edits.
- "apps/api/**"
- "apps/ui/**"
- "packages/**"
pull_request:
branches: [main]

Expand All @@ -34,6 +35,7 @@ concurrency:

permissions:
contents: read
pull-requests: read

jobs:
compose-config:
Expand Down Expand Up @@ -478,8 +480,10 @@ jobs:
code:
# Dockerfile.prod runs COPY . .: the whole app tree is
# image input, so app-only source changes must rebuild too.
# It also COPYs the packages/ named context.
- 'apps/api/**'
- 'apps/ui/**'
- 'packages/**'
- 'infra/compose/**'
- '.github/workflows/infra-compose-validate-compose.yml'

Expand All @@ -493,6 +497,8 @@ jobs:
with:
context: apps/api
file: apps/api/Dockerfile.prod
build-contexts: |
packages=packages
push: false
load: true
tags: boringstack-api:pr-build
Expand All @@ -505,6 +511,8 @@ jobs:
with:
context: apps/ui
file: apps/ui/Dockerfile.prod
build-contexts: |
packages=packages
push: false
load: true
tags: boringstack-ui:pr-build
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/infra-k3s-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

permissions:
contents: read
pull-requests: read

concurrency:
group: infra-k3s-validate-${{ github.ref }}
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/production-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ jobs:
with:
context: apps/api
file: apps/api/Dockerfile.prod
build-contexts: |
packages=packages
push: true
tags: ghcr.io/${{ github.repository }}-api:candidate-${{ github.sha }}
labels: org.opencontainers.image.revision=${{ github.sha }}
Expand All @@ -82,6 +84,8 @@ jobs:
with:
context: apps/api
file: apps/api/Dockerfile.prod
build-contexts: |
packages=packages
target: migrations
push: true
tags: ghcr.io/${{ github.repository }}-migrations:candidate-${{ github.sha }}
Expand All @@ -94,6 +98,8 @@ jobs:
with:
context: apps/ui
file: apps/ui/Dockerfile.prod
build-contexts: |
packages=packages
push: true
tags: ghcr.io/${{ github.repository }}-ui:candidate-${{ github.sha }}
# Same-origin API by default. Public URL, Sentry and VAPID values come
Expand Down
2 changes: 2 additions & 0 deletions apps/api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_PRICE_ID_FREE=
STRIPE_PRICE_ID_PRO=
# Optional yearly price for the Pro plan. Empty = yearly checkout is not offered.
STRIPE_PRICE_ID_PRO_YEARLY=

# Queues (BullMQ) + cache. The VALKEY_* + provider keys are required
# only when the relevant feature flag is true. QUEUES_ENABLED must be
Expand Down
29 changes: 25 additions & 4 deletions apps/api/Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Multi-stage build for production. Plain `docker build` works — no BuildKit
# required. If you have BuildKit available, you can wrap the bun install
# RUN in `--mount=type=cache,target=/root/.bun/install/cache` for faster
# rebuilds; we keep the portable version here.
# Multi-stage build for production. Needs BuildKit (the default since Docker
# 23) for the `packages` named context: shared code under the repo's packages/
# directory. Build from apps/api with:
# docker build --build-context packages=../../packages -f Dockerfile.prod .
# Compose, the release workflows and the infra gate pass the same context.
FROM oven/bun:1.4.2-alpine@sha256:d888c0ae6c86d7866ff10c5aafdd9077b36aee6455b33dd270fb93c0dd5cef6f AS builder

WORKDIR /app
Expand All @@ -16,6 +17,16 @@ RUN bun install --frozen-lockfile --production

COPY . .

# Shared code from packages/ (BuildKit named context `packages`, see the header).
# The app reaches it as ../../packages from /app, so it lands at /packages.
COPY --from=packages . /packages
# Each shared package installs its own runtime dependencies, as
# apps/ui/docs/agents/shared-packages.md requires. Packages with none skip this.
RUN for pkg in /packages/*/; do \
[ -f "$pkg/package.json" ] || continue; \
(cd "$pkg" && bun install --production); \
done

# Builds the email-template JSONs into src/templates/email/dist/, then bundles
# the API into /app/dist. Both are needed at runtime.
RUN bun run build
Expand Down Expand Up @@ -48,6 +59,16 @@ COPY drizzle ./drizzle
COPY scripts/db ./scripts/db
COPY src ./src

# Shared code from packages/ (BuildKit named context `packages`, see the header).
# The app reaches it as ../../packages from /app, so it lands at /packages.
COPY --from=packages . /packages
# Each shared package installs its own runtime dependencies, as
# apps/ui/docs/agents/shared-packages.md requires. Packages with none skip this.
RUN for pkg in /packages/*/; do \
[ -f "$pkg/package.json" ] || continue; \
(cd "$pkg" && bun install --production); \
done

# Set after install so `bun install` above still sees devDependencies.
ENV NODE_ENV=production

Expand Down
Loading
Loading