Skip to content

Commit cefb944

Browse files
committed
Add Docker image build and push to Azure Container Registry
- Added Docker support to reusable workflow for application releases - Configured ACR authentication using ACR_URL, ACR_USERNAME, and ACR_PASSWORD secrets - Automatic multi-stage Dockerfile generation if not present - Builds and pushes Docker images with version and latest tags - Updated Reframe release workflow to enable Docker builds - Updated documentation with ACR configuration requirements
1 parent abebf70 commit cefb944

3 files changed

Lines changed: 139 additions & 2 deletions

File tree

.github/workflows/release-reframe.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,10 @@ jobs:
1717
package-type: application
1818
skip-publish: true # Reframe is not published to crates.io
1919
dry-run: ${{ inputs.dry_run }}
20+
docker-enabled: true
21+
docker-image-name: reframe
2022
secrets:
21-
GH_PAT: ${{ secrets.GH_PAT }}
23+
GH_PAT: ${{ secrets.GH_PAT }}
24+
ACR_URL: ${{ secrets.ACR_URL }}
25+
ACR_USERNAME: ${{ secrets.ACR_USERNAME }}
26+
ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }}

.github/workflows/rust-release-reusable.yml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,31 @@ on:
2222
required: false
2323
type: boolean
2424
default: false
25+
docker-enabled:
26+
description: 'Enable Docker image build and push'
27+
required: false
28+
type: boolean
29+
default: false
30+
docker-image-name:
31+
description: 'Docker image name (defaults to package name)'
32+
required: false
33+
type: string
2534
secrets:
2635
GH_PAT:
2736
description: 'GitHub Personal Access Token for pushing tags'
2837
required: true
2938
CRATES_IO_TOKEN:
3039
description: 'Token for publishing to crates.io'
3140
required: false
41+
ACR_URL:
42+
description: 'Azure Container Registry URL (e.g., myregistry.azurecr.io)'
43+
required: false
44+
ACR_USERNAME:
45+
description: 'Azure Container Registry username (service principal ID or username)'
46+
required: false
47+
ACR_PASSWORD:
48+
description: 'Azure Container Registry password or token'
49+
required: false
3250

3351
env:
3452
CARGO_TERM_COLOR: always
@@ -181,6 +199,97 @@ jobs:
181199
182200
echo "Release artifacts packaged"
183201
202+
- name: Login to Azure Container Registry
203+
if: inputs.docker-enabled == true && inputs.dry-run != true
204+
run: |
205+
echo "Logging in to Azure Container Registry: ${{ secrets.ACR_URL }}"
206+
echo "${{ secrets.ACR_PASSWORD }}" | docker login "${{ secrets.ACR_URL }}" \
207+
--username "${{ secrets.ACR_USERNAME }}" \
208+
--password-stdin
209+
210+
- name: Create default Dockerfile if needed
211+
if: inputs.docker-enabled == true
212+
run: |
213+
if [ ! -f "Dockerfile" ]; then
214+
echo "Creating multi-stage Dockerfile for Rust application"
215+
cat > Dockerfile << 'DOCKERFILE_END'
216+
# Build stage
217+
FROM rust:1.75-slim as builder
218+
219+
WORKDIR /app
220+
221+
# Install build dependencies
222+
RUN apt-get update && apt-get install -y \
223+
pkg-config \
224+
libssl-dev \
225+
&& rm -rf /var/lib/apt/lists/*
226+
227+
# Copy manifests
228+
COPY Cargo.toml Cargo.lock ./
229+
230+
# Copy source code
231+
COPY src ./src
232+
233+
# Build release binary
234+
RUN cargo build --release
235+
236+
# Runtime stage
237+
FROM debian:bookworm-slim
238+
239+
# Install runtime dependencies
240+
RUN apt-get update && apt-get install -y \
241+
ca-certificates \
242+
libssl3 \
243+
&& rm -rf /var/lib/apt/lists/*
244+
245+
# Copy the binary from builder
246+
COPY --from=builder /app/target/release/${{ steps.package_info.outputs.name }} /usr/local/bin/${{ steps.package_info.outputs.name }}
247+
248+
# Create non-root user
249+
RUN useradd -m -u 1000 appuser && \
250+
chown appuser:appuser /usr/local/bin/${{ steps.package_info.outputs.name }}
251+
252+
USER appuser
253+
254+
ENTRYPOINT ["/usr/local/bin/${{ steps.package_info.outputs.name }}"]
255+
DOCKERFILE_END
256+
echo "Created default Dockerfile"
257+
else
258+
echo "Using existing Dockerfile"
259+
fi
260+
261+
- name: Build Docker image
262+
if: inputs.docker-enabled == true
263+
run: |
264+
IMAGE_NAME="${{ inputs.docker-image-name || steps.package_info.outputs.name }}"
265+
IMAGE_TAG="${{ steps.package_info.outputs.version }}"
266+
FULL_IMAGE="${{ secrets.ACR_URL }}/${IMAGE_NAME}:${IMAGE_TAG}"
267+
LATEST_IMAGE="${{ secrets.ACR_URL }}/${IMAGE_NAME}:latest"
268+
269+
echo "Building Docker image: ${FULL_IMAGE}"
270+
271+
# Build the Docker image
272+
docker build -t "${FULL_IMAGE}" -t "${LATEST_IMAGE}" .
273+
274+
echo "docker_image=${FULL_IMAGE}" >> $GITHUB_OUTPUT
275+
echo "docker_image_latest=${LATEST_IMAGE}" >> $GITHUB_OUTPUT
276+
277+
- name: Push Docker image to Azure Container Registry
278+
if: inputs.docker-enabled == true && inputs.dry-run != true
279+
run: |
280+
IMAGE_NAME="${{ inputs.docker-image-name || steps.package_info.outputs.name }}"
281+
IMAGE_TAG="${{ steps.package_info.outputs.version }}"
282+
FULL_IMAGE="${{ secrets.ACR_URL }}/${IMAGE_NAME}:${IMAGE_TAG}"
283+
LATEST_IMAGE="${{ secrets.ACR_URL }}/${IMAGE_NAME}:latest"
284+
285+
echo "Pushing Docker images to Azure Container Registry"
286+
docker push "${FULL_IMAGE}"
287+
docker push "${LATEST_IMAGE}"
288+
289+
echo "✅ Docker images pushed:"
290+
echo " - ${FULL_IMAGE}"
291+
echo " - ${LATEST_IMAGE}"
292+
184293
- name: Create GitHub Release
185294
if: steps.tag.outputs.exists != 'true'
186295
uses: softprops/action-gh-release@v2
@@ -285,4 +394,11 @@ jobs:
285394
echo "📦 Published to crates.io"
286395
fi
287396
echo "🏷️ Git tag: v${{ steps.package_info.outputs.version }}"
397+
398+
if [ "${{ inputs.docker-enabled }}" = "true" ]; then
399+
IMAGE_NAME="${{ inputs.docker-image-name || steps.package_info.outputs.name }}"
400+
echo "🐳 Docker images pushed to Azure Container Registry:"
401+
echo " - ${{ secrets.ACR_URL }}/${IMAGE_NAME}:${{ steps.package_info.outputs.version }}"
402+
echo " - ${{ secrets.ACR_URL }}/${IMAGE_NAME}:latest"
403+
fi
288404
fi

CLAUDE.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,15 @@ All workflows are manually triggered (workflow_dispatch) and include:
4141
- Creates GitHub releases with proper documentation
4242
- Publishes to crates.io (libraries only)
4343
- Packages binaries for applications
44+
- Docker image build and push to Azure Container Registry (optional for applications)
4445

45-
4. **Safety Features**:
46+
4. **Docker Support** (for applications):
47+
- Multi-stage Dockerfile generation if not present
48+
- Builds optimized Docker images with minimal runtime dependencies
49+
- Pushes images with version tag and 'latest' tag to Azure Container Registry
50+
- Non-root user execution for security
51+
52+
5. **Safety Features**:
4653
- Dry run option to test workflow without publishing
4754
- Version conflict detection
4855
- Automatic tag management
@@ -56,6 +63,15 @@ These secrets must be configured as organization-level secrets:
5663
- Required permissions: `repo` (full control of private repositories)
5764
- This is needed because the default GITHUB_TOKEN cannot push to other repositories
5865

66+
### Azure Container Registry (for Docker-enabled applications)
67+
68+
For applications that build and push Docker images to Azure Container Registry:
69+
70+
**Required Secrets:**
71+
- `ACR_URL` - Azure Container Registry URL (e.g., `myregistry.azurecr.io`)
72+
- `ACR_USERNAME` - Azure Container Registry username (service principal ID or admin username)
73+
- `ACR_PASSWORD` - Azure Container Registry password or access token
74+
5975
Note: `GITHUB_TOKEN` is auto-provided by GitHub but has limited permissions for cross-repo operations.
6076

6177
## Usage Instructions

0 commit comments

Comments
 (0)