Skip to content

Commit b7a9e66

Browse files
feat(CI): add buildkitd-based reusable image build workflow
- Add _buildkitd_image_build.yaml reusable workflow that uses buildctl to connect to a buildkitd daemon in the K8s cluster for image building - Supports TLS-based authentication to the buildkitd daemon - Uses commit SHA as image tag (matching BuildKite BUILDKITE_COMMIT pattern) - Outputs vllm_image_tag for downstream test workflows to pull the image - Configurable runner, dockerfile, registry, and extra build args Signed-off-by: Wu Hejun <wuhejun@huawei.com> Signed-off-by: JavaPythonAIForBAT <wuhejun@h-partners.com>
1 parent ac4d54b commit b7a9e66

1 file changed

Lines changed: 172 additions & 0 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
name: Buildkitd Image Build
2+
on:
3+
workflow_call:
4+
inputs:
5+
image_name:
6+
description: 'Image name (e.g. vllm-ascend-ci-npu)'
7+
required: true
8+
type: string
9+
image_registry:
10+
description: 'Registry URL (e.g. swr.cn-southwest-2.myhuaweicloud.com/modelfoundry)'
11+
required: true
12+
type: string
13+
runner:
14+
description: 'Runner label (must have network access to buildkitd daemon)'
15+
required: false
16+
type: string
17+
default: 'linux-aarch64-a2b3-1'
18+
dockerfile:
19+
description: 'Dockerfile name (relative to dockerfile_dir)'
20+
required: false
21+
type: string
22+
default: 'Dockerfile.npu.ci'
23+
dockerfile_dir:
24+
description: 'Directory containing the Dockerfile (relative to repo root)'
25+
required: false
26+
type: string
27+
default: 'docker'
28+
context_dir:
29+
description: 'Build context directory (relative to repo root)'
30+
required: false
31+
type: string
32+
default: '.'
33+
vllm_ascend_branch:
34+
description: 'Branch/ref to checkout'
35+
required: false
36+
type: string
37+
default: 'main'
38+
buildkitd_addr:
39+
description: 'Buildkitd daemon address (e.g. tcp://buildkitd-service.buildkitd:1234)'
40+
required: false
41+
type: string
42+
default: 'tcp://buildkitd-service.buildkitd:1234'
43+
vllm_image_tag:
44+
description: 'Image tag override (defaults to commit SHA)'
45+
required: false
46+
type: string
47+
default: ''
48+
buildkit_version:
49+
description: 'Buildkit client version for download'
50+
required: false
51+
type: string
52+
default: 'v0.19.0'
53+
extra_build_args:
54+
description: 'Extra buildctl --opt key=value pairs (newline-separated)'
55+
required: false
56+
type: string
57+
default: ''
58+
outputs:
59+
image_tag:
60+
description: 'The full image tag pushed to registry (registry/name:tag)'
61+
value: ${{ jobs.build.outputs.image_tag }}
62+
vllm_image_tag:
63+
description: 'The commit-based tag used for pulling'
64+
value: ${{ jobs.build.outputs.vllm_image_tag }}
65+
secrets:
66+
BUILDKITD_CA:
67+
description: 'Base64-encoded buildkitd TLS CA cert (ca.pem)'
68+
required: true
69+
BUILDKITD_CERT:
70+
description: 'Base64-encoded buildkitd TLS client cert (cert.pem)'
71+
required: true
72+
BUILDKITD_KEY:
73+
description: 'Base64-encoded buildkitd TLS client key (key.pem)'
74+
required: true
75+
SWR_USERNAME:
76+
description: 'SWR registry username'
77+
required: true
78+
SWR_PASSWORD:
79+
description: 'SWR registry password'
80+
required: true
81+
82+
jobs:
83+
build:
84+
name: Build and push via buildkitd
85+
runs-on: ${{ inputs.runner }}
86+
outputs:
87+
image_tag: ${{ steps.resolve-tag.outputs.image_tag }}
88+
vllm_image_tag: ${{ steps.resolve-tag.outputs.vllm_image_tag }}
89+
steps:
90+
- uses: actions/checkout@v7
91+
with:
92+
fetch-depth: 0
93+
ref: ${{ inputs.vllm_ascend_branch }}
94+
95+
- name: Resolve image tag
96+
id: resolve-tag
97+
run: |
98+
if [ -n "${{ inputs.vllm_image_tag }}" ]; then
99+
TAG="${{ inputs.vllm_image_tag }}"
100+
else
101+
TAG="${{ github.sha }}"
102+
fi
103+
FULL_TAG="${{ inputs.image_registry }}/${{ inputs.image_name }}:${TAG}"
104+
echo "vllm_image_tag=${TAG}" >> $GITHUB_OUTPUT
105+
echo "image_tag=${FULL_TAG}" >> $GITHUB_OUTPUT
106+
echo "Tag: ${FULL_TAG}"
107+
108+
- name: Install buildctl
109+
run: |
110+
ARCH=$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')
111+
BUILDKIT_VERSION="${{ inputs.buildkit_version }}"
112+
URL="https://github.com/moby/buildkit/releases/download/${BUILDKIT_VERSION}/buildkit-${BUILDKIT_VERSION}.linux-${ARCH}.tar.gz"
113+
echo "Downloading buildctl from: ${URL}"
114+
curl -sSL "${URL}" | tar -xz -C /usr/local/bin --strip-components=1 bin/buildctl
115+
buildctl --version
116+
117+
- name: Setup TLS certs
118+
run: |
119+
CERT_DIR="${RUNNER_TEMP}/buildkitd-certs"
120+
mkdir -p "${CERT_DIR}"
121+
echo "${{ secrets.BUILDKITD_CA }}" | base64 -d > "${CERT_DIR}/ca.pem"
122+
echo "${{ secrets.BUILDKITD_CERT }}" | base64 -d > "${CERT_DIR}/cert.pem"
123+
echo "${{ secrets.BUILDKITD_KEY }}" | base64 -d > "${CERT_DIR}/key.pem"
124+
echo "CERT_DIR=${CERT_DIR}" >> $GITHUB_ENV
125+
126+
- name: Setup registry auth config.json
127+
run: |
128+
DOCKER_CONFIG_DIR="${RUNNER_TEMP}/docker-config"
129+
mkdir -p "${DOCKER_CONFIG_DIR}"
130+
echo "${{ secrets.SWR_PASSWORD }}" | \
131+
docker --config "${DOCKER_CONFIG_DIR}" login \
132+
-u "${{ secrets.SWR_USERNAME }}" --password-stdin \
133+
"${{ inputs.image_registry }}"
134+
echo "DOCKER_CONFIG_DIR=${DOCKER_CONFIG_DIR}" >> $GITHUB_ENV
135+
136+
- name: Build and push
137+
env:
138+
BUILDKITD_ADDR: ${{ inputs.buildkitd_addr }}
139+
run: |
140+
OPT_ARGS=""
141+
if [ -n "${{ inputs.extra_build_args }}" ]; then
142+
while IFS= read -r arg; do
143+
[ -n "$arg" ] && OPT_ARGS="$OPT_ARGS --opt $arg"
144+
done <<< "${{ inputs.extra_build_args }}"
145+
fi
146+
147+
export DOCKER_CONFIG="${DOCKER_CONFIG_DIR}"
148+
149+
IMAGE_FULL="${{ inputs.image_registry }}/${{ inputs.image_name }}:${{ steps.resolve-tag.outputs.vllm_image_tag }}"
150+
151+
buildctl \
152+
--addr="${BUILDKITD_ADDR}" \
153+
--tlscacert="${CERT_DIR}/ca.pem" \
154+
--tlscert="${CERT_DIR}/cert.pem" \
155+
--tlskey="${CERT_DIR}/key.pem" \
156+
build \
157+
--frontend dockerfile.v0 \
158+
--local context="${{ inputs.context_dir }}" \
159+
--local dockerfile="${{ inputs.dockerfile_dir }}" \
160+
--opt filename="${{ inputs.dockerfile }}" \
161+
--secret id=dockerconfig,src="${DOCKER_CONFIG_DIR}/config.json" \
162+
--output type=image,name="${IMAGE_FULL}",push=true \
163+
--progress=plain \
164+
${OPT_ARGS}
165+
166+
echo "Image pushed: ${IMAGE_FULL}"
167+
168+
- name: Cleanup
169+
if: always()
170+
run: |
171+
rm -rf "${CERT_DIR:-${RUNNER_TEMP}/buildkitd-certs}"
172+
rm -rf "${DOCKER_CONFIG_DIR:-${RUNNER_TEMP}/docker-config}"

0 commit comments

Comments
 (0)