From e1b006de97fa2d9bbd42d9e7e27e0ff9e52ae5f4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 09:51:06 +0000 Subject: [PATCH 1/3] Initial plan From 8f3f9703ec8b237301d42cb175d5e21af81c7f34 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 09:58:54 +0000 Subject: [PATCH 2/3] feat: add Docker image CI workflow and Dockerfile - Dockerfile: multi-stage build (builder + slim runner) - Stage 1 builds all packages from source via bun + npx nx - Stage 2 copies built artifacts + node_modules, exposes adt via PATH - .github/workflows/docker.yml: triggers on push/tags/PRs, pushes to GHCR - .dockerignore: excludes node_modules, dist, .git, dev tooling Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com> --- .dockerignore | 44 ++++++++++++++++++++++++++++ .github/workflows/docker.yml | 56 ++++++++++++++++++++++++++++++++++++ Dockerfile | 43 +++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/workflows/docker.yml create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..585baee0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,44 @@ +# Build artifacts and caches +.nx/ +node_modules/ +**/node_modules/ +**/dist/ + +# Source control +.git/ +.gitmodules + +# CI/CD configuration (not needed inside the image) +.github/ +.gitlab-ci.yml + +# Dev tooling +.devcontainer/ +.vscode/ +.windsurf/ +.husky/ +.agents/ +.kilocode/ + +# Documentation and local scratch +docs/ +tmp/ + +# Lockfiles other than bun.lock (only bun.lock is used by the builder stage) +package-lock.json +yarn.lock +pnpm-lock.yaml + +# Miscellaneous +*.log +.prettierrc +.prettierignore +.nxignore +eslint.config.mjs +jest.config.ts +jest.preset.js +vitest.config.ts +knip.json +CHANGELOG.md +README.md +AGENTS.md diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..7f968ad5 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,56 @@ +name: Docker + +on: + push: + branches: + - main + tags: + - 'v*' + pull_request: + branches: + - main + +permissions: + contents: read + packages: write # needed to push to GHCR + +jobs: + docker: + name: Build and push Docker image + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..22c556b1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +# ── Stage 1: builder ───────────────────────────────────────────────────────── +# Installs all dependencies and builds every workspace package from source. +# Nothing is downloaded from the npm registry for @abapify/* packages. +FROM node:24-bookworm AS builder + +# Install bun (matches the version used in CI) +RUN npm install -g bun@1.2.9 + +WORKDIR /build + +# Copy workspace manifests first for better layer caching +COPY package.json bun.lock nx.json tsconfig.base.json tsconfig.json ./ + +# Copy all workspace members required for the build +COPY packages/ ./packages/ +COPY tools/ ./tools/ +COPY samples/ ./samples/ + +# Install all dependencies (including dev deps needed for the build) +RUN bun install --frozen-lockfile + +# Build every package (Nx respects the dependency graph, so output is correct) +RUN npx nx run-many -t build --all --parallel=4 + +# ── Stage 2: runner ────────────────────────────────────────────────────────── +# Lean image that ships only the built artifacts and their runtime deps. +# The adt CLI and all plugins are available without any npm registry access. +FROM node:24-bookworm-slim + +WORKDIR /app + +# Copy the built workspace packages (dist/ directories are now populated) +COPY --from=builder /build/packages ./packages +# Copy the workspace node_modules so @abapify/* symlinks resolve correctly +# and third-party runtime deps (commander, axios, etc.) are present +COPY --from=builder /build/node_modules ./node_modules +# Copy the root package.json so npm workspace resolution works at runtime +COPY --from=builder /build/package.json ./ + +# Expose workspace binaries (adt, adt-codegen, …) as global commands +ENV PATH="/app/node_modules/.bin:$PATH" + +CMD ["adt", "--help"] From 0cee55a0b6af0f1d9776f6f4b65685b2e289efed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 10:04:46 +0000 Subject: [PATCH 3/3] fix: restrict Docker image builds to releases only - docker.yml: replace push/PR triggers with workflow_dispatch + workflow_call (mirrors publish.yml pattern); always push; remove branch/PR tag types; fail if no release exists (remove main fallback) - release.yml: add docker job that calls docker.yml after release (same pattern as publish job), skipped on dry runs Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com> --- .github/workflows/docker.yml | 48 +++++++++++++++++++++++------------ .github/workflows/release.yml | 11 ++++++++ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7f968ad5..59d63ec6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,32 +1,50 @@ name: Docker on: - push: - branches: - - main - tags: - - 'v*' - pull_request: - branches: - - main - -permissions: - contents: read - packages: write # needed to push to GHCR + workflow_dispatch: + inputs: + version: + description: 'Release version tag to build (e.g. v1.2.3), defaults to latest release' + required: false + type: string + workflow_call: + inputs: + version: + description: 'Release version tag to build (e.g. v1.2.3), defaults to latest release' + required: false + type: string jobs: docker: name: Build and push Docker image runs-on: ubuntu-latest + permissions: + contents: read + packages: write # needed to push to GHCR steps: + - name: Resolve ref + id: resolve-ref + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + INPUT_VERSION: ${{ inputs.version }} + run: | + if [ -n "$INPUT_VERSION" ]; then + resolved="$INPUT_VERSION" + else + resolved=$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName -q .tagName) + fi + echo "Resolved ref: ${resolved}" + echo "ref=${resolved}" >> "$GITHUB_OUTPUT" + - name: Checkout repository uses: actions/checkout@v6 + with: + ref: ${{ steps.resolve-ref.outputs.ref }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GitHub Container Registry - if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ghcr.io @@ -39,8 +57,6 @@ jobs: with: images: ghcr.io/${{ github.repository }} tags: | - type=ref,event=branch - type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha @@ -49,7 +65,7 @@ jobs: uses: docker/build-push-action@v6 with: context: . - push: ${{ github.event_name != 'pull_request' }} + push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 716f3a54..4c62e446 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -101,3 +101,14 @@ jobs: permissions: contents: read id-token: write + + docker: + name: Build and push Docker image + needs: release + if: ${{ !inputs.dry_run }} + uses: ./.github/workflows/docker.yml + with: + version: ${{ needs.release.outputs.tag }} + permissions: + contents: read + packages: write