diff --git a/.github/workflows/_bake-and-push.yml b/.github/workflows/_bake-and-push.yml index 30a280bb7..7421ee4ad 100644 --- a/.github/workflows/_bake-and-push.yml +++ b/.github/workflows/_bake-and-push.yml @@ -65,6 +65,14 @@ on: required: false PAYLOAD_SECRET: required: false + PAYLOAD_SECRET_KEY: + required: false + # Not a genuine secret (Sentry DSNs are inlined into the public client + # bundle by design) but plumbed as one because it's stored as a GitHub + # Secret today; going through --mount=type=secret keeps it unlogged + # without needing a GitHub Variable migration. + NEXT_PUBLIC_SENTRY_DSN: + required: false SENTRY_AUTH_TOKEN: required: false SENTRY_ORG: @@ -126,6 +134,8 @@ jobs: BUILD_DATE: ${{ steps.meta.outputs.date }} DATABASE_URL: ${{ secrets.DATABASE_URL }} PAYLOAD_SECRET: ${{ secrets.PAYLOAD_SECRET }} + PAYLOAD_SECRET_KEY: ${{ secrets.PAYLOAD_SECRET_KEY }} + NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_ORG: ${{ secrets.SENTRY_ORG }} SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} diff --git a/.github/workflows/_build-charterafrica.yml b/.github/workflows/_build-charterafrica.yml new file mode 100644 index 000000000..74c99d92a --- /dev/null +++ b/.github/workflows/_build-charterafrica.yml @@ -0,0 +1,79 @@ +name: Reusable Build | charterAFRICA + +on: + workflow_call: + inputs: + tag: + required: true + type: string + description: "Image tag to build or push" + push: + required: true + type: boolean + description: "Whether to push the built image to the registry" + base_tag: + required: true + type: string + description: "Published base image tag to build from" + app_url: + required: true + type: string + description: "NEXT_PUBLIC_APP_URL baked into the client bundle (public, not a secret)" + sentry_environment: + required: true + type: string + description: "Sentry environment baked into the app" + seo_disabled: + required: false + type: string + default: "true" + description: "NEXT_PUBLIC_SEO_DISABLED baked into the client bundle" + set: + required: false + type: string + default: "" + description: "Additional bake --set overrides" + secrets: + DOCKER_HUB_USERNAME: + required: false + DOCKER_HUB_ACCESS_TOKEN: + required: false + DATABASE_URL: + required: false + PAYLOAD_SECRET_KEY: + required: false + NEXT_PUBLIC_SENTRY_DSN: + required: false + SENTRY_AUTH_TOKEN: + required: false + SENTRY_ORG: + required: false + SENTRY_PROJECT: + required: false + +jobs: + build: + permissions: + actions: read + contents: read + uses: ./.github/workflows/_bake-and-push.yml + with: + target: charterafrica + target_os: '["ubuntu-24.04-arm"]' + base_tag: ${{ inputs.base_tag }} + tag: ${{ inputs.tag }} + push: ${{ inputs.push }} + set: | + charterafrica.args.NEXT_PUBLIC_APP_URL=${{ inputs.app_url }} + charterafrica.args.SENTRY_ENVIRONMENT=${{ inputs.sentry_environment }} + charterafrica.args.NEXT_PUBLIC_SEO_DISABLED=${{ inputs.seo_disabled }} + ${{ inputs.set }} + secrets: + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + DATABASE_URL: ${{ secrets.DATABASE_URL }} + PAYLOAD_SECRET_KEY: ${{ secrets.PAYLOAD_SECRET_KEY }} + NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} diff --git a/.github/workflows/charterafrica.yml b/.github/workflows/charterafrica.yml new file mode 100644 index 000000000..19ecf5e27 --- /dev/null +++ b/.github/workflows/charterafrica.yml @@ -0,0 +1,136 @@ +name: charterAFRICA + +on: + push: + branches: + - main + paths: + - "apps/charterafrica/**" + - "docker/apps/charterafrica/**" + - "docker-bake.hcl" + - ".github/workflows/_bake-and-push.yml" + - ".github/workflows/_build-charterafrica.yml" + - ".github/workflows/charterafrica.yml" + +permissions: + actions: read + contents: read + +concurrency: + group: "${{ github.workflow }} @ ${{ github.ref }}" + cancel-in-progress: true + +jobs: + # Checks whether apps/charterafrica/package.json has a version bump. + # The prod build/deploy is gated on this; dev builds on every push. + version-check: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-24.04] + permissions: + contents: read + outputs: + changed: ${{ steps.check.outputs.changed }} + version: ${{ steps.check.outputs.version }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - uses: actions/setup-node@v6 + with: + node-version-file: "package.json" + + - name: Check if version is bumped + id: check + uses: EndBug/version-check@v3 + with: + diff-search: true + file-name: apps/charterafrica/package.json + + # Builds the DEV image and pushes it to DockerHub on every push. Matches + # the pre-bake workflow this replaces: there's no DEV Dokku app for + # charterafrica yet, so this only validates and publishes the image. + # + # Required GitHub Secrets: + # CHARTERAFRICA_MONGO_URL, CHARTERAFRICA_PAYLOAD_SECRET_KEY, + # CHARTERAFRICA_SENTRY_DSN, CHARTERAFRICA_SENTRY_PROJECT, + # SENTRY_AUTH_TOKEN, SENTRY_ORG, UI_BASE_TAG (var) + build-dev: + permissions: + actions: read + contents: read + uses: ./.github/workflows/_build-charterafrica.yml + with: + base_tag: ${{ vars.UI_BASE_TAG }} + tag: ${{ github.sha }} + push: true + app_url: "https://charterafrica.dev.codeforafrica.org" + sentry_environment: development + secrets: + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + DATABASE_URL: ${{ secrets.CHARTERAFRICA_MONGO_URL }} + PAYLOAD_SECRET_KEY: ${{ secrets.CHARTERAFRICA_PAYLOAD_SECRET_KEY }} + NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.CHARTERAFRICA_SENTRY_DSN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.CHARTERAFRICA_SENTRY_PROJECT }} + + # TODO: No DEV Dokku app exists for charterafrica yet. + # Enable this job (remove `if: false`) when the app is created on ui-1.dev + # and update the git_remote_url below. + deploy-dev: + if: false + needs: build-dev + permissions: {} + uses: ./.github/workflows/push-to-dokku.yml + with: + git_remote_url: "ssh://azureuser@ui-1.dev.codeforafrica.org/charterafrica-ui" + deploy_docker_image: "codeforafrica/charterafrica:${{ github.sha }}" + secrets: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + + # Builds the PROD image only when the package.json version is bumped, + # using the PROD canonical URL and the semver tag. + build-prod: + needs: version-check + if: needs.version-check.outputs.changed == 'true' + permissions: + actions: read + contents: read + uses: ./.github/workflows/_build-charterafrica.yml + with: + base_tag: ${{ vars.UI_BASE_TAG }} + tag: ${{ needs.version-check.outputs.version }} + push: true + app_url: "https://charter.africa" + sentry_environment: production + seo_disabled: "false" + set: | + charterafrica.tags+=codeforafrica/charterafrica:latest + secrets: + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + DATABASE_URL: ${{ secrets.CHARTERAFRICA_MONGO_URL }} + PAYLOAD_SECRET_KEY: ${{ secrets.CHARTERAFRICA_PAYLOAD_SECRET_KEY }} + NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.CHARTERAFRICA_SENTRY_DSN }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.CHARTERAFRICA_SENTRY_PROJECT }} + + # TODO: No PROD Dokku app exists for charterafrica yet either — confirm + # whether it should point to a different server (e.g. a different AWS + # account) before enabling this, matching the pre-bake workflow's own + # unresolved TODO. + deploy-prod: + if: false + needs: [version-check, build-prod] + permissions: {} + uses: ./.github/workflows/push-to-dokku.yml + with: + git_remote_url: "ssh://dokku@ui-1.prod.codeforafrica.org/charterafrica-ui" + deploy_docker_image: "codeforafrica/charterafrica:${{ needs.version-check.outputs.version }}" + secrets: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index 4cbd931fc..5ff19bfce 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -4,10 +4,12 @@ on: pull_request: types: [opened, synchronize, reopened, ready_for_review] paths: + - "apps/charterafrica/**" - "apps/pesayetu/**" - "apps/roboshield/**" - "apps/techlabblog/**" - "apps/trustlab/**" + - "docker/apps/charterafrica/**" - "docker/apps/pesayetu/**" - "docker/apps/roboshield/**" - "docker/apps/techlabblog/**" @@ -22,10 +24,12 @@ on: - "scripts/pr-build-targets.mjs" - "scripts/pr-build-targets.test.mjs" - ".github/workflows/_bake-and-push.yml" + - ".github/workflows/_build-charterafrica.yml" - ".github/workflows/_build-pesayetu.yml" - ".github/workflows/_build-roboshield.yml" - ".github/workflows/_build-techlabblog.yml" - ".github/workflows/_build-trustlab.yml" + - ".github/workflows/charterafrica.yml" - ".github/workflows/pesayetu.yml" - ".github/workflows/pr-build.yml" - ".github/workflows/roboshield.yml" @@ -99,6 +103,32 @@ jobs: --base "${{ github.event.pull_request.base.sha }}" \ --head "${{ github.event.pull_request.head.sha }}" + build-charterafrica: + name: Build charterafrica image + needs: affected + if: ${{ contains(fromJSON(needs.affected.outputs.targets), 'charterafrica') }} + permissions: + actions: read + contents: read + uses: ./.github/workflows/_build-charterafrica.yml + with: + base_tag: ${{ vars.UI_BASE_TAG }} + tag: pr-${{ github.event.pull_request.number }}-${{ github.sha }} + push: false + app_url: "http://localhost:3000" + sentry_environment: ci + secrets: + # The custom server connects to MongoDB via payload.init() before + # spawning `next build`, so — like the other Payload-backed migrated + # apps — PR builds need a genuinely reachable database, not a dummy + # value. + DATABASE_URL: ${{ secrets.CHARTERAFRICA_MONGO_URL }} + PAYLOAD_SECRET_KEY: pr-build-unused + NEXT_PUBLIC_SENTRY_DSN: pr-build-unused + SENTRY_AUTH_TOKEN: pr-build-unused + SENTRY_ORG: pr-build-unused + SENTRY_PROJECT: pr-build-unused + build-pesayetu: name: Build pesayetu image needs: affected diff --git a/Makefile b/Makefile index 82c8e6ef5..279207511 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ COMPOSE_BUILD_ENV=BUILDKIT_PROGRESS=plain .PHONY: charterafrica civicsignalblog climatemappedafrica codeforafrica down mongodb mongodb-keyfile pesayetu roboshield techlabblog trustlab twoopstracker vpnmanager charterafrica: - ./scripts/dc.sh charterafrica + ./scripts/bake-up.sh charterafrica civicsignalblog: ./scripts/dc.sh civicsignalblog diff --git a/apps/charterafrica/.env.template b/apps/charterafrica/.env.template index cd0a39b15..11a27cb9a 100644 --- a/apps/charterafrica/.env.template +++ b/apps/charterafrica/.env.template @@ -1,6 +1,6 @@ # Required # -------- -MONGO_URL +DATABASE_URL PAYLOAD_CORS PAYLOAD_CSRF diff --git a/apps/charterafrica/migrate-mongo-config.js b/apps/charterafrica/migrate-mongo-config.js index 8f85a69be..dae13f12d 100644 --- a/apps/charterafrica/migrate-mongo-config.js +++ b/apps/charterafrica/migrate-mongo-config.js @@ -3,7 +3,7 @@ require("dotenv").config({ path: "./.env" }); const config = { mongodb: { - url: process.env.MONGO_URL, + url: process.env.DATABASE_URL, options: { useNewUrlParser: true, useUnifiedTopology: true, diff --git a/apps/charterafrica/payload.config.ts b/apps/charterafrica/payload.config.ts index f4f4a0915..62a701225 100644 --- a/apps/charterafrica/payload.config.ts +++ b/apps/charterafrica/payload.config.ts @@ -82,7 +82,7 @@ export default buildConfig({ admin: "/admin", }, db: mongooseAdapter({ - url: process.env.MONGO_URL, + url: process.env.DATABASE_URL, migrationDir: process.env.MIGRATIONS_DIR, }), collections: [ diff --git a/apps/charterafrica/turbo.json b/apps/charterafrica/turbo.json index 9a11f8dd4..ff28aee9d 100644 --- a/apps/charterafrica/turbo.json +++ b/apps/charterafrica/turbo.json @@ -8,7 +8,7 @@ "outputs": [".next/**", "!.next/cache/**", "dist/**"], "env": [ "AIRTABLE_API_TOKEN", - "MONGO_URL", + "DATABASE_URL", "NEXT_BUILD", "NEXT_HOSTNAME", "NEXT_MANUAL_SIG_HANDLE", @@ -41,8 +41,8 @@ "env": [ "AIRTABLE_API_TOKEN", "CHARTERAFRICA_SENTRY_DSN", + "DATABASE_URL", "GOOGLE_API_KEY", - "MONGO_URL", "NEXT_BUILD", "NEXT_HOSTNAME", "NODE_ENV", diff --git a/docker-bake.hcl b/docker-bake.hcl index 25d39aa79..a66e8fd2b 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -71,7 +71,7 @@ group "base" { } group "apps" { - targets = ["pesayetu", "roboshield", "techlabblog", "trustlab"] + targets = ["charterafrica", "pesayetu", "roboshield", "techlabblog", "trustlab"] } # Prefer explicit targets/groups for predictability. @@ -160,6 +160,25 @@ target "_payload-app-runner" { ] } +target "charterafrica" { + inherits = ["_app-runner"] + dockerfile = "docker/apps/charterafrica/Dockerfile" + tags = ["${REGISTRY}charterafrica:${TAG}"] + args = { + NEXT_PUBLIC_APP_URL = "${NEXT_PUBLIC_APP_URL}" + SENTRY_ENVIRONMENT = "${SENTRY_ENVIRONMENT}" + } + # sentry_auth_token/org/project are inherited from _app. database_url, + # payload_secret_key, and next_public_sentry_dsn are charterafrica-specific + # — it reads PAYLOAD_SECRET_KEY (not PAYLOAD_SECRET like _payload-app-runner + # provides), so this declares its own secret list rather than inheriting it. + secret = [ + "type=env,id=database_url,env=DATABASE_URL", + "type=env,id=payload_secret_key,env=PAYLOAD_SECRET_KEY", + "type=env,id=next_public_sentry_dsn,env=NEXT_PUBLIC_SENTRY_DSN", + ] +} + # pesayetu fetches content from WordPress (WPGraphQL) during static generation, # so these are real build args, not just runtime config. They default to empty # so the image still builds without them; pages that depend on WordPress data diff --git a/docker-compose.yml b/docker-compose.yml index 4f9928b9e..5d4031956 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,6 @@ services: charterafrica: - build: - secrets: - - mongo_url - - payload_secret - - sentry_auth_token - - sentry_org - - sentry_project - - payload_secret_key - context: . - target: charterafrica-runner - args: - - SENTRY_ENVIRONMENT=${SENTRY_ENVIRONMENT} + image: codeforafrica/charterafrica:${TAG:-local} env_file: - path: ./apps/charterafrica/.env - path: ./apps/charterafrica/.env.local diff --git a/docker/README.md b/docker/README.md index 946f8c76d..a914baf2e 100644 --- a/docker/README.md +++ b/docker/README.md @@ -17,7 +17,7 @@ container/deploy metadata tied to the image rather than the application code. Apps checked below have migrated to the per-app Dockerfile pattern under `docker/apps//`. Unchecked apps still use the root `Dockerfile`. -- [ ] `charterafrica` +- [x] `charterafrica` - [ ] `civicsignalblog` - [ ] `climatemappedafrica` - [ ] `codeforafrica` diff --git a/docker/apps/charterafrica/Dockerfile b/docker/apps/charterafrica/Dockerfile new file mode 100644 index 000000000..000ed095d --- /dev/null +++ b/docker/apps/charterafrica/Dockerfile @@ -0,0 +1,86 @@ +# syntax=docker/dockerfile:1 + +# ui_builder_base / ui_runner_base: Docker named context references use underscores +# because hyphens are invalid in context names. The bake targets are still named +# ui-builder-base and ui-runner-base — only the FROM reference uses underscores. +FROM ui_builder_base AS pruned + +COPY . . + +# turbo is pre-installed in ui-builder-base — no network call needed here. +RUN turbo prune --docker --out-dir /workspace/out charterafrica + +FROM ui_builder_base AS deps + +COPY --from=pruned /workspace/out/json/ ./ +COPY --from=pruned /workspace/out/pnpm-lock.yaml ./ + +RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store,sharing=shared \ + pnpm install --frozen-lockfile + +FROM ui_builder_base AS builder + +ARG NEXT_PUBLIC_APP_URL \ + NEXT_PUBLIC_SEO_DISABLED="true" \ + SENTRY_ENVIRONMENT + +ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL} \ + NEXT_PUBLIC_SEO_DISABLED=${NEXT_PUBLIC_SEO_DISABLED} \ + SENTRY_ENVIRONMENT=${SENTRY_ENVIRONMENT} + +COPY --from=deps /workspace/node_modules ./node_modules +COPY --from=deps /workspace/apps/charterafrica/node_modules ./apps/charterafrica/node_modules +# turbo WARNs when lockfile is missing during build +COPY --from=pruned /workspace/out/pnpm-lock.yaml ./pnpm-lock.yaml +COPY --from=pruned /workspace/out/full/ ./ + +# Payload's admin panel needs a serverURL at build time; the real value is +# supplied at runtime via Dokku config, not baked into the image. +ENV PAYLOAD_PUBLIC_APP_URL=http://localhost:3000 + +# NEXT_PUBLIC_SENTRY_DSN is inlined into the client bundle by webpack, but +# mounted as a BuildKit secret (rather than a plain ARG/GitHub Variable) so +# it stays unlogged without needing a GitHub Variable migration — it's +# stored as a GitHub Secret today even though DSNs aren't actually sensitive. +RUN --mount=type=secret,id=database_url,env=DATABASE_URL \ + --mount=type=secret,id=payload_secret_key,env=PAYLOAD_SECRET_KEY \ + --mount=type=secret,id=next_public_sentry_dsn,env=NEXT_PUBLIC_SENTRY_DSN \ + --mount=type=secret,id=sentry_auth_token,env=SENTRY_AUTH_TOKEN \ + --mount=type=secret,id=sentry_org,env=SENTRY_ORG \ + --mount=type=secret,id=sentry_project,env=SENTRY_PROJECT \ + pnpm --filter './apps/charterafrica' build:next + +ENV PAYLOAD_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL} +RUN pnpm --filter './apps/charterafrica' build-payload + +FROM ui_runner_base AS runner + +ARG NEXT_PUBLIC_SEO_DISABLED + +ENV NEXT_PUBLIC_SEO_DISABLED=${NEXT_PUBLIC_SEO_DISABLED} + +RUN set -ex \ + && mkdir -p ./apps/charterafrica/.next \ + && chown nextjs:nodejs ./apps/charterafrica/.next + +# charterafrica doesn't use output: "standalone", so the full node_modules +# and .next folder (not just the standalone bundle) are needed at runtime. +COPY --from=builder --chown=nextjs:nodejs /workspace/node_modules ./node_modules +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/node_modules ./apps/charterafrica/node_modules +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/next.config.js ./apps/charterafrica/next.config.js +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/.env ./apps/charterafrica/.env +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/migrations ./apps/charterafrica/migrations +# app.json's `cron` config runs scripts/ecosystem.mjs via Dokku's cron plugin +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/app.json ./apps/charterafrica/app.json +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/scripts ./apps/charterafrica/scripts +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/public ./apps/charterafrica/public +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/.next ./apps/charterafrica/.next +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/dist ./apps/charterafrica/dist +COPY --from=builder --chown=nextjs:nodejs /workspace/apps/charterafrica/build ./apps/charterafrica/build + +WORKDIR /workspace/apps/charterafrica + +USER nextjs + +# Custom server to run Payload and Next.js in the same app +CMD ["node", "dist/server.js"] diff --git a/scripts/pr-build-targets.mjs b/scripts/pr-build-targets.mjs index fdda874c1..1957583ea 100644 --- a/scripts/pr-build-targets.mjs +++ b/scripts/pr-build-targets.mjs @@ -11,6 +11,12 @@ import { fileURLToPath } from "node:url"; // - Non-workspace build inputs are handled explicitly because Turbo cannot map // them through the workspace graph. export const BUILD_TARGET_CONFIG = { + charterafrica: { + directBuildInputPaths: [ + ".github/workflows/charterafrica.yml", + "docker/apps/charterafrica/", + ], + }, pesayetu: { directBuildInputPaths: [ ".github/workflows/pesayetu.yml", @@ -40,6 +46,7 @@ export const BUILD_TARGET_CONFIG = { const GLOBAL_BUILD_FILES = new Set([ ".github/workflows/_bake-and-push.yml", + ".github/workflows/_build-charterafrica.yml", ".github/workflows/_build-pesayetu.yml", ".github/workflows/_build-roboshield.yml", ".github/workflows/_build-techlabblog.yml", diff --git a/scripts/pr-build-targets.test.mjs b/scripts/pr-build-targets.test.mjs index 1a645b525..43548c441 100644 --- a/scripts/pr-build-targets.test.mjs +++ b/scripts/pr-build-targets.test.mjs @@ -22,12 +22,13 @@ describe("pr-build-targets", () => { it("maps direct build input paths to candidate build targets", () => { assert.deepEqual( directBuildTargets([ + "docker/apps/charterafrica/Dockerfile", "docker/apps/pesayetu/Dockerfile", "docker/apps/roboshield/Dockerfile", "docker/apps/techlabblog/Dockerfile", ".github/workflows/trustlab.yml", ]), - ["pesayetu", "roboshield", "techlabblog", "trustlab"], + ["charterafrica", "pesayetu", "roboshield", "techlabblog", "trustlab"], ); });