Skip to content

Commit 58a76ea

Browse files
authored
Merge pull request #960 from OWASP/copilot/fix-959
Add GitHub preview action for automated container builds and deployment instructions
2 parents dde2438 + 4498afa commit 58a76ea

File tree

4 files changed

+292
-1
lines changed

4 files changed

+292
-1
lines changed

.github/workflows/preview.yml

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
--- # yamllint disable rule:line-length
2+
name: "Preview Deployment"
3+
4+
on:
5+
pull_request:
6+
types: [opened, synchronize, reopened]
7+
push:
8+
branches: [main]
9+
10+
permissions:
11+
contents: read
12+
packages: write
13+
pull-requests: write
14+
15+
env:
16+
REGISTRY: ghcr.io
17+
IMAGE_PREFIX: ghcr.io/${{ github.repository_owner }}
18+
19+
jobs:
20+
set-tag:
21+
name: "Determine Tag"
22+
runs-on: ubuntu-latest
23+
outputs:
24+
tag: ${{ steps.set-tag.outputs.tag }}
25+
steps:
26+
- name: Set output tag
27+
id: set-tag
28+
run: |
29+
if [ "${{ github.event_name }}" == "pull_request" ]; then
30+
echo "tag=pr-${{ github.event.number }}" >> $GITHUB_OUTPUT
31+
else
32+
echo "tag=${{ github.ref_name }}" >> $GITHUB_OUTPUT
33+
fi
34+
35+
build-and-publish:
36+
name: "Build and Publish Preview Images"
37+
runs-on: ubuntu-latest
38+
needs: set-tag
39+
strategy:
40+
matrix:
41+
component:
42+
- wrongsecrets-balancer
43+
- cleaner
44+
steps:
45+
- name: Checkout
46+
uses: actions/checkout@v5
47+
48+
- name: Set up Docker Buildx
49+
uses: docker/setup-buildx-action@v3
50+
51+
- name: Log in to Container Registry
52+
uses: docker/login-action@v3
53+
with:
54+
registry: ${{ env.REGISTRY }}
55+
username: ${{ github.actor }}
56+
password: ${{ secrets.GITHUB_TOKEN }}
57+
58+
- name: Generate metadata
59+
id: meta
60+
uses: docker/metadata-action@v5
61+
with:
62+
images: ${{ env.IMAGE_PREFIX }}/${{ matrix.component }}
63+
tags: |
64+
type=raw,value=${{ needs.set-tag.outputs.tag }}
65+
66+
- name: Build and push
67+
uses: docker/build-push-action@v6
68+
with:
69+
context: ./${{ matrix.component }}
70+
file: ./${{ matrix.component }}/Dockerfile
71+
push: true
72+
tags: ${{ steps.meta.outputs.tags }}
73+
labels: ${{ steps.meta.outputs.labels }}
74+
platforms: linux/amd64,linux/arm64
75+
76+
generate-preview-instructions:
77+
name: "Generate Preview Instructions"
78+
runs-on: ubuntu-latest
79+
needs: [set-tag, build-and-publish]
80+
if: github.event_name == 'pull_request'
81+
steps:
82+
- name: Checkout
83+
uses: actions/checkout@v5
84+
85+
- name: Install yq
86+
run: |
87+
sudo snap install yq
88+
89+
- name: Generate preview values
90+
id: values
91+
run: |
92+
# Create a preview values file
93+
cat > preview-values.yaml << EOF
94+
balancer:
95+
repository: ${{ env.IMAGE_PREFIX }}/wrongsecrets-balancer
96+
tag: ${{ needs.set-tag.outputs.tag }}
97+
98+
wrongsecretsCleanup:
99+
repository: ${{ env.IMAGE_PREFIX }}/cleaner
100+
tag: ${{ needs.set-tag.outputs.tag }}
101+
102+
# Preview configuration
103+
ingress:
104+
enabled: true
105+
hosts:
106+
- host: >-
107+
preview-${{ needs.set-tag.outputs.tag }}.wrongsecrets.local
108+
paths:
109+
- "/"
110+
EOF
111+
112+
# Output the content for use in the comment
113+
echo "values<<EOF" >> $GITHUB_OUTPUT
114+
cat preview-values.yaml >> $GITHUB_OUTPUT
115+
echo "EOF" >> $GITHUB_OUTPUT
116+
117+
- name: Create deployment instructions
118+
id: instructions
119+
run: |
120+
# yamllint disable rule:line-length
121+
cat > instructions.md << 'EOF'
122+
## 🚀 Preview Deployment Ready!
123+
124+
Your pull request has been built and is ready for preview deployment.
125+
Here's how to test your changes:
126+
127+
### Container Images Built
128+
129+
- **Balancer**: `${{ env.IMAGE_PREFIX }}/wrongsecrets-balancer:${{ needs.set-tag.outputs.tag }}`
130+
- **Cleaner**: `${{ env.IMAGE_PREFIX }}/cleaner:${{ needs.set-tag.outputs.tag }}`
131+
132+
### Quick Deploy with Helm
133+
134+
```bash
135+
# Add the wrongsecrets helm repository
136+
helm repo add wrongsecrets https://owasp.org/wrongsecrets-ctf-party
137+
helm repo update
138+
139+
# Deploy with preview images
140+
helm install my-preview wrongsecrets/wrongsecrets-ctf-party \
141+
--set balancer.repository=${{ env.IMAGE_PREFIX }}/wrongsecrets-balancer \
142+
--set balancer.tag=${{ needs.set-tag.outputs.tag }} \
143+
--set wrongsecretsCleanup.repository=${{ env.IMAGE_PREFIX }}/cleaner \
144+
--set wrongsecretsCleanup.tag=${{ needs.set-tag.outputs.tag }} \
145+
--set imagePullPolicy=Always
146+
147+
# Port forward to access locally
148+
kubectl port-forward service/wrongsecrets-balancer 3000:3000
149+
```
150+
151+
### Deploy with Custom Values
152+
153+
<details>
154+
<summary>Click to see preview-values.yaml</summary>
155+
156+
```yaml
157+
${{ steps.values.outputs.values }}
158+
```
159+
160+
</details>
161+
162+
```bash
163+
# Save the above values to preview-values.yaml, then:
164+
helm install my-preview wrongsecrets/wrongsecrets-ctf-party \
165+
-f preview-values.yaml
166+
```
167+
168+
### Deploy with Local Build Scripts
169+
170+
```bash
171+
# Clone this PR
172+
git fetch origin pull/${{ github.event.number }}/head:pr-${{ github.event.number }}
173+
git checkout pr-${{ github.event.number }}
174+
175+
# Use the existing deployment script with custom images
176+
./build-and-deploy.sh
177+
```
178+
179+
### Test the Changes
180+
181+
1. Access the application at http://localhost:3000
182+
2. Create a team and verify functionality
183+
3. Test any new features or bug fixes
184+
185+
### Container Registry
186+
187+
The preview images are available at:
188+
- https://github.com/${{ github.repository_owner }}/wrongsecrets-ctf-party/pkgs/container/wrongsecrets-balancer
189+
- https://github.com/${{ github.repository_owner }}/wrongsecrets-ctf-party/pkgs/container/cleaner
190+
191+
---
192+
193+
*This preview was automatically generated for PR #${{ github.event.number }}*
194+
EOF
195+
# yamllint enable rule:line-length
196+
197+
echo "content<<EOF" >> $GITHUB_OUTPUT
198+
cat instructions.md >> $GITHUB_OUTPUT
199+
echo "EOF" >> $GITHUB_OUTPUT
200+
201+
- name: Comment on PR
202+
uses: actions/github-script@v7
203+
env:
204+
INSTRUCTIONS_CONTENT: ${{ steps.instructions.outputs.content }}
205+
with:
206+
script: |
207+
const { owner, repo } = context.repo;
208+
const issue_number = context.issue.number;
209+
210+
// Find existing preview comment
211+
const comments = await github.rest.issues.listComments({
212+
owner,
213+
repo,
214+
issue_number,
215+
});
216+
217+
const existingComment = comments.data.find(comment =>
218+
comment.user.login === 'github-actions[bot]' &&
219+
comment.body.includes('🚀 Preview Deployment Ready!')
220+
);
221+
222+
const body = process.env.INSTRUCTIONS_CONTENT;
223+
224+
if (existingComment) {
225+
// Update existing comment
226+
await github.rest.issues.updateComment({
227+
owner,
228+
repo,
229+
comment_id: existingComment.id,
230+
body
231+
});
232+
} else {
233+
// Create new comment
234+
await github.rest.issues.createComment({
235+
owner,
236+
repo,
237+
issue_number,
238+
body
239+
});
240+
}
241+
242+
notify-main-branch:
243+
name: "Notify Main Branch Build"
244+
runs-on: ubuntu-latest
245+
needs: [set-tag, build-and-publish]
246+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
247+
steps:
248+
- name: Create main branch notification
249+
run: |
250+
# yamllint disable rule:line-length
251+
echo "## 🚀 Main Branch Preview Images Updated!"
252+
echo ""
253+
echo "New preview images have been built for the main branch:"
254+
echo ""
255+
echo "- **Balancer**: \`${{ env.IMAGE_PREFIX }}/wrongsecrets-balancer:${{ needs.set-tag.outputs.tag }}\`"
256+
echo "- **Cleaner**: \`${{ env.IMAGE_PREFIX }}/cleaner:${{ needs.set-tag.outputs.tag }}\`"
257+
echo ""
258+
echo "These can be used for testing the latest main branch changes."
259+
# yamllint enable rule:line-length

CONTRIBUTING.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,37 @@ Pull requests should be as small/atomic as possible. Large, wide-sweeping change
4646

4747
For example: `Fix #545` or `Closes #10`
4848

49+
### Testing your changes with Preview Deployments
50+
51+
When you create a pull request, GitHub Actions will automatically build and publish preview Docker containers to GitHub Container Registry. This allows you and reviewers to easily test your changes before merging.
52+
53+
#### How Preview Deployments Work
54+
55+
1. **Automatic Build**: When you open a PR, the preview workflow builds both `wrongsecrets-balancer` and `cleaner` containers
56+
2. **Container Publishing**: Images are pushed to `ghcr.io` with PR-specific tags (e.g., `pr-123`)
57+
3. **Deployment Instructions**: A comment is automatically posted on your PR with detailed deployment instructions
58+
4. **Easy Testing**: Anyone can deploy and test your changes using the provided Helm commands
59+
60+
#### Using Preview Deployments
61+
62+
After opening a PR, look for the automated comment that provides:
63+
64+
- **Direct deployment commands** using Helm
65+
- **Custom values file** for advanced configuration
66+
- **Container registry links** to inspect the built images
67+
- **Local testing instructions** for different deployment scenarios
68+
69+
Example deployment command from the preview comment:
70+
```bash
71+
helm install my-preview wrongsecrets/wrongsecrets-ctf-party \
72+
--set balancer.repository=ghcr.io/owasp/wrongsecrets-balancer \
73+
--set balancer.tag=pr-123 \
74+
--set wrongsecretsCleanup.repository=ghcr.io/owasp/cleaner \
75+
--set wrongsecretsCleanup.tag=pr-123
76+
```
77+
78+
This makes it easy for maintainers and other contributors to test your changes in a real Kubernetes environment.
79+
4980
## How to set up your Contributor Environment
5081

5182
1. Create a GitHub account. Multiple different GitHub subscription plans are available, but you only need a free one. Follow [these steps](https://help.github.com/en/articles/signing-up-for-a-new-github-account "Signing up for a new GitHub account") to set up your account.

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ A 100 contestant game can be played on the AWS, GCP, and Azure setup, which will
6868

6969
This is an experimental release. It showed to work at 6 CTFs already, we just did not complete the documentation and the cleaning up of the Helm chart yet. However: it is working in its basis, and can support a good crowd. Currently, we support using Minikube, AWS EKS, GCP GKE, and Azure AKS (_**Please follow the readme in the folder for each cloud provider if you want to use it, as the guides section is not updated yet**_).
7070

71+
**For Contributors**: Pull requests automatically generate preview deployments with containers published to GitHub Container Registry. See the automated PR comments for deployment instructions.
72+
7173
## How to use it
7274

7375
The different setups are explained in [OWASP WrongSecrets CTF-instructions](https://github.com/OWASP/wrongsecrets/blob/master/ctf-instructions.md). With the 3-domain approach you generate flags for CTFD automatically, while with the 2-domain setup you need to set it up manually.

wrongsecrets-balancer/Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ FROM node:22-alpine AS build
22
RUN mkdir -p /home/app
33
WORKDIR /home/app
44
COPY package.json package-lock.json ./
5-
RUN npm install
65
RUN npm ci --omit=dev
76

87
FROM node:22-alpine AS ui

0 commit comments

Comments
 (0)