All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Bump zad-cli from v0.6.0 to v0.8.0 (admin orphan-report/orphan-confirm commands, and a new structured error diagnosis layer with source labels, next-step suggestions and CI exit codes 1/2/3)
- Update
report_zad_errorto read zad-cli's new diagnosis JSON (headline,summary,next_steps) so error annotations surface the cause and remediation; falls back to the old flaterrorfield for version skew. Network/unknown failures (HTTP status 0) now keep their message instead of dropping it.
- Bump zad-cli from v0.5.0 to v0.6.0 (restore deployment, pvc-snapshots and admin commands, async admin delete, syncs with upstream ZAD API changes from 2026-05-18; zad-cli drops the
-salias and renders list commands as tables, but the actions do not parse that output so no behaviour change here)
- Bump zad-cli from v0.3.0 to v0.5.0 (v2 deployment read endpoints, mutation confirmations, faster
describe, plus error/validation fixes) - Bump
softprops/action-gh-releasefrom v2 to v3 in release workflow (moves release job to Node 24 runtime)
- Bump zad-cli from v0.2.1 to v0.3.0 (syncs with upstream ZAD API changes from 2026-04-20)
- Bump zad-cli from v0.1.2 to v0.2.1 (fixes crash on empty task-polling response, RijksICTGilde/zad-cli#11)
- Bump zad-cli from v0.1.1 to v0.1.2
- Update all documentation references from
@v3to@v4 - Update root README API section to reflect zad-cli usage
- all actions: Replace curl+bash API layer with zad-cli (pinned to v0.1.1)
- deploy: ~200 lines of curl/jq/polling replaced by single
zad deployment createcall - cleanup: ~80 lines of curl/polling replaced by single
zad deployment deletecall - scheduled-cleanup: same inline curl/polling replaced by shared
zad_delete_deploymenthelper - Retry logic, task polling, and error handling now delegated to the CLI
- Net reduction: ~310 lines of duplicated bash
- deploy: ~200 lines of curl/jq/polling replaced by single
- scripts/zad-common.sh: Rewritten —
curl_with_retry,poll_task, andbuild_poll_urlreplaced byinstall_zad_cli,validate_input,validate_integer,report_zad_error, andzad_delete_deployment - all actions: ZAD configuration now uses
ZAD_*env vars (ZAD_API_URL,ZAD_PROJECT_ID,ZAD_MAX_RETRIES,ZAD_RETRY_DELAY,ZAD_TASK_TIMEOUT,ZAD_TASK_POLL_INTERVAL) consumed directly by the CLI
- all actions:
astral-sh/setup-uvstep to ensureuvis available on GitHub runners - all actions:
$HOME/.local/binadded toGITHUB_PATHafter install sozadis available across steps
- all actions:
validate_inputandvalidate_integernowexit 1instead ofreturn 1(validation failures were silently ignored withoutset -e) - scheduled-cleanup: Add missing
validate_input "project-id"check (was present in deploy and cleanup but missing here) - all actions: Improve error message when CLI fails with no HTTP status code
3.2.0 - 2026-03-20
- deploy action: Optional domain configuration inputs (
domain-format,subdomain,base-domain) for custom hostname generation- Input validation consistent with existing fields
- Early-fail when
domain-formatcontains "subdomain" butsubdomainis not set
- deploy: URL fallback removed — action now fails with an error when the API response does not include a URL, instead of silently constructing one
3.1.0 - 2026-03-19
- cleanup: Multi-container deletion support
- New
containersinput: JSON array of[{"org": "...", "name": "...", "tag": "..."}] - Deletes all container images in a single cleanup call
- When set,
container-org/container-name/container-taginputs are ignored - Best-effort: each container deletion is independent
- Backward compatible: existing single-container inputs continue to work
- New
- deploy: Fix multi-component
urlsoutput writing multi-line JSON toGITHUB_OUTPUT— usejq -cfor compact single-line output
3.0.0 - 2026-03-19
- BREAKING: Migrate from synchronous V1 API to async V2 API
- Deploy, cleanup, and scheduled-cleanup now use
/api/v2/endpoints - Operations return a task ID immediately (HTTP 202) and are polled until completion
- Task progress (percentage, current step) is logged during polling
- Users must update from
@v2to@v3to use this version
- Deploy, cleanup, and scheduled-cleanup now use
- all actions: Extract
curl_with_retry,poll_task, andbuild_poll_urlto sharedscripts/zad-common.sh - all actions: Poll URL construction now handles absolute URLs from the API (not just relative paths)
- cleanup, scheduled-cleanup: Failed delete tasks now log
::error::instead of::warning::(consistent with deploy)
- all actions: New
task-timeoutinput (default:300s) — maximum wait for async task completion - all actions: New
task-poll-intervalinput (default:3s) — interval between task status polls - deploy action: Multi-component deployment support
- New
componentsinput: JSON array of[{"name": "...", "image": "..."}] - Deploys all components in a single API call
- When set,
componentandimageinputs are ignored - New
urlsoutput: JSON object mapping component names to URLs urloutput returns the first component's URL for backward compatibility- PR comment combines all component URLs into a single comment
componentandimageinputs are now optional (at least one approach must be provided)
- New
- deploy: PR comment URL parsing now uses tab delimiter instead of
=, preventing breakage when URLs contain query parameters - all actions:
poll_task()now fails fast on 4xx HTTP errors instead of retrying until timeout - scheduled-cleanup: Added missing validation for
task-timeoutandtask-poll-intervalinputs
2.4.0 - 2026-03-03
- deploy action: Per-component PR comments
- Each component now gets its own PR comment (e.g.
## 🚀 Preview Deployment — web) - No more overwriting: deploying multiple components via matrix strategy creates separate comments
- Re-deploying a component updates only its own comment
- Cleanup action still removes all component comments (matches on shared header prefix)
- Each component now gets its own PR comment (e.g.
- deploy action: Use URL from API response instead of hardcoded construction
- Projects with
subdomainconfiguration (e.g. deployment-name mode) now get the correct URL - Falls back to constructed URL with a warning if API response doesn't include URLs
- Projects with
2.3.0 - 2026-02-19
- deploy action: New
path-suffixinput to append a path to the deployment URL (e.g./docs/)- The suffix is included in the
urloutput, PR comment, and QR code - Handles leading/trailing slashes gracefully
- The suffix is included in the
2.2.1 - 2026-02-19
- scheduled-cleanup: Allow
$regex anchor inenvironment-patternandpr-number-patterninputs (was incorrectly blocked as a dangerous shell character)
2.2.0 - 2026-02-19
- deploy, cleanup, and scheduled-cleanup actions: Retry with exponential backoff for transient ZAD API errors
- New inputs:
max-retries(default:3),retry-delay(default:2) - Retries on network errors (HTTP 000), rate limits (429), and server errors (500-504)
- Does not retry on auth errors (401, 403) or not found (404)
- Backoff: 2s → 4s → 8s (worst-case 14s extra)
- Retry logic extracted into shared
curl_with_retrybash function - Note: only ZAD API calls are retried; GitHub API calls use best-effort error handling
- New inputs:
- scheduled-cleanup action: Periodically find and clean up stale PR environments
- Scans GitHub environments matching a configurable regex pattern
- Checks PR state and marks closed/merged PRs as stale
- Optional age-based cleanup via
max-age-days - Dry-run mode for safe testing
- Cleans up ZAD deployments, GitHub deployments/environments, and container images
- Smart rate limiting: reads
X-RateLimit-Remainingheader and only pauses when approaching the limit (replaces blind 0.5s delay) - Input validation for
environment-patternandpr-number-pattern(including sedeflag injection protection) cleaned-countoutput defaults to0when no cleanup is needed- Compact JSON output for
stale-environmentsto prevent GITHUB_OUTPUT corruption - Safe date parsing: warns and skips age check instead of falling back to epoch 0
- Container deletion uses
2>/dev/nullinstead of2>&1to prevent stderr leaking into captured output
- deploy, cleanup: ZAD API calls now retry 3 times by default on transient errors (was 0).
This adds up to 14s extra delay on persistent failures. Set
max-retries: '0'to restore previous fail-fast behavior. - deploy, cleanup:
github-tokendefault now consistently quoted as'${{ github.token }}'
- scheduled-cleanup:
cleaned-countno longer counts 404 (already deleted) as successfully cleaned - scheduled-cleanup: Admin token no longer leaks into subsequent operations if environment deletion fails (uses subshell)
- scheduled-cleanup:
pr-number-patternis now validated in both find-stale and cleanup steps (defense-in-depth)
2.1.0 - 2026-02-18
- deploy and cleanup actions: Skip bot PR deployments by default
- New input:
skip-bot-prs(default:true) - New output:
skipped - Detects bots via GitHub user type and known bot list (dependabot, renovate, pre-commit-ci, github-actions)
- Set
skip-bot-prs: 'false'to restore previous behavior - Supports both
pull_requestandpull_request_targetevents
- New input:
- CI workflow: Add explicit
permissions: contents: readto all jobs to comply with GitHub security best practices
2.0.1 - 2026-02-06
- deploy QR code not displaying in PR comments (switched from base64 PNG to text-based UTF8 format)
- cleanup action: Handle deletion of last tagged package version by deleting entire package when needed
- Update all documentation examples to use
@v2instead of@v1 - SECURITY.md: Mark v1.x.x as end of life, v2.x.x as supported
2.0.0 - 2026-02-02
- cleanup action: PR comment delete feature
- Delete the deploy PR comment when PR is closed (default: enabled)
- New inputs:
delete-pr-comment,comment-header - New output:
pr-comment-deleted
- BREAKING
cleanupaction:update-pr-commentinput (usedelete-pr-commentinstead) - BREAKING
cleanupaction:pr-comment-updatedoutput (usepr-comment-deletedinstead)
If you use the cleanup action with update-pr-comment, update your workflow:
- Replace
update-pr-comment: truewithdelete-pr-comment: true - The output
pr-comment-updatedis nowpr-comment-deleted - Note:
delete-pr-commentdefaults totrue, so you can remove it if you want the comment deleted
1.3.0 - 2026-02-02
- deploy action: Wait for ready feature
- Wait for deployment to be reachable before continuing
- New inputs:
wait-for-ready,health-endpoint,wait-timeout,wait-interval - Polls deployment URL until HTTP 2xx/3xx or timeout
- PR comment only appears after deployment is healthy (when combined with
comment-on-pr)
- deploy action: QR code in PR comment
- New input:
qr-code(default:false) - QR code for easy mobile testing of preview deployments
- Generated locally using
qrencode(no external API calls, privacy-friendly)
- New input:
.editorconfigfor consistent editor formatting.github/dependabot.ymlfor automated GitHub Actions updates.gitignorefor local settings and Claude plans.claude/configuration for AI assistant (coding rules, skills, workflow)
.pre-commit-config.yaml: require minimum version 4.5.0CONTRIBUTING.md: simplify setup withuvinstead ofpiprelease.yml: verify CHANGELOG entry exists, rollback tag on failure- deploy and cleanup actions:
github-tokennow defaults togithub.token- No longer necessary to explicitly pass
github-token: ${{ secrets.GITHUB_TOKEN }} - Only needed when using a custom PAT for cross-repository operations
- No longer necessary to explicitly pass
- Bump
actions/checkoutfrom v4 to v6
- Added justfile for common development tasks
- Added pre-commit.ci configuration (weekly autoupdates, skip duplicates with CI)
1.2.0 - 2026-01-22
- cleanup action: PR comment update feature
- Update the deploy PR comment to show cleanup status when PR is closed
- New inputs:
update-pr-comment,comment-header - New output:
pr-comment-updated
1.1.0 - 2026-01-22
- deploy action: PR commenting feature
- Automatically post/update a comment on PRs with the deployment URL
- New inputs:
comment-on-pr,github-token,comment-header - Upsert behavior: updates existing comment instead of creating duplicates
- CI/CD pipeline with ShellCheck, actionlint, and yamllint
- Branch protection and governance files (CODEOWNERS, issue templates, PR template)
- CONTRIBUTING.md with development guidelines
- SECURITY.md with security policy
- Pre-commit hooks configuration
- ShellCheck warnings: properly quoted GITHUB_OUTPUT
- Actionlint configuration to only lint workflow files
1.0.0 - 2026-01-22
- Initial release of ZAD Actions
- deploy action: Deploy container images to ZAD Operations Manager
- Support for cloning configuration from existing deployments
force-cloneparameter to re-clone even if deployment exists- Input validation for security (alphanumeric, hyphens, underscores, dots only)
- 60-second curl timeout to prevent hanging
- cleanup action: Remove ZAD deployments and GitHub resources
- Delete ZAD deployments via Operations Manager API
- Delete GitHub deployments (mark inactive, then delete)
- Delete GitHub environments (requires admin token)
- Delete container images from GHCR
- Best-effort cleanup (continues even if individual steps fail)
- Comprehensive documentation with examples
- EUPL-1.2 license
- Input validation before logging to prevent injection attacks
- Secure handling of API keys via environment variables
- Dangerous character detection for container inputs