Skip to content

Commit 7171e32

Browse files
authored
Merge pull request #37 from abapify/copilot/build-docker-image-ci-workflow
feat: restrict Docker image publishing to releases only
2 parents b79fe52 + 8524633 commit 7171e32

4 files changed

Lines changed: 170 additions & 0 deletions

File tree

.dockerignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Build artifacts and caches
2+
.nx/
3+
node_modules/
4+
**/node_modules/
5+
**/dist/
6+
7+
# Source control
8+
.git/
9+
.gitmodules
10+
11+
# CI/CD configuration (not needed inside the image)
12+
.github/
13+
.gitlab-ci.yml
14+
15+
# Dev tooling
16+
.devcontainer/
17+
.vscode/
18+
.windsurf/
19+
.husky/
20+
.agents/
21+
.kilocode/
22+
23+
# Documentation and local scratch
24+
docs/
25+
tmp/
26+
27+
# Lockfiles other than bun.lock (only bun.lock is used by the builder stage)
28+
package-lock.json
29+
yarn.lock
30+
pnpm-lock.yaml
31+
32+
# Miscellaneous
33+
*.log
34+
.prettierrc
35+
.prettierignore
36+
.nxignore
37+
eslint.config.mjs
38+
jest.config.ts
39+
jest.preset.js
40+
vitest.config.ts
41+
knip.json
42+
CHANGELOG.md
43+
README.md
44+
AGENTS.md

.github/workflows/docker.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Docker
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Release version tag to build (e.g. v1.2.3), defaults to latest release'
8+
required: false
9+
type: string
10+
workflow_call:
11+
inputs:
12+
version:
13+
description: 'Release version tag to build (e.g. v1.2.3), defaults to latest release'
14+
required: false
15+
type: string
16+
17+
jobs:
18+
docker:
19+
name: Build and push Docker image
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
packages: write # needed to push to GHCR
24+
steps:
25+
- name: Resolve ref
26+
id: resolve-ref
27+
env:
28+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29+
INPUT_VERSION: ${{ inputs.version }}
30+
run: |
31+
if [ -n "$INPUT_VERSION" ]; then
32+
resolved="$INPUT_VERSION"
33+
else
34+
resolved=$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName -q .tagName)
35+
fi
36+
echo "Resolved ref: ${resolved}"
37+
echo "ref=${resolved}" >> "$GITHUB_OUTPUT"
38+
39+
- name: Checkout repository
40+
uses: actions/checkout@v6
41+
with:
42+
ref: ${{ steps.resolve-ref.outputs.ref }}
43+
44+
- name: Set up Docker Buildx
45+
uses: docker/setup-buildx-action@v3
46+
47+
- name: Log in to GitHub Container Registry
48+
uses: docker/login-action@v3
49+
with:
50+
registry: ghcr.io
51+
username: ${{ github.actor }}
52+
password: ${{ secrets.GITHUB_TOKEN }}
53+
54+
- name: Extract Docker metadata
55+
id: meta
56+
uses: docker/metadata-action@v5
57+
with:
58+
images: ghcr.io/${{ github.repository }}
59+
tags: |
60+
type=semver,pattern={{version}}
61+
type=semver,pattern={{major}}.{{minor}}
62+
type=sha
63+
64+
- name: Build and push
65+
uses: docker/build-push-action@v6
66+
with:
67+
context: .
68+
push: true
69+
tags: ${{ steps.meta.outputs.tags }}
70+
labels: ${{ steps.meta.outputs.labels }}
71+
cache-from: type=gha
72+
cache-to: type=gha,mode=max

.github/workflows/release.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,14 @@ jobs:
101101
permissions:
102102
contents: read
103103
id-token: write
104+
105+
docker:
106+
name: Build and push Docker image
107+
needs: release
108+
if: ${{ !inputs.dry_run }}
109+
uses: ./.github/workflows/docker.yml
110+
with:
111+
version: ${{ needs.release.outputs.tag }}
112+
permissions:
113+
contents: read
114+
packages: write

Dockerfile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# ── Stage 1: builder ─────────────────────────────────────────────────────────
2+
# Installs all dependencies and builds every workspace package from source.
3+
# Nothing is downloaded from the npm registry for @abapify/* packages.
4+
FROM node:24-bookworm AS builder
5+
6+
# Install bun (matches the version used in CI)
7+
RUN npm install -g bun@1.2.9
8+
9+
WORKDIR /build
10+
11+
# Copy workspace manifests first for better layer caching
12+
COPY package.json bun.lock nx.json tsconfig.base.json tsconfig.json ./
13+
14+
# Copy all workspace members required for the build
15+
COPY packages/ ./packages/
16+
COPY tools/ ./tools/
17+
COPY samples/ ./samples/
18+
19+
# Install all dependencies (including dev deps needed for the build)
20+
RUN bun install --frozen-lockfile
21+
22+
# Build every package (Nx respects the dependency graph, so output is correct)
23+
RUN npx nx run-many -t build --all --parallel=4
24+
25+
# ── Stage 2: runner ──────────────────────────────────────────────────────────
26+
# Lean image that ships only the built artifacts and their runtime deps.
27+
# The adt CLI and all plugins are available without any npm registry access.
28+
FROM node:24-bookworm-slim
29+
30+
WORKDIR /app
31+
32+
# Copy the built workspace packages (dist/ directories are now populated)
33+
COPY --from=builder /build/packages ./packages
34+
# Copy the workspace node_modules so @abapify/* symlinks resolve correctly
35+
# and third-party runtime deps (commander, axios, etc.) are present
36+
COPY --from=builder /build/node_modules ./node_modules
37+
# Copy the root package.json so npm workspace resolution works at runtime
38+
COPY --from=builder /build/package.json ./
39+
40+
# Expose workspace binaries (adt, adt-codegen, …) as global commands
41+
ENV PATH="/app/node_modules/.bin:$PATH"
42+
43+
CMD ["adt", "--help"]

0 commit comments

Comments
 (0)