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
42 changes: 42 additions & 0 deletions .github/workflows/component-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ on:
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY:
required: false
description: 'Encryption key for Next.js Server Actions, this value is injected into the secrets of a docker image'
GH_ACTION_ACCESS_KEY_ID:
required: false
description: "AWS access key for the S3 cache bucket, used on ARC. Without it ARC builds use the GitHub cache."
GH_ACTION_SECRET_ACCESS_KEY:
required: false
description: "AWS secret key for the S3 cache bucket, used on ARC. Without it ARC builds use the GitHub cache."
outputs:
image-tag:
description: 'The image tag that was built'
Expand Down Expand Up @@ -186,6 +192,9 @@ jobs:
if: ${{ !inputs.use-blacksmith-runners || inputs.use-arc-runners }}
runs-on: ${{ needs.setup.outputs.runner }}
timeout-minutes: 30
env:
# On ARC the cache mounts go to S3 when the caller passes the bucket credentials, and the GitHub cache otherwise.
S3_CACHE: ${{ inputs.use-arc-runners && secrets.GH_ACTION_ACCESS_KEY_ID != '' }}
steps:
- name: Checkout
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
Expand All @@ -212,6 +221,39 @@ jobs:
# docker driver does not support cache-to).
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
# ARC builders start empty and the registry cache does not carry RUN --mount=type=cache
# contents (e.g. /root/.gradle), so persist them between builds.
- name: Restore Dockerfile cache mounts
id: cache-mounts
if: ${{ inputs.use-arc-runners && env.S3_CACHE != 'true' }}
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
with: &cache-mounts
path: buildkit-cache-mounts
key: buildkit-cache-mounts-${{ inputs.docker-file-name }}-${{ hashFiles('**/*.gradle.kts', '**/gradle.properties', 'gradle/libs.versions.toml', 'gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: |
buildkit-cache-mounts-${{ inputs.docker-file-name }}-
# The combined action, not restore/save: its post-step save must run after the
# cache-dance post step below has extracted the mounts from the builder.
- name: Restore Dockerfile cache mounts (S3)
id: cache-mounts-s3
if: ${{ env.S3_CACHE == 'true' }}
uses: runs-on/cache@88d90644011a3a9957fd141a106f5a94f9794203 # v5.0.7
env:
RUNS_ON_S3_BUCKET_CACHE: monta-github-ci-cache
RUNS_ON_RUNNER_NAME: ""
AWS_ACCESS_KEY_ID: ${{ secrets.GH_ACTION_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.GH_ACTION_SECRET_ACCESS_KEY }}
# Blank the ecr-put-image session exported by the credentials step above.
AWS_SESSION_TOKEN: ""
AWS_REGION: eu-west-1
with: *cache-mounts
- name: Inject Dockerfile cache mounts into the builder
if: ${{ inputs.use-arc-runners }}
uses: reproducible-containers/buildkit-cache-dance@5422eac04292c961a382e0f584ea0f03ad9da723 # v3.4.0
with:
dockerfile: ${{ inputs.docker-file-name }}
cache-dir: buildkit-cache-mounts
skip-extraction: ${{ steps.cache-mounts.outputs.cache-hit || steps.cache-mounts-s3.outputs.cache-hit }}
- name: Build and push
id: build
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/deploy-kotlin-v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ on:
LOKALISE_PROJECT_ID:
required: false
description: 'Lokalise project ID for Lokalise API'
GH_ACTION_ACCESS_KEY_ID:
required: false
description: "AWS access key for the S3 cache bucket, used on ARC. Without it ARC builds use the GitHub cache."
GH_ACTION_SECRET_ACCESS_KEY:
required: false
description: "AWS secret key for the S3 cache bucket, used on ARC. Without it ARC builds use the GitHub cache."
JIRA_EMAIL:
required: false
description: 'Email for JIRA API authentication (used for ticket operations in changelog)'
Expand Down Expand Up @@ -278,6 +284,8 @@ jobs:
AWS_CDN_SECRET_ACCESS_KEY: ${{ secrets.AWS_CDN_SECRET_ACCESS_KEY }}
LOKALISE_TOKEN: ${{ secrets.LOKALISE_TOKEN }}
LOKALISE_PROJECT_ID: ${{ secrets.LOKALISE_PROJECT_ID }}
GH_ACTION_ACCESS_KEY_ID: ${{ secrets.GH_ACTION_ACCESS_KEY_ID }}
GH_ACTION_SECRET_ACCESS_KEY: ${{ secrets.GH_ACTION_SECRET_ACCESS_KEY }}
deploy:
name: Deploy
needs:
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/deploy-kotlin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ on:
LOKALISE_PROJECT_ID:
required: false
description: 'Lokalise project ID for Lokalise API'
GH_ACTION_ACCESS_KEY_ID:
required: false
description: "AWS access key for the S3 cache bucket, used on ARC. Without it ARC builds use the GitHub cache."
GH_ACTION_SECRET_ACCESS_KEY:
required: false
description: "AWS secret key for the S3 cache bucket, used on ARC. Without it ARC builds use the GitHub cache."
JIRA_EMAIL:
required: false
description: 'Email for JIRA API authentication (used for ticket operations in changelog)'
Expand Down Expand Up @@ -266,6 +272,8 @@ jobs:
AWS_CDN_SECRET_ACCESS_KEY: ${{ secrets.AWS_CDN_SECRET_ACCESS_KEY }}
LOKALISE_TOKEN: ${{ secrets.LOKALISE_TOKEN }}
LOKALISE_PROJECT_ID: ${{ secrets.LOKALISE_PROJECT_ID }}
GH_ACTION_ACCESS_KEY_ID: ${{ secrets.GH_ACTION_ACCESS_KEY_ID }}
GH_ACTION_SECRET_ACCESS_KEY: ${{ secrets.GH_ACTION_SECRET_ACCESS_KEY }}
deploy:
name: Deploy
needs:
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- **Changes**: Added `use-arc-runners` to `deploy-kotlin(-v2)`, `component-test-kotlin` and `component-build`; added the `arc-job-report` composite action

## Recent Changes (2026-09-29)
1. **Dockerfile cache mounts persisted on ARC image builds**: when `use-arc-runners` is set, `component-build.yml`'s buildx job restores and saves `RUN --mount=type=cache` contents (all Kotlin service Dockerfiles mount `/root/.gradle` around `./gradlew buildLayers`) via `reproducible-containers/buildkit-cache-dance`, which finds the mounts by parsing the Dockerfile. ARC builders start empty and the ECR registry cache (`cache-to ... mode=max`) does not carry cache mounts, so without this every deploy re-downloads all Gradle dependencies straight from Maven Central (the in-Docker Gradle has neither the runner's CodeArtifact init script nor AWS credentials). Storage follows the PR workflows: `runs-on/cache` on S3 when the caller passes the `GH_ACTION_*` secrets (new optional secrets on `component-build` and `deploy-kotlin(-v2)`), `actions/cache` otherwise. It must be the combined `runs-on/cache`, not `restore`/`save`: cache-dance extracts in its post step, and only a post-step save runs after that. The S3 step blanks `AWS_SESSION_TOKEN`, because the job's `ecr-put-image` credentials are exported into the environment before it. Key: Dockerfile path + hash of the Gradle build files, with a prefix restore-key.
1. **`use-arc-runners` for the Kotlin deploy workflows**: `deploy-kotlin.yml` and `deploy-kotlin-v2.yml` accept `use-arc-runners` and pass it to `component-test-kotlin.yml` and `component-build.yml`, which both gained the input. Tests run on the converter's ARC runner, with Setup on `arc-arm64-2cpu-4gb` and `LC_ALL=C.UTF-8`, and keep `setup-java`'s GitHub-backed Gradle cache. The image build runs the existing `build-self-hosted` job (docker buildx + ECR registry layer cache, the ARC README's recommendation) instead of `build-blacksmith`. The deploy, service-profile, release-tag and changelog jobs never used Blacksmith and are unchanged. Callers that don't opt in are unaffected.
2. **`arc-job-report` action**: New composite action at `.github/actions/arc-job-report` that keeps one PR comment with each job's ARC runner, duration, peak memory and CPU, a table of suggested runner-size changes, and a per-run history (commit, wall time, slowest job). Callers run it from a `workflow_run` trigger on their PR workflow (so it reports on the finished run and adds no job to the PR checks) and pass `github-token` + `grafana-token` (e.g. `secrets.GRAFANA_CLOUD_TOKEN`) as inputs; no checkout needed, the action ships its scripts. `job_resources.py` is kube-manifests' `infra/arc/scripts/job-resources.py` plus a `GRAFANA_TOKEN` path through Grafana's datasource proxy (CI has no `gcx`); keep the two in sync. Metrics are scraped every 60 s, so jobs under 2 min are left out of the suggestions and jobs under 1 min show no CPU at all (`rate()` needs two samples); waiting does not help because the pod is deleted when the job ends. Only bot-authored comments are updated, so local `--dry-run` testing never collides with CI. Built and trialled in service-ocpi#2599.

Expand Down
2 changes: 1 addition & 1 deletion docs/workflow-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ jobs:
| `service-identifier` | Yes | - | Service identifier (e.g., "ocpp", "vehicle") |
| `runner-size` | No | "normal" | Runner size: "normal" or "large" |
| `use-blacksmith-runners` | No | true | Run on Blacksmith arm64 cloud runners (default). Set to false to run on self-hosted linux-arm64 |
| `use-arc-runners` | No | false | Run on the self-hosted ARC arm64 runners (`normal` → `arc-arm64-4cpu-12gb`, `large` → `arc-arm64-8cpu-24gb`); takes precedence over `use-blacksmith-runners`. Builds with docker buildx and the ECR registry layer cache. |
| `use-arc-runners` | No | false | Run on the self-hosted ARC arm64 runners (`normal` → `arc-arm64-4cpu-12gb`, `large` → `arc-arm64-8cpu-24gb`); takes precedence over `use-blacksmith-runners`. Builds with docker buildx and the ECR registry layer cache. Dockerfile `RUN --mount=type=cache` contents (e.g. `/root/.gradle`) are kept between builds: in S3 when the `GH_ACTION_*` secrets are passed, the GitHub cache otherwise. |
| `region` | No | "eu-west-1" | AWS region |
| `docker-file-name` | No | "Dockerfile" | Dockerfile name |
| `additional-build-args` | No | - | Additional Docker build arguments |
Expand Down
Loading