2026-04-10 00:26:32 +00:00

306 lines
9.7 KiB
YAML

name: build
on:
pull_request:
branches:
- master
workflow_dispatch:
inputs:
tag_suffix:
description: 'Optional tag suffix (e.g., "test-feature")'
required: false
default: ''
permissions:
contents: read
packages: write
pull-requests: write
jobs:
setup:
runs-on: ubuntu-latest
outputs:
tag_suffix: ${{ steps.tags.outputs.tag_suffix }}
is_pr: ${{ steps.tags.outputs.is_pr }}
webapp_release: ${{ steps.webapp.outputs.webapp_release }}
build_date: ${{ steps.tags.outputs.build_date }}
steps:
- name: Get latest Webapp release version
id: webapp
run: |
WEBAPP_RELEASE=$(curl -sX GET "https://api.github.com/repos/netbootxyz/webapp/releases/latest" | jq -r '. | .tag_name')
echo "webapp_release=${WEBAPP_RELEASE}" >> $GITHUB_OUTPUT
- name: Determine tag strategy
id: tags
env:
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.number }}
INPUT_TAG_SUFFIX: ${{ github.event.inputs.tag_suffix }}
run: |
if [ "$EVENT_NAME" == "pull_request" ]; then
echo "tag_suffix=pr-${PR_NUMBER}" >> $GITHUB_OUTPUT
echo "is_pr=true" >> $GITHUB_OUTPUT
elif [ "$EVENT_NAME" == "workflow_dispatch" ]; then
if [ -n "$INPUT_TAG_SUFFIX" ]; then
SANITIZED=$(echo "$INPUT_TAG_SUFFIX" | tr -cd '[:alnum:]-_' | cut -c1-50)
if [ -n "$SANITIZED" ]; then
echo "tag_suffix=test-${SANITIZED}" >> $GITHUB_OUTPUT
else
echo "tag_suffix=test-$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_OUTPUT
fi
else
echo "tag_suffix=test-$(date +'%Y%m%d-%H%M%S')" >> $GITHUB_OUTPUT
fi
echo "is_pr=false" >> $GITHUB_OUTPUT
else
echo "::error::Unsupported event type: $EVENT_NAME"
exit 1
fi
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
build-amd64:
needs: setup
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: '0'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to the Docker Container Registry
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to the GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USER }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Build and push (amd64)
id: build
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
build-args: |
WEBAPP_VERSION=${{ needs.setup.outputs.webapp_release }}
VERSION=${{ needs.setup.outputs.tag_suffix }}
BUILD_DATE=${{ needs.setup.outputs.build_date }}
labels: |
org.opencontainers.image.title=netbootxyz
org.opencontainers.image.description=netboot.xyz test image
org.opencontainers.image.version=${{ needs.setup.outputs.tag_suffix }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.source=https://github.com/netbootxyz/docker-netbootxyz
outputs: type=image,name=ghcr.io/netbootxyz/netbootxyz,push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v7
with:
name: digests-amd64
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
# - name: Run Trivy vulnerability scanner (amd64)
# uses: aquasecurity/trivy-action@0.35.0
# with:
# image-ref: 'ghcr.io/netbootxyz/netbootxyz@${{ steps.build.outputs.digest }}'
# version: 'v0.69.3'
# format: 'table'
# exit-code: ${{ needs.setup.outputs.is_pr == 'true' && '1' || '0' }}
# ignore-unfixed: true
# vuln-type: 'os,library'
# severity: 'CRITICAL,HIGH'
build-arm64:
needs: setup
runs-on: ubuntu-24.04-arm
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: '0'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to the Docker Container Registry
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to the GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USER }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Build and push (arm64)
id: build
uses: docker/build-push-action@v7
with:
context: .
file: ./Dockerfile
platforms: linux/arm64
build-args: |
WEBAPP_VERSION=${{ needs.setup.outputs.webapp_release }}
VERSION=${{ needs.setup.outputs.tag_suffix }}
BUILD_DATE=${{ needs.setup.outputs.build_date }}
labels: |
org.opencontainers.image.title=netbootxyz
org.opencontainers.image.description=netboot.xyz test image
org.opencontainers.image.version=${{ needs.setup.outputs.tag_suffix }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.source=https://github.com/netbootxyz/docker-netbootxyz
outputs: type=image,name=ghcr.io/netbootxyz/netbootxyz,push-by-digest=true,name-canonical=true,push=true
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v7
with:
name: digests-arm64
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
# - name: Run Trivy vulnerability scanner (arm64)
# uses: aquasecurity/trivy-action@0.35.0
# env:
# TRIVY_PLATFORM: linux/arm64
# with:
# image-ref: 'ghcr.io/netbootxyz/netbootxyz@${{ steps.build.outputs.digest }}'
# version: 'v0.69.3'
# format: 'table'
# exit-code: ${{ needs.setup.outputs.is_pr == 'true' && '1' || '0' }}
# ignore-unfixed: true
# vuln-type: 'os,library'
# severity: 'CRITICAL,HIGH'
manifest:
needs: [setup, build-amd64, build-arm64]
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to the Docker Container Registry
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to the GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USER }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Download digests
uses: actions/download-artifact@v8
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Create manifest list and push (GHCR)
working-directory: /tmp/digests
run: |
TAG_SUFFIX="${{ needs.setup.outputs.tag_suffix }}"
SHA="${{ github.sha }}"
docker buildx imagetools create \
-t "ghcr.io/netbootxyz/netbootxyz:${TAG_SUFFIX}" \
-t "ghcr.io/netbootxyz/netbootxyz:${TAG_SUFFIX}-${SHA}" \
$(printf 'ghcr.io/netbootxyz/netbootxyz@sha256:%s ' *)
- name: Create manifest list and push (Docker Hub)
working-directory: /tmp/digests
run: |
TAG_SUFFIX="${{ needs.setup.outputs.tag_suffix }}"
SHA="${{ github.sha }}"
docker buildx imagetools create \
-t "netbootxyz/netbootxyz:${TAG_SUFFIX}" \
-t "netbootxyz/netbootxyz:${TAG_SUFFIX}-${SHA}" \
$(printf 'ghcr.io/netbootxyz/netbootxyz@sha256:%s ' *)
comment:
needs: [setup, manifest]
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Comment on PR with test instructions
uses: actions/github-script@v9
with:
script: |
const comment = `## 🚀 Test Image Built Successfully!
Your PR test images have been published and are ready for testing:
### Docker Hub
\`\`\`bash
docker pull netbootxyz/netbootxyz:pr-${{ github.event.number }}
\`\`\`
### GitHub Container Registry
\`\`\`bash
docker pull ghcr.io/netbootxyz/netbootxyz:pr-${{ github.event.number }}
\`\`\`
### Quick Test Commands
**Standard Docker:**
\`\`\`bash
docker run -d \\
--name netbootxyz-test \\
-e PUID=1000 \\
-e PGID=1000 \\
-p 3000:3000 \\
-p 69:69/udp \\
-p 8080:80 \\
-v /local/path/config:/config \\
netbootxyz/netbootxyz:pr-${{ github.event.number }}
\`\`\`
### Platforms
- ✅ linux/amd64
- ✅ linux/arm64
### Check Logs
\`\`\`bash
docker logs -f netbootxyz-test
\`\`\`
---
📦 **SHA:** \`${{ github.sha }}\`
🏷️ **Webapp Version:** \`${{ needs.setup.outputs.webapp_release }}\`
`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});