Skip to content

Commit e01cc2e

Browse files
authored
Add CI system using GitHub Actions (#104)
* update extended glob pattern to use regex pattern which is more portable * update docker compose script to be compat with osx shell and create port override options * Fix issue 99 * add github actions for ci * update webui to use unpriv image and new port/mounts * update entrypoint ownership
1 parent 00633cd commit e01cc2e

File tree

9 files changed

+414
-15
lines changed

9 files changed

+414
-15
lines changed

.github/workflows/README.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# GitHub Actions Workflows
2+
3+
This directory contains GitHub Actions workflows for building and publishing container images to GitHub Container Registry (ghcr.io).
4+
5+
## Workflows
6+
7+
### build-containers.yml
8+
9+
**Trigger:** Push to `main` branch
10+
**Purpose:** Builds and publishes all container images with `latest` and SHA tags
11+
**Images:**
12+
13+
- `ghcr.io/<owner>/<repo>:latest` - Main API container
14+
- `ghcr.io/<owner>/<repo>-webui:latest` - Web UI container
15+
- `ghcr.io/<owner>/<repo>-devportal:latest` - DevPortal container
16+
17+
### build-pr.yml
18+
19+
**Trigger:** Pull requests to `main` branch
20+
**Purpose:** Builds all container images (without publishing) to verify they build correctly
21+
**Images:** Same as above but not pushed to registry
22+
23+
### build-release.yml
24+
25+
**Trigger:** Git tags matching `v*.*.*` pattern (e.g., `v1.0.0`)
26+
**Purpose:** Builds and publishes release versions with semantic versioning tags
27+
**Images:** Same containers as above but tagged with:
28+
29+
- Full version (e.g., `v1.2.3`)
30+
- Major.minor version (e.g., `v1.2`)
31+
- Major version (e.g., `v1`)
32+
- SHA commit hash
33+
34+
## Container Images
35+
36+
### Main API (`Dockerfile`)
37+
38+
The core NGINX Declarative API service built with Python and Alpine Linux.
39+
40+
### Web UI (`webui/Dockerfile`)
41+
42+
The web interface for managing the NGINX Declarative API, built with Node.js and served by NGINX.
43+
44+
### DevPortal (`contrib/devportal/redocly/Dockerfile`)
45+
46+
The Redocly-based developer portal for API documentation.
47+
48+
## Usage
49+
50+
### Pushing to Main Branch
51+
52+
```bash
53+
git push origin main
54+
```
55+
56+
This triggers `build-containers.yml` and publishes images with the `latest` tag.
57+
58+
### Creating a Release
59+
60+
```bash
61+
git tag v1.0.0
62+
git push origin v1.0.0
63+
```
64+
65+
This triggers `build-release.yml` and publishes versioned images.
66+
67+
### Pull Requests
68+
69+
When creating a pull request to `main`, the `build-pr.yml` workflow automatically runs to verify all containers build successfully.
70+
71+
## Permissions
72+
73+
The workflows require the following GitHub token permissions:
74+
75+
- `contents: read` - To checkout the repository
76+
- `packages: write` - To publish to GitHub Container Registry
77+
78+
These are automatically provided by the `GITHUB_TOKEN` secret.
79+
80+
## Registry Access
81+
82+
Published images are available at:
83+
84+
```
85+
ghcr.io/<owner>/<repo>
86+
ghcr.io/<owner>/<repo>-webui
87+
ghcr.io/<owner>/<repo>-devportal
88+
```
89+
90+
To pull images:
91+
92+
```bash
93+
docker pull ghcr.io/<owner>/<repo>:latest
94+
docker pull ghcr.io/<owner>/<repo>-webui:latest
95+
docker pull ghcr.io/<owner>/<repo>-devportal:latest
96+
```
97+
98+
For versioned releases:
99+
100+
```bash
101+
docker pull ghcr.io/<owner>/<repo>:v1.0.0
102+
docker pull ghcr.io/<owner>/<repo>-webui:v1.0.0
103+
docker pull ghcr.io/<owner>/<repo>-devportal:v1.0.0
104+
```
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Create and publish container images
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
7+
env:
8+
REGISTRY: ghcr.io
9+
IMAGE_NAME: ${{ github.repository }}
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: 'lts/*'
25+
cache: 'npm'
26+
cache-dependency-path: webui/package-lock.json
27+
28+
- name: Install WebUI dependencies
29+
working-directory: webui
30+
run: npm ci
31+
32+
- name: Run WebUI tests
33+
working-directory: webui
34+
run: npm test -- --run
35+
36+
build-and-push-images:
37+
runs-on: ubuntu-latest
38+
needs: test
39+
permissions:
40+
contents: read
41+
packages: write
42+
43+
steps:
44+
- name: Checkout repository
45+
uses: actions/checkout@v4
46+
47+
- name: Log in to the Container registry
48+
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
49+
with:
50+
registry: ${{ env.REGISTRY }}
51+
username: ${{ github.actor }}
52+
password: ${{ secrets.GITHUB_TOKEN }}
53+
54+
# Build and push dapi container (main Dockerfile)
55+
- name: Extract metadata (tags, labels) for dapi container
56+
id: meta-dapi
57+
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
58+
with:
59+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
60+
tags: |
61+
type=sha
62+
type=raw,value=latest
63+
64+
- name: Build and push dapi image
65+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
66+
with:
67+
context: .
68+
push: true
69+
tags: ${{ steps.meta-dapi.outputs.tags }}
70+
labels: ${{ steps.meta-dapi.outputs.labels }}
71+
72+
# Build and push WebUI container
73+
- name: Extract metadata (tags, labels) for WebUI container
74+
id: meta-webui
75+
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
76+
with:
77+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-webui
78+
tags: |
79+
type=sha
80+
type=raw,value=latest
81+
82+
- name: Build and push WebUI image
83+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
84+
with:
85+
context: webui/.
86+
push: true
87+
tags: ${{ steps.meta-webui.outputs.tags }}
88+
labels: ${{ steps.meta-webui.outputs.labels }}
89+
90+
# Build and push DevPortal container
91+
- name: Extract metadata (tags, labels) for DevPortal container
92+
id: meta-devportal
93+
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
94+
with:
95+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-devportal
96+
tags: |
97+
type=sha
98+
type=raw,value=latest
99+
100+
- name: Build and push DevPortal image
101+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
102+
with:
103+
context: contrib/devportal/redocly/.
104+
push: true
105+
tags: ${{ steps.meta-devportal.outputs.tags }}
106+
labels: ${{ steps.meta-devportal.outputs.labels }}

.github/workflows/build-pr.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Build container images (PR)
2+
3+
on:
4+
pull_request:
5+
branches: ["main"]
6+
7+
env:
8+
REGISTRY: ghcr.io
9+
IMAGE_NAME: ${{ github.repository }}
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: 'lts/*'
25+
cache: 'npm'
26+
cache-dependency-path: webui/package-lock.json
27+
28+
- name: Install WebUI dependencies
29+
working-directory: webui
30+
run: npm ci
31+
32+
- name: Run WebUI tests
33+
working-directory: webui
34+
run: npm test -- --run
35+
36+
build-images:
37+
runs-on: ubuntu-latest
38+
needs: test
39+
permissions:
40+
contents: read
41+
42+
steps:
43+
- name: Checkout repository
44+
uses: actions/checkout@v4
45+
46+
# Build dapi container (main Dockerfile)
47+
- name: Build dapi image
48+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
49+
with:
50+
context: .
51+
push: false
52+
53+
# Build WebUI container
54+
- name: Build WebUI image
55+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
56+
with:
57+
context: webui/.
58+
push: false
59+
60+
# Build DevPortal container
61+
- name: Build DevPortal image
62+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
63+
with:
64+
context: contrib/devportal/redocly/.
65+
push: false
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: Create and publish release container images
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
8+
env:
9+
REGISTRY: ghcr.io
10+
IMAGE_NAME: ${{ github.repository }}
11+
12+
jobs:
13+
test:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Node.js
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: 'lts/*'
26+
cache: 'npm'
27+
cache-dependency-path: webui/package-lock.json
28+
29+
- name: Install WebUI dependencies
30+
working-directory: webui
31+
run: npm ci
32+
33+
- name: Run WebUI tests
34+
working-directory: webui
35+
run: npm test -- --run
36+
37+
build-and-push-images:
38+
runs-on: ubuntu-latest
39+
needs: test
40+
permissions:
41+
contents: read
42+
packages: write
43+
44+
steps:
45+
- name: Checkout repository
46+
uses: actions/checkout@v4
47+
48+
- name: Log in to the Container registry
49+
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
50+
with:
51+
registry: ${{ env.REGISTRY }}
52+
username: ${{ github.actor }}
53+
password: ${{ secrets.GITHUB_TOKEN }}
54+
55+
# Build and push dapi container (main Dockerfile)
56+
- name: Extract metadata (tags, labels) for dapi container
57+
id: meta-dapi
58+
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
59+
with:
60+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
61+
tags: |
62+
type=semver,pattern={{version}}
63+
type=semver,pattern={{major}}.{{minor}}
64+
type=semver,pattern={{major}}
65+
type=sha
66+
67+
- name: Build and push dapi image
68+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
69+
with:
70+
context: .
71+
push: true
72+
tags: ${{ steps.meta-dapi.outputs.tags }}
73+
labels: ${{ steps.meta-dapi.outputs.labels }}
74+
75+
# Build and push WebUI container
76+
- name: Extract metadata (tags, labels) for WebUI container
77+
id: meta-webui
78+
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
79+
with:
80+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-webui
81+
tags: |
82+
type=semver,pattern={{version}}
83+
type=semver,pattern={{major}}.{{minor}}
84+
type=semver,pattern={{major}}
85+
type=sha
86+
87+
- name: Build and push WebUI image
88+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
89+
with:
90+
context: webui/.
91+
push: true
92+
tags: ${{ steps.meta-webui.outputs.tags }}
93+
labels: ${{ steps.meta-webui.outputs.labels }}
94+
95+
# Build and push DevPortal container
96+
- name: Extract metadata (tags, labels) for DevPortal container
97+
id: meta-devportal
98+
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
99+
with:
100+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-devportal
101+
tags: |
102+
type=semver,pattern={{version}}
103+
type=semver,pattern={{major}}.{{minor}}
104+
type=semver,pattern={{major}}
105+
type=sha
106+
107+
- name: Build and push DevPortal image
108+
uses: docker/build-push-action@5cd11c3a4ced054e52742c5fd54dca954e0edd85
109+
with:
110+
context: contrib/devportal/redocly/.
111+
push: true
112+
tags: ${{ steps.meta-devportal.outputs.tags }}
113+
labels: ${{ steps.meta-devportal.outputs.labels }}

0 commit comments

Comments
 (0)