Skip to content

Commit 9441cec

Browse files
committed
Add PR CI
1 parent 6e8c340 commit 9441cec

File tree

2 files changed

+228
-22
lines changed

2 files changed

+228
-22
lines changed
Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
name: Build and Push Docker Image
22

33
on:
4+
# Trigger manually from Actions tab
5+
workflow_dispatch:
6+
inputs:
7+
tag:
8+
description: 'Docker image tag (e.g., latest, v1.0.0, dev)'
9+
required: true
10+
default: 'latest'
11+
# Trigger on version tags
412
push:
5-
branches:
6-
- main
713
tags:
814
- 'v*.*.*'
9-
pull_request:
10-
branches:
11-
- main
1215

1316
env:
1417
REGISTRY: docker.io
@@ -31,42 +34,59 @@ jobs:
3134
uses: docker/setup-buildx-action@v3
3235

3336
- name: Log in to Docker Hub
34-
if: github.event_name != 'pull_request'
3537
uses: docker/login-action@v3
3638
with:
3739
username: ${{ secrets.DOCKERHUB_USERNAME }}
3840
password: ${{ secrets.DOCKERHUB_TOKEN }}
3941

40-
- name: Extract metadata (tags, labels) for Docker
41-
id: meta
42-
uses: docker/metadata-action@v5
43-
with:
44-
images: ${{ env.IMAGE_NAME }}
45-
tags: |
46-
type=ref,event=branch
47-
type=ref,event=pr
48-
type=semver,pattern={{version}}
49-
type=semver,pattern={{major}}.{{minor}}
50-
type=semver,pattern={{major}}
51-
type=raw,value=latest,enable={{is_default_branch}}
42+
- name: Determine Docker tags
43+
id: tags
44+
run: |
45+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
46+
# Manual trigger - use provided tag
47+
echo "tags=${{ secrets.DOCKERHUB_USERNAME }}/zeropay:${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
48+
elif [ "${{ github.ref_type }}" = "tag" ]; then
49+
# Version tag push - extract version
50+
VERSION=${GITHUB_REF#refs/tags/v}
51+
MAJOR=$(echo $VERSION | cut -d. -f1)
52+
MINOR=$(echo $VERSION | cut -d. -f2)
53+
echo "tags=${{ secrets.DOCKERHUB_USERNAME }}/zeropay:latest,${{ secrets.DOCKERHUB_USERNAME }}/zeropay:$VERSION,${{ secrets.DOCKERHUB_USERNAME }}/zeropay:$MAJOR.$MINOR,${{ secrets.DOCKERHUB_USERNAME }}/zeropay:$MAJOR" >> $GITHUB_OUTPUT
54+
else
55+
# Fallback
56+
echo "tags=${{ secrets.DOCKERHUB_USERNAME }}/zeropay:latest" >> $GITHUB_OUTPUT
57+
fi
5258
5359
- name: Build and push Docker image
5460
id: build
5561
uses: docker/build-push-action@v5
5662
with:
5763
context: .
5864
platforms: linux/amd64,linux/arm64
59-
push: ${{ github.event_name != 'pull_request' }}
60-
tags: ${{ steps.meta.outputs.tags }}
61-
labels: ${{ steps.meta.outputs.labels }}
65+
push: true
66+
tags: ${{ steps.tags.outputs.tags }}
67+
labels: |
68+
org.opencontainers.image.source=${{ github.repositoryUrl }}
69+
org.opencontainers.image.revision=${{ github.sha }}
6270
cache-from: type=gha
6371
cache-to: type=gha,mode=max
6472

6573
- name: Generate artifact attestation
66-
if: github.event_name != 'pull_request'
6774
continue-on-error: true
6875
uses: actions/attest-build-provenance@v1
6976
with:
7077
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
7178
subject-digest: ${{ steps.build.outputs.digest }}
7279
push-to-registry: true
80+
81+
- name: Output summary
82+
run: |
83+
echo "### Docker Build Summary :rocket:" >> $GITHUB_STEP_SUMMARY
84+
echo "" >> $GITHUB_STEP_SUMMARY
85+
echo "**Image pushed to:** \`${{ steps.tags.outputs.tags }}\`" >> $GITHUB_STEP_SUMMARY
86+
echo "**Platforms:** linux/amd64, linux/arm64" >> $GITHUB_STEP_SUMMARY
87+
echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
88+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
89+
echo "**Tag:** ${{ github.event.inputs.tag }}" >> $GITHUB_STEP_SUMMARY
90+
elif [ "${{ github.ref_type }}" = "tag" ]; then
91+
echo "**Version:** ${GITHUB_REF#refs/tags/}" >> $GITHUB_STEP_SUMMARY
92+
fi

.github/workflows/pr-check.yml

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
name: Pull Request Checks
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
- develop
8+
pull_request_target:
9+
types: [opened, synchronize, reopened]
10+
11+
env:
12+
CARGO_TERM_COLOR: always
13+
RUST_BACKTRACE: 1
14+
15+
jobs:
16+
# Check code formatting
17+
format-check:
18+
name: Code Formatting
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Install Rust
25+
uses: dtolnay/rust-toolchain@stable
26+
with:
27+
components: rustfmt
28+
29+
- name: Check formatting
30+
run: cargo fmt --all -- --check
31+
32+
# Run Clippy linter
33+
clippy:
34+
name: Clippy Lints
35+
runs-on: ubuntu-latest
36+
steps:
37+
- name: Checkout code
38+
uses: actions/checkout@v4
39+
40+
- name: Install Rust
41+
uses: dtolnay/rust-toolchain@stable
42+
with:
43+
components: clippy
44+
45+
- name: Cache cargo registry
46+
uses: actions/cache@v3
47+
with:
48+
path: ~/.cargo/registry
49+
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
50+
51+
- name: Cache cargo index
52+
uses: actions/cache@v3
53+
with:
54+
path: ~/.cargo/git
55+
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
56+
57+
- name: Cache cargo build
58+
uses: actions/cache@v3
59+
with:
60+
path: target
61+
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
62+
63+
- name: Run Clippy
64+
run: cargo clippy --all-targets --all-features -- -D warnings
65+
66+
# Run tests
67+
test:
68+
name: Tests
69+
runs-on: ubuntu-latest
70+
services:
71+
postgres:
72+
image: postgres:16-alpine
73+
env:
74+
POSTGRES_DB: zeropay_test
75+
POSTGRES_USER: postgres
76+
POSTGRES_PASSWORD: postgres
77+
ports:
78+
- 5432:5432
79+
options: >-
80+
--health-cmd pg_isready
81+
--health-interval 10s
82+
--health-timeout 5s
83+
--health-retries 5
84+
85+
redis:
86+
image: redis:7-alpine
87+
ports:
88+
- 6379:6379
89+
options: >-
90+
--health-cmd "redis-cli ping"
91+
--health-interval 10s
92+
--health-timeout 5s
93+
--health-retries 5
94+
95+
steps:
96+
- name: Checkout code
97+
uses: actions/checkout@v4
98+
99+
- name: Install Rust
100+
uses: dtolnay/rust-toolchain@stable
101+
102+
- name: Install system dependencies
103+
run: |
104+
sudo apt-get update
105+
sudo apt-get install -y pkg-config libssl-dev
106+
107+
- name: Cache cargo registry
108+
uses: actions/cache@v3
109+
with:
110+
path: ~/.cargo/registry
111+
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
112+
113+
- name: Cache cargo index
114+
uses: actions/cache@v3
115+
with:
116+
path: ~/.cargo/git
117+
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
118+
119+
- name: Cache cargo build
120+
uses: actions/cache@v3
121+
with:
122+
path: target
123+
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
124+
125+
- name: Run tests
126+
env:
127+
DATABASE_URL: postgres://postgres:postgres@localhost:5432/zeropay_test
128+
REDIS_URL: redis://localhost:6379
129+
run: cargo test --verbose --all
130+
131+
# Security audit
132+
security-audit:
133+
name: Security Audit
134+
runs-on: ubuntu-latest
135+
steps:
136+
- name: Checkout code
137+
uses: actions/checkout@v4
138+
139+
- name: Install Rust
140+
uses: dtolnay/rust-toolchain@stable
141+
142+
- name: Install cargo-audit
143+
run: cargo install cargo-audit
144+
145+
- name: Run security audit
146+
run: cargo audit
147+
148+
# Summary check - all must pass
149+
pr-check-summary:
150+
name: PR Check Summary
151+
runs-on: ubuntu-latest
152+
needs: [format-check, clippy, test, security-audit]
153+
if: always()
154+
steps:
155+
- name: Check all jobs status
156+
run: |
157+
if [[ "${{ needs.format-check.result }}" != "success" ]] || \
158+
[[ "${{ needs.clippy.result }}" != "success" ]] || \
159+
[[ "${{ needs.test.result }}" != "success" ]] || \
160+
[[ "${{ needs.security-audit.result }}" != "success" ]]; then
161+
echo "❌ One or more checks failed"
162+
exit 1
163+
else
164+
echo "✅ All checks passed"
165+
fi
166+
167+
- name: Comment on PR
168+
if: github.event_name == 'pull_request'
169+
uses: actions/github-script@v7
170+
with:
171+
script: |
172+
const status = '${{ needs.format-check.result }}' === 'success' &&
173+
'${{ needs.clippy.result }}' === 'success' &&
174+
'${{ needs.test.result }}' === 'success' &&
175+
'${{ needs.security-audit.result }}' === 'success';
176+
177+
const body = status
178+
? '✅ All PR checks passed! Ready for review.'
179+
: '❌ Some PR checks failed. Please review the workflow logs.';
180+
181+
github.rest.issues.createComment({
182+
issue_number: context.issue.number,
183+
owner: context.repo.owner,
184+
repo: context.repo.repo,
185+
body: body
186+
});

0 commit comments

Comments
 (0)