Skip to content

CD Server: main

CD Server: main #155

Workflow file for this run

name: CD Server
run-name: "CD Server: ${{ github.ref_name }}"
on:
push:
branches: [main]
tags:
- 'server-v[0-9]+.[0-9]+.[0-9]+'
workflow_dispatch: {}
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
permissions:
contents: read
jobs:
# Wait for CI to pass on this commit
wait-for-ci:
name: Wait for CI
runs-on: ubuntu-latest
permissions:
contents: read
checks: read
steps:
- name: Wait for CI checks to pass
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: wait-for-ci
with:
token: ${{ secrets.GITHUB_TOKEN }}
checkName: CI Passed
ref: ${{ github.sha }}
timeoutSeconds: 900
intervalSeconds: 15
- name: Fail if CI did not pass
if: steps.wait-for-ci.outputs.conclusion != 'success'
run: |
echo "CI check 'CI Passed' did not pass (conclusion: ${{ steps.wait-for-ci.outputs.conclusion }})"
exit 1
build-server:
name: Build Server Binaries
needs: [wait-for-ci]
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
matrix:
include:
- os: ubuntu-latest
goos: linux
goarch: amd64
- os: ubuntu-latest
goos: linux
goarch: arm64
- os: windows-latest
goos: windows
goarch: amd64
- os: macos-latest
goos: darwin
goarch: amd64
- os: macos-latest
goos: darwin
goarch: arm64
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.3.0
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.24'
cache-dependency-path: |
common/go.sum
server/go.sum
- name: Get version
id: version
shell: bash
run: |
BASE_VERSION=$(cat server/VERSION)
GIT_COMMIT=$(git rev-parse --short HEAD)
BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
# Determine if this is a release (tag push) or dev build (main branch push)
if [[ "${{ github.ref }}" == refs/tags/server-v* ]]; then
echo "server_version=$BASE_VERSION" >> $GITHUB_OUTPUT
echo "build_type=release" >> $GITHUB_OUTPUT
else
echo "server_version=${BASE_VERSION}-dev.${GIT_COMMIT}" >> $GITHUB_OUTPUT
echo "build_type=dev" >> $GITHUB_OUTPUT
fi
echo "git_commit=$GIT_COMMIT" >> $GITHUB_OUTPUT
echo "build_time=$BUILD_TIME" >> $GITHUB_OUTPUT
- name: Build Server
working-directory: ./server
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: 0
run: |
go build -ldflags="-s -w -X 'main.Version=${{ steps.version.outputs.server_version }}' -X 'main.BuildTime=${{ steps.version.outputs.build_time }}' -X 'main.GitCommit=${{ steps.version.outputs.git_commit }}' -X 'main.BuildType=${{ steps.version.outputs.build_type }}'" -o printmaster-server-v${{ steps.version.outputs.server_version }}-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goos == 'windows' && '.exe' || '' }} .
- name: Upload Server Binary
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.3.0
with:
name: server-${{ matrix.goos }}-${{ matrix.goarch }}
path: server/printmaster-server-v${{ steps.version.outputs.server_version }}-${{ matrix.goos }}-${{ matrix.goarch }}*
build-docker:
name: Build Docker (${{ matrix.platform }})
needs: [wait-for-ci]
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
suffix: amd64
- platform: linux/arm64
runner: ubuntu-24.04-arm
suffix: arm64
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.3.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: version
run: |
echo "version=$(cat server/VERSION)" >> $GITHUB_OUTPUT
echo "git_commit=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_OUTPUT
# Dev builds from main branch, release builds from tags
if [[ "${{ github.ref }}" == refs/tags/server-v* ]]; then
echo "build_type=release" >> $GITHUB_OUTPUT
else
echo "build_type=dev" >> $GITHUB_OUTPUT
fi
- name: Build and push by digest
id: build
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v5
with:
context: .
file: ./server/Dockerfile
platforms: ${{ matrix.platform }}
build-args: |
VERSION=${{ steps.version.outputs.version }}
BUILD_TIME=${{ steps.version.outputs.build_time }}
GIT_COMMIT=${{ steps.version.outputs.git_commit }}
BUILD_TYPE=${{ steps.version.outputs.build_type }}
cache-from: type=gha,scope=server-${{ matrix.suffix }}
cache-to: type=gha,mode=max,scope=server-${{ matrix.suffix }}
outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-server,push-by-digest=true,name-canonical=true,push=true
provenance: false
sbom: false
- 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@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.3.0
with:
name: server-digests-${{ matrix.suffix }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
merge-docker:
name: Create Docker Manifest
needs: [build-docker]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.3.0
- name: Download digests
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: /tmp/digests
pattern: server-digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: version
run: |
echo "version=$(cat server/VERSION)" >> $GITHUB_OUTPUT
echo "git_commit=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
# Determine if this is a release (tag push) or dev build (main branch push)
if [[ "${{ github.ref }}" == refs/tags/server-v* ]]; then
echo "is_release=true" >> $GITHUB_OUTPUT
else
echo "is_release=false" >> $GITHUB_OUTPUT
fi
- name: Extract metadata
id: meta
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-server
tags: |
type=semver,pattern={{version}},value=${{ steps.version.outputs.version }},enable=${{ steps.version.outputs.is_release }}
type=semver,pattern={{major}}.{{minor}},value=${{ steps.version.outputs.version }},enable=${{ steps.version.outputs.is_release }}
type=raw,value=latest,enable=${{ steps.version.outputs.is_release }}
type=raw,value=${{ steps.version.outputs.version }},enable=${{ steps.version.outputs.is_release }}
type=raw,value=main,enable=${{ github.ref == 'refs/heads/main' }}
type=raw,value=dev-${{ steps.version.outputs.git_commit }},enable=${{ github.ref == 'refs/heads/main' }}
labels: |
org.opencontainers.image.description=PrintMaster Server container image (build ${{ steps.version.outputs.version }} / commit ${{ steps.version.outputs.git_commit }})
- name: Create manifest list and push
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-server@sha256:%s ' *)
- name: Inspect image
run: |
if [[ "${{ github.ref }}" == refs/tags/server-v* ]]; then
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-server:${{ steps.version.outputs.version }}
else
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-server:main
fi
release-server:
name: Create Server Release
if: startsWith(github.ref, 'refs/tags/server-v')
needs: [build-server, merge-docker]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.3.0
with:
fetch-depth: 0
- name: Download release artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: artifacts
pattern: server-*
merge-multiple: false
- name: Get version info
id: version
run: |
SERVER_VERSION=$(cat server/VERSION)
echo "version=$SERVER_VERSION" >> $GITHUB_OUTPUT
echo "tag=server-v$SERVER_VERSION" >> $GITHUB_OUTPUT
# Extract major.minor for compatible agent matching
MAJOR_MINOR=$(echo "$SERVER_VERSION" | sed 's/\.[^.]*$//')
# Find latest agent with matching minor version (e.g., server 0.9.5 -> agent 0.9.*)
MATCHING_AGENT_TAG=$(git tag -l "agent-v${MAJOR_MINOR}.*" --sort=-version:refname | head -n 1)
if [ -n "$MATCHING_AGENT_TAG" ]; then
echo "agent_version=${MATCHING_AGENT_TAG#agent-v}" >> $GITHUB_OUTPUT
echo "agent_tag=$MATCHING_AGENT_TAG" >> $GITHUB_OUTPUT
echo "Found compatible agent: $MATCHING_AGENT_TAG"
else
echo "agent_version=" >> $GITHUB_OUTPUT
echo "agent_tag=" >> $GITHUB_OUTPUT
echo "No compatible agent found for v${MAJOR_MINOR}.*"
fi
- name: Prepare release binaries
run: |
cd artifacts
for dir in */; do
name="${dir%/}"
binary=$(find "$dir" -maxdepth 1 -type f -name "printmaster-*" | head -n 1)
if [ -n "$binary" ]; then
cp "$binary" "./$(basename "$binary")"
echo "Prepared: $(basename "$binary")"
fi
done
echo "=== Release Binaries ==="
ls -lh printmaster-* 2>/dev/null || true
- name: Generate changelog
id: changelog
run: |
TAG_NAME="server-v${{ steps.version.outputs.version }}"
VERSION="${{ steps.version.outputs.version }}"
# Parse version components
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
# Determine release type and find appropriate comparison tag
if [ "$PATCH" = "0" ] && [ "$MINOR" = "0" ]; then
# Major release (x.0.0) - compare against last major
RELEASE_TYPE="major"
PREV_MAJOR=$((MAJOR - 1))
LAST_TAG=$(git tag -l "server-v${PREV_MAJOR}.*" --sort=-version:refname | head -n 1)
elif [ "$PATCH" = "0" ]; then
# Minor release (x.y.0) - compare against last minor's first tag
RELEASE_TYPE="minor"
PREV_MINOR=$((MINOR - 1))
LAST_TAG=$(git tag -l "server-v${MAJOR}.${PREV_MINOR}.*" --sort=-version:refname | head -n 1)
else
# Patch release - compare against previous patch
RELEASE_TYPE="patch"
LAST_TAG=$(git tag -l "server-v*" --sort=-version:refname | grep -v "^${TAG_NAME}$" | head -n 1)
fi
echo "Release type: $RELEASE_TYPE, comparing against: ${LAST_TAG:-none}"
if [ -z "$LAST_TAG" ]; then
CHANGELOG="Initial release"
else
# Get commits, filter release commits, and categorize
RAW_LOG=$(git log ${LAST_TAG}..${TAG_NAME} --pretty=format:"%s|||%h" --no-merges 2>/dev/null || echo "")
if [ -z "$RAW_LOG" ]; then
CHANGELOG="- Bug fixes and improvements"
else
# Categorize commits by conventional commit type
FEATURES=""
FIXES=""
DOCS=""
REFACTORS=""
OTHER=""
while IFS= read -r line; do
[ -z "$line" ] && continue
MSG=$(echo "$line" | cut -d'|' -f1)
HASH=$(echo "$line" | rev | cut -d'|' -f1 | rev)
# Skip release commits
echo "$MSG" | grep -q "^chore: Release" && continue
echo "$MSG" | grep -q "^chore(release)" && continue
# Categorize by type
if echo "$MSG" | grep -qE "^feat(\([^)]+\))?:"; then
DESC=$(echo "$MSG" | sed 's/^feat[^:]*: //')
FEATURES="${FEATURES}- ${DESC} (${HASH})\n"
elif echo "$MSG" | grep -qE "^fix(\([^)]+\))?:"; then
DESC=$(echo "$MSG" | sed 's/^fix[^:]*: //')
FIXES="${FIXES}- ${DESC} (${HASH})\n"
elif echo "$MSG" | grep -qE "^docs(\([^)]+\))?:"; then
DESC=$(echo "$MSG" | sed 's/^docs[^:]*: //')
DOCS="${DOCS}- ${DESC} (${HASH})\n"
elif echo "$MSG" | grep -qE "^refactor(\([^)]+\))?:"; then
DESC=$(echo "$MSG" | sed 's/^refactor[^:]*: //')
REFACTORS="${REFACTORS}- ${DESC} (${HASH})\n"
elif ! echo "$MSG" | grep -qE "^(chore|test|ci|build)(\([^)]+\))?:"; then
# Include non-chore/test/ci/build commits in OTHER
OTHER="${OTHER}- ${MSG} (${HASH})\n"
fi
done <<< "$RAW_LOG"
# Build changelog with sections
CHANGELOG=""
[ -n "$FEATURES" ] && CHANGELOG="${CHANGELOG}### ✨ Features\n${FEATURES}\n"
[ -n "$FIXES" ] && CHANGELOG="${CHANGELOG}### 🐛 Bug Fixes\n${FIXES}\n"
[ -n "$REFACTORS" ] && CHANGELOG="${CHANGELOG}### ♻️ Refactoring\n${REFACTORS}\n"
[ -n "$DOCS" ] && CHANGELOG="${CHANGELOG}### 📚 Documentation\n${DOCS}\n"
[ -n "$OTHER" ] && CHANGELOG="${CHANGELOG}### 📝 Other Changes\n${OTHER}\n"
# Fallback if nothing was categorized
if [ -z "$CHANGELOG" ]; then
CHANGELOG="- Bug fixes and improvements"
fi
fi
fi
# For major releases, add a note about checking full changelog
if [ "$RELEASE_TYPE" = "major" ]; then
CHANGELOG="**🎉 Major Release**\n\nThis is a major version update. Please review the [full changelog](https://github.com/mstrhakr/printmaster/compare/${LAST_TAG}...${TAG_NAME}) for breaking changes.\n\n${CHANGELOG}"
fi
{
echo 'CHANGELOG<<EOF'
echo -e "$CHANGELOG"
echo 'EOF'
} >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v1
with:
tag_name: ${{ steps.version.outputs.tag }}
name: PrintMaster Server v${{ steps.version.outputs.version }}
body: |
## PrintMaster Server v${{ steps.version.outputs.version }}
### 📝 Changes
${{ steps.changelog.outputs.CHANGELOG }}
---
### 📦 Installation
#### Docker (Recommended)
```bash
# Pull the latest image (supports amd64, arm64, arm/v7)
docker pull ghcr.io/mstrhakr/printmaster-server:${{ steps.version.outputs.version }}
docker pull ghcr.io/mstrhakr/printmaster-server:latest
# Run the container
docker run -d \
--name printmaster-server \
-p 9090:9090 \
-v printmaster-data:/var/lib/printmaster/server \
ghcr.io/mstrhakr/printmaster-server:latest
```
#### Binary Installation
1. Download the appropriate binary for your platform from the Assets section below
2. Extract the archive
3. Run the binary with `--help` to see available options
**Supported Platforms:**
- Windows (amd64)
- Linux (amd64, arm64)
- macOS (amd64, arm64)
---
### 🤖 Agent Downloads
You'll need the PrintMaster Agent to discover and monitor printers. Download the latest agent:
**Latest Agent: v${{ steps.version.outputs.agent_version }}** — [View Release](https://github.com/mstrhakr/printmaster/releases/tag/${{ steps.version.outputs.agent_tag }})
| Platform | Download |
|----------|----------|
| Windows (MSI) | [printmaster-agent-v${{ steps.version.outputs.agent_version }}-windows-amd64.msi](https://github.com/mstrhakr/printmaster/releases/download/${{ steps.version.outputs.agent_tag }}/printmaster-agent-v${{ steps.version.outputs.agent_version }}-windows-amd64.msi) |
| Linux (amd64) | [printmaster-agent-v${{ steps.version.outputs.agent_version }}-linux-amd64](https://github.com/mstrhakr/printmaster/releases/download/${{ steps.version.outputs.agent_tag }}/printmaster-agent-v${{ steps.version.outputs.agent_version }}-linux-amd64) |
| Linux (arm64) | [printmaster-agent-v${{ steps.version.outputs.agent_version }}-linux-arm64](https://github.com/mstrhakr/printmaster/releases/download/${{ steps.version.outputs.agent_tag }}/printmaster-agent-v${{ steps.version.outputs.agent_version }}-linux-arm64) |
| Debian/Ubuntu | [printmaster-agent_${{ steps.version.outputs.agent_version }}_amd64.deb](https://github.com/mstrhakr/printmaster/releases/download/${{ steps.version.outputs.agent_tag }}/printmaster-agent_${{ steps.version.outputs.agent_version }}_amd64.deb) |
| Fedora/RHEL | [printmaster-agent-${{ steps.version.outputs.agent_version }}.x86_64.rpm](https://github.com/mstrhakr/printmaster/releases/download/${{ steps.version.outputs.agent_tag }}/printmaster-agent-${{ steps.version.outputs.agent_version }}.x86_64.rpm) |
| macOS (Intel) | [printmaster-agent-v${{ steps.version.outputs.agent_version }}-darwin-amd64](https://github.com/mstrhakr/printmaster/releases/download/${{ steps.version.outputs.agent_tag }}/printmaster-agent-v${{ steps.version.outputs.agent_version }}-darwin-amd64) |
| macOS (Apple Silicon) | [printmaster-agent-v${{ steps.version.outputs.agent_version }}-darwin-arm64](https://github.com/mstrhakr/printmaster/releases/download/${{ steps.version.outputs.agent_tag }}/printmaster-agent-v${{ steps.version.outputs.agent_version }}-darwin-arm64) |
---
### ⏱️ Build Information
- **Workflow run:** ${{ github.run_id }}
- **Commit:** ${{ github.sha }}
### 🔗 Links
- [Documentation](https://github.com/mstrhakr/printmaster/tree/main/docs)
- [Docker Images](https://github.com/mstrhakr/printmaster/pkgs/container/printmaster-server)
- [Issue Tracker](https://github.com/mstrhakr/printmaster/issues)
files: artifacts/printmaster-*
fail_on_unmatched_files: false
draft: false
prerelease: false
release-server-dev:
name: Create Server Dev Release
if: github.ref == 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/')
needs: [build-server, merge-docker]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.3.0
with:
fetch-depth: 0
- name: Download release artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: artifacts
pattern: server-*
merge-multiple: false
- name: Get version info
id: version
run: |
BASE_VERSION=$(cat server/VERSION)
GIT_COMMIT=$(git rev-parse --short HEAD)
DEV_VERSION="${BASE_VERSION}-dev.${GIT_COMMIT}"
echo "version=$DEV_VERSION" >> $GITHUB_OUTPUT
echo "tag=server-v$DEV_VERSION" >> $GITHUB_OUTPUT
echo "base_version=$BASE_VERSION" >> $GITHUB_OUTPUT
echo "git_commit=$GIT_COMMIT" >> $GITHUB_OUTPUT
- name: Prepare release binaries
run: |
cd artifacts
for dir in */; do
name="${dir%/}"
binary=$(find "$dir" -maxdepth 1 -type f -name "printmaster-*" | head -n 1)
if [ -n "$binary" ]; then
cp "$binary" "./$(basename "$binary")"
echo "Prepared: $(basename "$binary")"
fi
done
echo "=== Release Binaries ==="
ls -lh printmaster-* 2>/dev/null || true
- name: Delete existing dev release (if any)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Delete the existing dev tag/release if it exists (we always update the dev release)
TAG="server-v${{ steps.version.outputs.version }}"
if gh release view "$TAG" &>/dev/null; then
echo "Deleting existing release $TAG..."
gh release delete "$TAG" --yes || true
fi
if git ls-remote --tags origin | grep -q "refs/tags/$TAG"; then
echo "Deleting existing tag $TAG..."
git push origin --delete "$TAG" || true
fi
- name: Create GitHub Dev Release
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v1
with:
tag_name: ${{ steps.version.outputs.tag }}
name: PrintMaster Server v${{ steps.version.outputs.version }} (Dev)
body: |
## PrintMaster Server v${{ steps.version.outputs.version }} (Development Build)
⚠️ **This is a development build from the main branch.** It may contain unstable or experimental features.
To receive dev builds automatically, set your server's `releases.include_prerelease = "true"` or run a dev build of the server.
---
### 📦 Installation
#### Docker
```bash
# Pull the dev image
docker pull ghcr.io/mstrhakr/printmaster-server:main
# Run the container
docker run -d \
--name printmaster-server \
-p 9090:9090 \
-v printmaster-data:/var/lib/printmaster/server \
ghcr.io/mstrhakr/printmaster-server:main
```
---
### ⏱️ Build Information
- **Base Version:** ${{ steps.version.outputs.base_version }}
- **Commit:** ${{ steps.version.outputs.git_commit }}
- **Full SHA:** ${{ github.sha }}
- **Workflow run:** ${{ github.run_id }}
### 🔗 Links
- [Documentation](https://github.com/mstrhakr/printmaster/tree/main/docs)
- [Docker Images](https://github.com/mstrhakr/printmaster/pkgs/container/printmaster-server)
- [Issue Tracker](https://github.com/mstrhakr/printmaster/issues)
files: artifacts/printmaster-*
fail_on_unmatched_files: false
draft: false
prerelease: true