Skip to content

Commit 37c6f59

Browse files
pierre-bclaude
andcommitted
Add GitHub Actions CI/CD workflows
- go.yml: Run unit tests on push/PR to main - docker.yml: Run integration tests, build and push to Docker Hub - Integration tests run against actual Docker container - Push to Docker Hub on main branch and version tags - Multi-platform builds (amd64, arm64) - Update compose.yaml to use Docker Hub image 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 0264843 commit 37c6f59

File tree

3 files changed

+204
-3
lines changed

3 files changed

+204
-3
lines changed

.github/workflows/docker.yml

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
name: Docker Build, Test and Push
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags:
7+
- "v*.*"
8+
- "latest"
9+
pull_request:
10+
branches: [main]
11+
12+
env:
13+
REGISTRY: docker.io
14+
IMAGE_NAME: notifuse/selfhost_s3
15+
16+
jobs:
17+
integration-tests:
18+
name: Integration Tests
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Go
26+
uses: actions/setup-go@v5
27+
with:
28+
go-version: "1.23"
29+
cache: true
30+
31+
- name: Set up Docker Buildx
32+
uses: docker/setup-buildx-action@v3
33+
34+
- name: Build Docker image for testing
35+
uses: docker/build-push-action@v5
36+
with:
37+
context: .
38+
file: ./Dockerfile
39+
push: false
40+
load: true
41+
tags: selfhost_s3:test
42+
cache-from: type=gha
43+
cache-to: type=gha,mode=max
44+
45+
- name: Start selfhost_s3 container
46+
run: |
47+
docker run -d \
48+
--name selfhost_s3-test \
49+
-p 9000:9000 \
50+
-e S3_BUCKET=test-bucket \
51+
-e S3_ACCESS_KEY=testkey \
52+
-e S3_SECRET_KEY=testsecret \
53+
-e S3_PORT=9000 \
54+
-e S3_REGION=us-east-1 \
55+
selfhost_s3:test
56+
57+
- name: Wait for selfhost_s3 to be ready
58+
run: |
59+
echo "Waiting for selfhost_s3 to be ready..."
60+
for i in {1..30}; do
61+
if curl -f http://localhost:9000/health > /dev/null 2>&1; then
62+
echo "selfhost_s3 is ready!"
63+
break
64+
fi
65+
echo "Waiting for selfhost_s3... ($i/30)"
66+
sleep 2
67+
done
68+
# Final check
69+
curl -f http://localhost:9000/health || exit 1
70+
71+
- name: Run integration tests
72+
env:
73+
INTEGRATION_TEST_ENDPOINT: http://localhost:9000
74+
INTEGRATION_TEST_BUCKET: test-bucket
75+
INTEGRATION_TEST_ACCESS_KEY: testkey
76+
INTEGRATION_TEST_SECRET_KEY: testsecret
77+
INTEGRATION_TEST_REGION: us-east-1
78+
run: |
79+
go test -race -timeout=5m ./integration/... -v
80+
81+
- name: Show container logs on failure
82+
if: failure()
83+
run: docker logs selfhost_s3-test
84+
85+
- name: Cleanup
86+
if: always()
87+
run: docker rm -f selfhost_s3-test || true
88+
89+
build-and-push:
90+
name: Build and Push
91+
runs-on: ubuntu-latest
92+
needs: integration-tests
93+
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main')
94+
permissions:
95+
contents: read
96+
packages: write
97+
id-token: write
98+
attestations: write
99+
100+
steps:
101+
- name: Checkout repository
102+
uses: actions/checkout@v4
103+
with:
104+
fetch-depth: 0
105+
106+
- name: Get git commit info
107+
id: git-info
108+
run: |
109+
echo "commit-sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
110+
echo "commit-short-sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
111+
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
112+
echo "tag-name=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
113+
else
114+
echo "tag-name=latest" >> $GITHUB_OUTPUT
115+
fi
116+
117+
- name: Set up Docker Buildx
118+
uses: docker/setup-buildx-action@v3
119+
120+
- name: Log in to Docker Hub
121+
uses: docker/login-action@v3
122+
with:
123+
username: ${{ secrets.DOCKERHUB_USERNAME }}
124+
password: ${{ secrets.DOCKERHUB_TOKEN }}
125+
126+
- name: Extract metadata
127+
id: meta
128+
uses: docker/metadata-action@v5
129+
with:
130+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
131+
tags: |
132+
type=ref,event=tag
133+
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || github.ref_name == 'latest' }}
134+
labels: |
135+
org.opencontainers.image.revision=${{ steps.git-info.outputs.commit-sha }}
136+
org.opencontainers.image.version=${{ steps.git-info.outputs.tag-name }}
137+
138+
- name: Build and push Docker image
139+
id: build
140+
uses: docker/build-push-action@v5
141+
with:
142+
context: .
143+
file: ./Dockerfile
144+
push: true
145+
tags: ${{ steps.meta.outputs.tags }}
146+
labels: ${{ steps.meta.outputs.labels }}
147+
platforms: linux/amd64,linux/arm64
148+
cache-from: type=gha
149+
cache-to: type=gha,mode=max
150+
151+
- name: Generate artifact attestation
152+
if: steps.build.outputs.digest != ''
153+
uses: actions/attest-build-provenance@v1
154+
with:
155+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
156+
subject-digest: ${{ steps.build.outputs.digest }}
157+
push-to-registry: true
158+
159+
- name: Output image details
160+
run: |
161+
echo "🚀 Docker image successfully built and pushed!"
162+
echo "📦 Registry: ${{ env.REGISTRY }}"
163+
echo "🏷️ Image: ${{ env.IMAGE_NAME }}"
164+
echo "🔖 Tags: ${{ steps.meta.outputs.tags }}"
165+
echo "📝 Git commit: ${{ steps.git-info.outputs.commit-short-sha }}"
166+
echo "🔗 Build URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"

.github/workflows/go.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Go
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
unit-tests:
11+
name: Unit Tests
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Go
19+
uses: actions/setup-go@v5
20+
with:
21+
go-version: "1.23"
22+
cache: true
23+
24+
- name: Install dependencies
25+
run: go mod download
26+
27+
- name: Run unit tests
28+
run: |
29+
# Run unit tests (exclude integration tests)
30+
go test -race -coverprofile=coverage.txt -covermode=atomic $(go list ./... | grep -v '/integration') -v
31+
32+
- name: Upload coverage to Codecov
33+
uses: codecov/codecov-action@v5
34+
with:
35+
token: ${{ secrets.CODECOV_TOKEN }}
36+
files: coverage.txt
37+
fail_ci_if_error: false
38+
verbose: true

compose.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ name: selfhost_s3
22

33
services:
44
selfhost_s3:
5-
build:
6-
context: .
7-
dockerfile: Dockerfile
85
image: notifuse/selfhost_s3:latest
96
container_name: selfhost_s3
107
restart: unless-stopped

0 commit comments

Comments
 (0)