Skip to content

Commit 0a1a113

Browse files
committed
feat(gha): add docker push github action
fixes #427
1 parent 6802cc6 commit 0a1a113

File tree

3 files changed

+347
-7
lines changed

3 files changed

+347
-7
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Build and Push Docker Image
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
release_tag:
9+
description: "Release tag to build and push"
10+
required: true
11+
12+
jobs:
13+
build-and-push:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read # Allows read access to the repository code
17+
packages: write # Allows pushing images to GitHub Container Registry
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Set up Docker Buildx
24+
uses: docker/setup-buildx-action@v3
25+
26+
- name: Log in to GitHub Container Registry
27+
uses: docker/login-action@v3
28+
with:
29+
registry: ghcr.io
30+
username: ${{ github.actor }}
31+
password: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- name: Determine the release tag
34+
id: get_tag
35+
run: |
36+
if [ "${{ github.event_name }}" == "release" ]; then
37+
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
38+
else
39+
echo "tag=${{ github.event.inputs.release_tag }}" >> $GITHUB_OUTPUT
40+
fi
41+
42+
- name: Build and push Docker image
43+
uses: docker/build-push-action@v6
44+
with:
45+
context: .
46+
push: true
47+
tags: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ steps.get_tag.outputs.tag }}
48+
# platforms: linux/arm64/v8,darwin/amd64,linux/amd64,windows/amd64,linux/amd64 # was what I was aiming for
49+
# but locally I only got to these 3 (specifically linux/arm64/v8 but yeah)
50+
platforms: linux/arm64,linux/amd64

Dockerfile

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,82 @@
1-
ARG DEBIAN_DIST=bullseye
1+
# syntax=docker/dockerfile:1.10
2+
# go to https://hub.docker.com/r/docker/dockerfile to see the latest version of the syntax
23

3-
FROM rust:${DEBIAN_DIST} as builder
4+
# Stage 1: Build the typos binary
5+
FROM rust:1.81.0-slim-bookworm AS builder
6+
7+
# Install musl-tools for static linking
8+
RUN apt-get update && \
9+
apt-get install -y --no-install-recommends \
10+
liblz4-tool \
11+
musl-tools \
12+
xz-utils \
13+
&& \
14+
rm -rf /var/lib/apt/lists/*
15+
16+
# some targets were not used in the end because rust package is not working with them
17+
# x86_64-pc-windows-msvc \
18+
19+
RUN rustup target add \
20+
aarch64-apple-darwin \
21+
aarch64-unknown-linux-musl \
22+
aarch64-unknown-linux-musl \
23+
x86_64-apple-darwin \
24+
x86_64-unknown-linux-musl \
25+
&& :
26+
27+
# Set the working directory
428
WORKDIR /usr/src/typos
29+
30+
# Copy the source code into the container
531
COPY . .
6-
RUN cargo install --path ./crates/typos-cli
732

8-
FROM debian:${DEBIAN_DIST}-slim
9-
COPY --from=builder /usr/local/cargo/bin/typos /usr/local/bin/typos
10-
ENTRYPOINT ["typos"]
11-
CMD ["--help"]
33+
# Set build arguments
34+
ARG TARGETPLATFORM
35+
ARG BIN_NAME=typos
36+
37+
# Determine the Rust target based on the platform
38+
# fingers crossed this build will just work
39+
# in case I need more platforms - https://github.com/containerd/containerd/blob/90cd777a6c8c92c105625ba086e2e67a0c32d7ed/platforms/platforms.go#L88-L94
40+
# elif [ "${TARGETPLATFORM}" = "windows/amd64" ]; then \
41+
# RUST_TARGET="x86_64-pc-windows-msvc"; \
42+
RUN --mount=type=cache,target=/usr/local/cargo/registry \
43+
--mount=type=cache,target=/usr/src/typos/target \
44+
set -xeEu \
45+
&& \
46+
ARM_PLATFORMS='linux/arm/v6 linux/arm/v7 linux/arm64/v8 linux/arm64' \
47+
&& \
48+
if [ "${TARGETPLATFORM}" = "darwin/arm64" ]; then \
49+
RUST_TARGET="aarch64-apple-darwin"; \
50+
elif printf '%s\n' ${ARM_PLATFORMS} | grep -Fxq "${TARGETPLATFORM}" ; then \
51+
RUST_TARGET="aarch64-unknown-linux-musl"; \
52+
elif [ "${TARGETPLATFORM}" = "darwin/amd64" ]; then \
53+
RUST_TARGET="x86_64-apple-darwin"; \
54+
elif [ "${TARGETPLATFORM}" = "linux/amd64" ]; then \
55+
RUST_TARGET="x86_64-unknown-linux-musl"; \
56+
else \
57+
echo "Unsupported TARGETPLATFORM: ${TARGETPLATFORM}"; \
58+
exit 1; \
59+
fi \
60+
&& \
61+
echo "Building for ${RUST_TARGET}" \
62+
&& \
63+
cargo build \
64+
--release \
65+
--verbose \
66+
--target ${RUST_TARGET} \
67+
&& \
68+
cp target/${RUST_TARGET}/release/${BIN_NAME} /usr/src/${BIN_NAME}/${BIN_NAME}
69+
70+
# Stage 2: Create the final image
71+
FROM scratch
72+
73+
# Set build arguments
74+
ARG BIN_NAME=typos
75+
76+
# Copy the statically linked binary from the builder stage
77+
COPY --from=builder /usr/src/typos/${BIN_NAME} /${BIN_NAME}
78+
79+
# Set the entrypoint to the typos binary
80+
# This was done to make the default run not scan the whole container for typos
81+
WORKDIR /workdir
82+
ENTRYPOINT ["/typos"]
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# Build and Push Docker Image Workflow Documentation
2+
3+
This document provides an overview and detailed explanation of the GitHub Actions workflow that automates the building and pushing of Docker images to the GitHub Container Registry (GHCR).
4+
5+
## Overview
6+
7+
The **Build and Push Docker Image** workflow is designed to:
8+
9+
- **Automate Docker Image Builds**: Whenever a new release is published or the workflow is manually triggered, the workflow builds a Docker image from your repository's code.
10+
- **Push to GitHub Container Registry**: The built Docker image is then pushed to GHCR, tagged appropriately for easy versioning and retrieval.
11+
- **Support Multiple Platforms**: The workflow is set up to build images for multiple platforms, ensuring broad compatibility.
12+
13+
## Workflow Triggers
14+
15+
The workflow is triggered in two scenarios:
16+
17+
1. **On Release Published**: Automatically runs when a new release is published in the repository.
18+
2. **Manual Trigger**: Can be manually triggered via the GitHub Actions tab, allowing you to specify a custom release tag.
19+
20+
## Workflow Details
21+
22+
### Name
23+
24+
- **Workflow Name**: `Build and Push Docker Image`
25+
26+
### Trigger Events
27+
28+
```yaml
29+
on:
30+
release:
31+
types: [published]
32+
workflow_dispatch:
33+
inputs:
34+
release_tag:
35+
description: "Release tag to build and push"
36+
required: true
37+
```
38+
39+
- **Release Published**: Listens for the `published` event on releases.
40+
- **Workflow Dispatch**: Allows manual triggering with an input `release_tag`.
41+
42+
### Permissions
43+
44+
```yaml
45+
permissions:
46+
contents: read # Allows read access to the repository code
47+
packages: write # Allows pushing images to GitHub Container Registry
48+
```
49+
50+
- **Contents**: Read access to fetch the repository code.
51+
- **Packages**: Write access to push Docker images to GHCR.
52+
53+
## Job Breakdown
54+
55+
### Job: `build-and-push`
56+
57+
#### Runs On
58+
59+
- **Environment**: `ubuntu-latest`
60+
61+
#### Steps
62+
63+
1. **Checkout Code**
64+
65+
```yaml
66+
- name: Checkout code
67+
uses: actions/checkout@v4
68+
```
69+
70+
- **Description**: Checks out the repository code so that the workflow can access it.
71+
72+
2. **Set Up Docker Buildx**
73+
74+
```yaml
75+
- name: Set up Docker Buildx
76+
uses: docker/setup-buildx-action@v3
77+
```
78+
79+
- **Description**: Sets up Docker Buildx for building multi-platform images.
80+
81+
3. **Log in to GitHub Container Registry**
82+
83+
```yaml
84+
- name: Log in to GitHub Container Registry
85+
uses: docker/login-action@v3
86+
with:
87+
registry: ghcr.io
88+
username: ${{ github.actor }}
89+
password: ${{ secrets.GITHUB_TOKEN }}
90+
```
91+
92+
- **Description**: Authenticates with GHCR using your GitHub credentials.
93+
94+
4. **Determine the Release Tag**
95+
96+
```yaml
97+
- name: Determine the release tag
98+
id: get_tag
99+
run: |
100+
if [ "${{ github.event_name }}" == "release" ]; then
101+
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
102+
else
103+
echo "tag=${{ github.event.inputs.release_tag }}" >> $GITHUB_OUTPUT
104+
fi
105+
```
106+
107+
- **Description**: Determines the Docker image tag:
108+
- If triggered by a release, uses the release tag.
109+
- If manually triggered, uses the provided `release_tag` input.
110+
111+
5. **Build and Push Docker Image**
112+
113+
```yaml
114+
- name: Build and push Docker image
115+
uses: docker/build-push-action@v6
116+
with:
117+
context: .
118+
push: true
119+
tags: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ steps.get_tag.outputs.tag }}
120+
platforms: linux/arm64,linux/amd64
121+
```
122+
123+
- **Description**: Builds and pushes the Docker image to GHCR for the specified platforms.
124+
125+
## Platforms
126+
127+
The workflow builds Docker images for the following platforms:
128+
129+
- **linux/arm64**
130+
- **linux/amd64**
131+
132+
**Note**: Initially, the aim was to build for additional platforms such as `darwin/amd64` and `windows/amd64`, but due to local limitations, the workflow currently builds for the platforms listed above.
133+
134+
## Requirements and Prerequisites
135+
136+
To effectively use this workflow, ensure the following:
137+
138+
- **Dockerfile**: A valid `Dockerfile` must be present at the root of your repository.
139+
- **GitHub Permissions**: The `GITHUB_TOKEN` provided by GitHub Actions must have the necessary permissions (default settings typically suffice).
140+
- **Understanding of Docker and GHCR**: Basic knowledge of Docker image building and pushing to GHCR will be beneficial.
141+
142+
## How to Use the Workflow
143+
144+
### Triggering the Workflow on Release
145+
146+
1. **Create a New Release**:
147+
148+
- Navigate to the "Releases" section of your repository.
149+
- Click on "Draft a new release".
150+
- Fill in the release details and publish it.
151+
152+
2. **Workflow Execution**:
153+
154+
- Upon publishing, the workflow automatically triggers.
155+
- It will build the Docker image using the release tag and push it to GHCR.
156+
157+
### Manually Triggering the Workflow
158+
159+
1. **Navigate to GitHub Actions**:
160+
161+
- Go to the "Actions" tab in your repository.
162+
163+
2. **Select the Workflow**:
164+
165+
- Find the **Build and Push Docker Image** workflow from the list.
166+
167+
3. **Run the Workflow**:
168+
169+
- Click on the "Run workflow" button.
170+
- Provide the required `release_tag` input when prompted.
171+
- Confirm to start the workflow.
172+
173+
4. **Workflow Execution**:
174+
175+
- The workflow uses the provided `release_tag` to build and push the Docker image.
176+
177+
## Accessing the Pushed Docker Image
178+
179+
The Docker image will be available at:
180+
181+
```
182+
ghcr.io/<repository_owner>/<repository_name>:<tag>
183+
```
184+
185+
Replace:
186+
187+
- `<repository_owner>`: Your GitHub username or organization name.
188+
- `<repository_name>`: The name of your repository.
189+
- `<tag>`: The release tag used during the build.
190+
191+
## Additional Notes
192+
193+
- **Customizing Platforms**: If you need to build for additional platforms, you can modify the `platforms` parameter in the workflow. Be cautious of compatibility and build environment limitations.
194+
- **Troubleshooting**:
195+
196+
- **Build Failures**: Check the workflow logs for detailed error messages.
197+
- **Authentication Issues**: Ensure that `GITHUB_TOKEN` has the necessary permissions.
198+
- **Dockerfile Errors**: Verify that your `Dockerfile` is correctly set up for multi-platform builds.
199+
200+
- **Security Considerations**:
201+
202+
- The `GITHUB_TOKEN` is scoped to the repository and should be kept secure.
203+
- Avoid echoing sensitive information in the workflow logs.
204+
205+
## Understanding the Workflow's Impact
206+
207+
By integrating this workflow:
208+
209+
- **Consistency**: Ensures that Docker images are consistently built and tagged with each release.
210+
- **Automation**: Reduces manual efforts in building and pushing Docker images.
211+
- **Version Control**: Leveraging release tags helps in maintaining versions of your Docker images aligned with your codebase.
212+
213+
## Conclusion
214+
215+
This workflow enhances your CI/CD pipeline by automating the Docker image build and push process. It is essential to familiarize yourself with its steps and requirements to leverage its full potential effectively. Should you have any questions or need further assistance, feel free to reach out or consult the GitHub Actions and Docker documentation.
216+
217+
---
218+
219+
*This documentation aims to provide a comprehensive understanding of the new workflow and the requirements it places on you. Ensure to review and customize any parts of the workflow to suit your specific needs.*

0 commit comments

Comments
 (0)