Skip to content

Commit a7be326

Browse files
authored
feat: add release pipeline and harden Dockerfile
1 parent 4db7a7a commit a7be326

9 files changed

Lines changed: 263 additions & 33 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: GPU Build Image
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- "[0-9]*"
9+
10+
permissions:
11+
id-token: write # Required for requesting the JWT token
12+
contents: read # Required for actions/checkout
13+
14+
jobs:
15+
build-image:
16+
uses: kyma-project/test-infra/.github/workflows/image-builder.yml@main
17+
with:
18+
tags: ${{ github.ref_name }}
19+
name: gpu
20+
dockerfile: Dockerfile
21+
export-tags: true
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: GPU Build Image PR
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, synchronize, reopened, ready_for_review, labeled]
6+
paths-ignore:
7+
- .github/workflows/stale.yml
8+
- docs/**
9+
10+
permissions:
11+
id-token: write # Required for requesting the JWT token
12+
contents: read # Required for actions/checkout
13+
14+
jobs:
15+
approve-image-build:
16+
if: ${{ contains(github.event.pull_request.labels.*.name, 'pr-build-image') }}
17+
environment: pr-image-build
18+
runs-on: ubuntu-latest
19+
steps:
20+
- run: echo "Build approved"
21+
22+
build-image:
23+
needs: approve-image-build
24+
uses: kyma-project/test-infra/.github/workflows/image-builder.yml@main
25+
with:
26+
name: gpu
27+
dockerfile: Dockerfile
28+
export-tags: true
29+
30+
local-build:
31+
name: Build Image Locally
32+
if: ${{ !contains(github.event.pull_request.labels.*.name, 'pr-build-image') }}
33+
runs-on: ubuntu-latest
34+
steps:
35+
- name: Checkout PR head
36+
uses: actions/checkout@v4
37+
with:
38+
ref: ${{ github.event.pull_request.head.sha }}
39+
40+
- name: Set up Docker Buildx
41+
uses: docker/setup-buildx-action@v3
42+
43+
- name: Build Image Locally
44+
uses: docker/build-push-action@v6
45+
with:
46+
context: .
47+
outputs: type=cacheonly
48+
push: false
49+
tags: gpu:${{ github.event.pull_request.head.sha }}

.github/workflows/pr-build-image.yml

Lines changed: 0 additions & 26 deletions
This file was deleted.

.github/workflows/release.yml

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Version to release - bare semver without 'v' (e.g. 0.1.0)"
8+
required: true
9+
type: string
10+
ref:
11+
description: "Branch, tag, or SHA to release from"
12+
required: true
13+
default: "main"
14+
type: string
15+
16+
concurrency:
17+
group: release-${{ inputs.version }}
18+
cancel-in-progress: false
19+
20+
env:
21+
IMAGE: europe-docker.pkg.dev/kyma-project/prod/gpu
22+
23+
jobs:
24+
validate:
25+
name: Validate
26+
runs-on: ubuntu-latest
27+
permissions:
28+
contents: read
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@v6
32+
with:
33+
ref: ${{ inputs.ref }}
34+
35+
- name: Check version format
36+
env:
37+
VERSION: ${{ inputs.version }}
38+
run: |
39+
if ! echo "${VERSION}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'; then
40+
echo "::error::version must be bare semver (e.g. 0.1.0 or 0.1.0-rc.1) - got '${VERSION}'"
41+
exit 1
42+
fi
43+
44+
- name: Check tag does not already exist
45+
env:
46+
VERSION: ${{ inputs.version }}
47+
run: |
48+
if git ls-remote --quiet --exit-code origin "refs/tags/${VERSION}" >/dev/null; then
49+
echo "::error::tag ${VERSION} already exists"
50+
exit 1
51+
fi
52+
53+
build-image:
54+
name: Build Image
55+
needs: validate
56+
permissions:
57+
id-token: write
58+
contents: read
59+
uses: kyma-project/test-infra/.github/workflows/image-builder.yml@main
60+
with:
61+
name: gpu
62+
dockerfile: Dockerfile
63+
context: .
64+
tags: ${{ inputs.version }}
65+
66+
test:
67+
name: Test
68+
needs: validate
69+
runs-on: ubuntu-latest
70+
permissions:
71+
contents: read
72+
steps:
73+
- name: Checkout
74+
uses: actions/checkout@v6
75+
with:
76+
ref: ${{ inputs.ref }}
77+
78+
- name: Setup Go
79+
uses: actions/setup-go@v6
80+
with:
81+
go-version-file: go.mod
82+
83+
- name: Build
84+
run: make build
85+
86+
- name: Test
87+
run: make test
88+
89+
create-tag:
90+
name: Create Tag
91+
needs: [build-image, test]
92+
runs-on: ubuntu-latest
93+
permissions:
94+
contents: write
95+
steps:
96+
- name: Checkout
97+
uses: actions/checkout@v6
98+
with:
99+
ref: ${{ inputs.ref }}
100+
fetch-depth: 0
101+
102+
- name: Configure git identity
103+
run: |
104+
git config user.name "github-actions[bot]"
105+
git config user.email "github-actions[bot]@users.noreply.github.com"
106+
107+
- name: Create and push annotated tag
108+
env:
109+
VERSION: ${{ inputs.version }}
110+
run: |
111+
git tag -a "${VERSION}" -m "Release ${VERSION}"
112+
git push origin "${VERSION}"
113+
114+
publish-release:
115+
name: Publish Release
116+
needs: create-tag
117+
runs-on: ubuntu-latest
118+
permissions:
119+
contents: write
120+
steps:
121+
- name: Checkout
122+
uses: actions/checkout@v6
123+
with:
124+
ref: ${{ inputs.ref }}
125+
fetch-depth: 0
126+
127+
- name: Setup Go
128+
uses: actions/setup-go@v6
129+
with:
130+
go-version-file: go.mod
131+
132+
- name: Render install.yaml
133+
env:
134+
VERSION: ${{ inputs.version }}
135+
run: |
136+
make build-installer IMG=${IMAGE}:${VERSION}
137+
138+
- name: Generate release notes
139+
env:
140+
VERSION: ${{ inputs.version }}
141+
REPOSITORY: ${{ github.repository }}
142+
run: |
143+
PREV_TAG=$(git describe --tags --abbrev=0 "${VERSION}^" 2>/dev/null || echo "")
144+
if [ -n "$PREV_TAG" ]; then
145+
CHANGES=$(git log "${PREV_TAG}..${VERSION}" \
146+
--pretty=format:"- %s (%h)" --no-merges)
147+
else
148+
CHANGES=$(git log --pretty=format:"- %s (%h)" --no-merges)
149+
fi
150+
{
151+
echo "## Changes"
152+
echo ""
153+
echo "${CHANGES}"
154+
echo ""
155+
echo "## Installation"
156+
echo ""
157+
echo '```bash'
158+
echo "# Install the GPU operator (CRD, RBAC, and controller)"
159+
echo "kubectl apply -f https://github.com/${REPOSITORY}/releases/download/${VERSION}/install.yaml"
160+
echo ""
161+
echo "# Create a Gpu resource to enable GPU support on your cluster"
162+
echo "kubectl apply -f https://github.com/${REPOSITORY}/releases/download/${VERSION}/instance.yaml"
163+
echo '```'
164+
echo ""
165+
echo "## Image"
166+
echo ""
167+
echo "\`${IMAGE}:${VERSION}\`"
168+
} > /tmp/release-notes.md
169+
170+
- name: Create GitHub Release
171+
env:
172+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
173+
VERSION: ${{ inputs.version }}
174+
run: |
175+
gh release create "${VERSION}" \
176+
--title "${VERSION}" \
177+
--notes-file /tmp/release-notes.md \
178+
dist/install.yaml \
179+
dist/instance.yaml

Dockerfile

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Build the manager binary
2-
FROM golang:1.25 AS builder
2+
FROM --platform=$BUILDPLATFORM golang:1.26.3 AS builder
33
ARG TARGETOS
44
ARG TARGETARCH
55

@@ -11,21 +11,25 @@ COPY go.sum go.sum
1111
# and so that source changes don't invalidate our downloaded layer
1212
RUN go mod download
1313

14-
# Copy the Go source (relies on .dockerignore to filter)
15-
COPY . .
14+
# Copy the go source
15+
COPY cmd/ cmd/
16+
COPY api/ api/
17+
COPY internal/ internal/
1618

1719
# Build
1820
# the GOARCH has no default value to allow the binary to be built according to the host where the command
1921
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
2022
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
2123
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
22-
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
24+
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} GOFIPS140=v1.0.0 go build -ldflags="-s -w" -o manager cmd/main.go
2325

2426
# Use distroless as minimal base image to package the manager binary
2527
# Refer to https://github.com/GoogleContainerTools/distroless for more details
2628
FROM gcr.io/distroless/static:nonroot
2729
WORKDIR /
28-
COPY --from=builder /workspace/manager .
30+
COPY --chown=65532:65532 --from=builder /workspace/manager .
2931
USER 65532:65532
3032

33+
ENV GODEBUG=fips140=only,tlsmlkem=0
34+
3135
ENTRYPOINT ["/manager"]

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ build-installer: manifests generate kustomize ## Generate a consolidated YAML wi
149149
mkdir -p dist
150150
cd config/manager && "$(KUSTOMIZE)" edit set image controller=${IMG}
151151
"$(KUSTOMIZE)" build config/default > dist/install.yaml
152+
cp config/samples/gpu_v1beta1_gpu.yaml dist/instance.yaml
152153

153154
##@ Deployment
154155

config/default/kustomization.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namePrefix: gpu-
1515
# someName: someValue
1616

1717
resources:
18-
#- ../crd
18+
- ../crd
1919
- ../rbac
2020
- ../manager
2121
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/kyma-project/gpu
22

3-
go 1.25.3
3+
go 1.26.3
44

55
require (
66
github.com/Masterminds/semver/v3 v3.4.0

sec-scanners-config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ mend:
88
language: golang-mod
99
exclude:
1010
- "**/*_test.go"
11+
- "**/test/**"
1112
checkmarx-one:
1213
preset: go-default
1314
exclude:
1415
- '**/*_test.go'
16+
- '**/test/**'

0 commit comments

Comments
 (0)