Release
rogerpadilla/uql
Cut and publish a uql release - review the change, changelog entry, commit, version bump and tag, GitHub Release, npm publish, docs site.
Create a WebCalendar release — bump version, update CHANGELOG.md, verify DB upgrade SQL, generate GitHub release notes, commit/merge/tag/push to trigger CI, then publish curated release notes.
The automated check flagged lines worth reading first. See the safety section below.
$ npx skills add craigk5n/webcalendar --skill release -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install craigk5n/webcalendar release --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/craigk5n/webcalendar.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/release .claude/skills/release && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "release" agent skill from https://github.com/craigk5n/webcalendar/tree/master/.claude/skills/release into .claude/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/craigk5n/webcalendar/tree/master/.claude/skills/releaseType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add craigk5n/webcalendar --skill release -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install craigk5n/webcalendar release --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/craigk5n/webcalendar.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/release .agents/skills/release && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "release" agent skill from https://github.com/craigk5n/webcalendar/tree/master/.claude/skills/release into .agents/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add craigk5n/webcalendar --skill release -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install craigk5n/webcalendar release --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/craigk5n/webcalendar.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/release .cursor/skills/release && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "release" agent skill from https://github.com/craigk5n/webcalendar/tree/master/.claude/skills/release into .cursor/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/craigk5n/webcalendar.git --path .claude/skills/release--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add craigk5n/webcalendar --skill release -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install craigk5n/webcalendar release --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/craigk5n/webcalendar.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/release .gemini/skills/release && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "release" agent skill from https://github.com/craigk5n/webcalendar/tree/master/.claude/skills/release into .gemini/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install craigk5n/webcalendar releaseInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add craigk5n/webcalendar --skill release -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/craigk5n/webcalendar.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/release .github/skills/release && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "release" agent skill from https://github.com/craigk5n/webcalendar/tree/master/.claude/skills/release into .github/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add craigk5n/webcalendar --skill release -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install craigk5n/webcalendar release --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/craigk5n/webcalendar.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/release .opencode/skills/release && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "release" agent skill from https://github.com/craigk5n/webcalendar/tree/master/.claude/skills/release into .opencode/skills/release/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "release", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
releaseCreate a WebCalendar release — bump version, update CHANGELOG.md, verify DB upgrade SQL, generate GitHub release notes, commit/merge/tag/push to trigger CI, then publish curated release notes.
Release is an agent skill from craigk5n/webcalendar. Create a WebCalendar release — bump version, update CHANGELOG.md, verify DB upgrade SQL, generate GitHub release notes, commit/merge/tag/push to trigger CI, then publish curated release notes. Use when the user asks to "cut a release", "tag a release", "ship vX.Y.Z", or similar.
Its SKILL.md is about 5.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Changelog and release notes and SQL. It works with GitHub and SQL. The repository describes itself as: WebCalendar is a PHP application used to maintain a calendar for a single user or an intranet group of users. It can also be configured as an event calendar. The licence is GPL-2.0.
11 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit c516cb4. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitghphpjqcurlFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
auth.docker.ioregistry-1.docker.ioFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Release loads about 5.2k tokens when it runs. Until then it costs about 72 tokens; SKILL.md has 2,210 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found patterns that need a careful read before installing.
E`), `composer.json`, `composer.lock`, `.npmrc`, `wizard/shared/tables-*.sql`, `wizard/shared/tables-sqlite*.php`, `wiza.npmrc \| `.npmrc` | `init-version` |Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from craigk5n/webcalendar at commit c516cb4, republished under its GPL-2.0 licence (© craigk5n). 2,210 words, ~5,167 tokens.
.claude/skills/release/SKILL.md (or your agent's skills folder).Drives the WebCalendar release process end-to-end. Most version-string updates are already automated by bump_version.sh; this skill orchestrates the surrounding steps that aren't (CHANGELOG, upgrade-SQL verification, branch merge, tag, GitHub release notes).
User asks to:
vX.Y.Z. If omitted, auto-increment patch from current version.If the user gave no version, ask: "Auto-bump patch from <current> to <next-patch>, or do you want a different version?"
Run these checks. Halt and report on any failure.
# Must be on master
git rev-parse --abbrev-ref HEAD # expect: master
# No modified tracked files. Untracked local files are chronic in this
# repo (a couple of dozen scratch files, roadmaps and local configs), so
# plain --porcelain is never empty and would halt every release. The bump
# itself happens in a fresh worktree (Step 3), which is clean by
# construction; what matters here is that master has no uncommitted edits.
git status --porcelain --untracked-files=no # expect: empty
# Up to date with remote
git fetch origin
git log HEAD..origin/master --oneline # expect: empty
# Current version
./bump_version.sh -pIf on a different branch, or a tracked file is modified: stop and ask the user how to proceed. Do not auto-stash or auto-checkout.
Release-manifest coverage check. Every git-tracked file must be classified: listed in release-files (ships in the ZIP) or matched by release-files-excluded (dev-only). Past releases shipped broken because new files were committed without updating release-files (#667, missing translations, export_wordpress.php).
# Enforced invariant — fails if any tracked file is unclassified
vendor/bin/phpunit -c tests/phpunit.xml --filter ReleaseFilesConsistencyTest
# Files added since the last release, with their classification
PREV_TAG=$(git describe --tags --abbrev=0)
git diff --diff-filter=A --name-only "$PREV_TAG"..HEADShow the user the list of files added since PREV_TAG and, for each, whether it ships (release-files) or is excluded (release-files-excluded). Ask the user to confirm the classification of any newly added file that landed in the excluded set — a runtime file wrongly excluded is exactly the drift that broke past releases. If the test fails, stop: classify the offending files (with the user) before proceeding.
Compute the new version:
vX.Y.Z, use that.bump_version.sh will auto-increment the patch when called with no arg.State the planned version explicitly to the user before continuing.
Per maintainer policy, verify locally before triggering CI:
./tests/compile_test.sh # PHP syntax + composer.lock drift
vendor/bin/phpunit -c tests/phpunit.xml # PHPUnit suiteHalt on any failure. Do not "fix and retry" — surface the failure to the user.
First: is this checkout also a live deployment? If the tree is served by a
web server — /var/www/..., or includes/settings.php points at a database
real users rely on — do not bump in it. upgrade_requires_db_changes() returns
true for every version bump by design (includes/functions.php, "This
ensures the wizard is triggered for every version bump"), so from the moment
includes/config.php names a version ahead of the database, every request
redirects to wizard/index.php. The site is down until the tree is switched
back.
The mechanism is confirmed: upgrade_requires_db_changes() returns true for
any newer version, from nested scope and on repeat calls, so the redirect
branch is the one that runs. What that costs depends on whether a request
arrives. When v1.9.24 was cut this way on 2026-09-26 the tree sat ahead of the
database for about six minutes; whether a visitor hit it in that window was
never established, so treat the exposure as "every request during the window",
not as a measured outage.
Restoring the tree is not necessarily the whole recovery, because a request
that does arrive can complete the wizard and upgrade the database — which is
what appears to have happened on 2026-09-26. Then the roles reverse: the
database is ahead of a restored tree, upgrade_requires_db_changes() finds
nothing newer, returns false, and update_webcalendar_version_in_db() silently
rewrites the stored version backwards to match the older code. A calendar can
therefore end up with its version row flip-flopping as the tree is switched,
with no record in the activity log.
The rewrite moves the version row; it does not undo applied SQL. That is
the part to be careful about. After someone upgrades and the tree is then
restored, the row understates the schema: it says vX.Y.(Z-1) while vX.Y.Z's
statements have already run. Upgrading again from that row re-applies them.
v1.9.24's one statement is explicitly idempotent, so this cost nothing on
2026-09-26 — but upgrade-sql.php contains 72 ALTER TABLE ... ADD statements
across its history, and every one of those fails on a second run with a
duplicate-column error.
So after any release attempt that was interrupted, reverted, or bounced between trees, check the version row against what has actually been applied rather than trusting the row:
php bin/webcal.php config get WEBCAL_PROGRAM_VERSIONand confirm it against the effect of that version's entry in
wizard/shared/upgrade-sql.php. db check compares the row to the code, so it
agrees with a row that is itself wrong.
Work in a git worktree instead, which leaves the served tree untouched:
git worktree add -b chore/release-vX.Y.Z /tmp/wc-release origin/master
ln -s "$PWD/vendor" /tmp/wc-release/vendor # so the test suite can run
cd /tmp/wc-releaseThree release-files guards markTestSkipped in a linked worktree (.git is a
file there, so their git ls-files probe fails), so Step 1's manifest check
must be run in the main checkout or trusted to CI.
Then bump:
./bump_version.sh # auto-patch bump
# OR
./bump_version.sh vX.Y.Z # explicit versionThis updates: includes/default_config.php, wizard/shared/upgrade_matrix.php, includes/config.php ($PROGRAM_VERSION + $PROGRAM_DATE), composer.json, composer.lock, .npmrc, wizard/shared/tables-*.sql, wizard/shared/tables-sqlite*.php, wizard/shared/upgrade-sql.php (adds empty placeholder entry), the four wizard files (index.php, headless.php, wizard.js, WizardState.php), and three documentation stamps: README.md's version badge, docs/WebCalendar-Database.md's **Version:** line, and CLAUDE.md's overview line where that file exists.
The documentation stamps are not cosmetic: tests/DocumentedVersionTest.php
asserts all three against includes/config.php, so a release that bumps the
code and not the docs fails the build. They must be staged with the rest
(Step 8).
Confirm by running ./bump_version.sh -p — should show the new version.
bump_version.sh does not touch CHANGELOG.md. This skill must.
Open CHANGELOG.md. The file uses Keep a Changelog format with an ## [Unreleased] section near the top (after the intro paragraphs). Two edits:
A. Rename ## [Unreleased] → ## [vX.Y.Z] - YYYY-MM-DD
Use today's date in YYYY-MM-DD format (compute from date +%Y-%m-%d).
B. Insert a fresh ## [Unreleased] section directly above the new versioned heading
The fresh section must contain empty subsections so future contributors can drop entries in. Template:
## [Unreleased]
### Added
### Changed
### Fixed
### Removed
(Yes — empty subsections are intentional. They guide future PRs.)
After editing, show the user the diff for CHANGELOG.md so they can confirm before committing.
If the existing [Unreleased] section is empty (no entries under any subsection): stop and ask the user. A release with no changelog entries is suspicious — they may want to add entries or skip the release.
wizard/shared/upgrade-sql.phpbump_version.sh appends a placeholder entry like:
[
'version' => 'vX.Y.Z',
'default-sql' => ''
],Open wizard/shared/upgrade-sql.php, locate the entry for the new version, and inspect its default-sql (and any postgresql-sql / sqlite3-sql / upgrade-function keys).
Two cases:
Case A — default-sql is non-empty (DB schema changes for this release):
Show the user the SQL block(s) and ask: "Confirm these are the correct DB upgrade statements for vX.Y.Z?" Wait for confirmation before proceeding.
Case B — default-sql is empty:
Ask the user explicitly: "No DB schema changes detected for vX.Y.Z. Confirm there are genuinely no DB changes for this release? (If there should be, edit wizard/shared/upgrade-sql.php now.)"
The empty-entry-as-marker convention matches prior no-DB-change releases (see v1.9.14 and v1.9.15 entries). Leaving the empty entry in place is the correct way to record "no DB changes for this version" — do not delete the entry.
Write release notes to /tmp/release-notes-vX.Y.Z.md.
Source material, in order of priority:
## [vX.Y.Z] section from CHANGELOG.md (just renamed in Step 4) — primary content.git log <prev-tag>..HEAD --oneline. Use this to spot-check that the changelog is complete; if commits clearly missing from the changelog reference issues/PRs (fix(...): ... (#NNN)), include them.Format (matches recent releases like v1.9.15):
# WebCalendar vX.Y.Z
<one-paragraph release summary — pull from CHANGELOG.md intro or write a 1-2 sentence summary>
## Added
- ...
## Changed
- ...
## Fixed
- ...
## Removed
- ...
## Verifying this release
WebCalendar releases ship a signed manifest. See `docs/release-signing.md` for verification instructions.Drop empty subsections. Keep PR/issue references ((#NNN)) intact — they render as links on GitHub.
Show the user the generated notes and ask for edits before continuing.
Before any git commit, show the user:
git status — files staged/changedgit diff --stat — summary of changesCHANGELOG.md diff (Step 4)./bump_version.sh -p)Wait for explicit "go" / "yes" / equivalent confirmation. Do not assume.
Note that "cut the release" earlier in the conversation is authorisation for the release; it is not this confirmation, which is about the specific diff.
Stage explicitly — never git add -A. The repo carries a couple of dozen
untracked local files; -A would sweep them into the release commit. Stage
only the files this release touches:
# Files bump_version.sh touches + CHANGELOG.md.
# If a release skips bump_version.sh (e.g. shipping a previously-prepared
# version), stage only what actually changed (commonly just CHANGELOG.md).
git add \
CHANGELOG.md \
includes/default_config.php \
wizard/shared/upgrade_matrix.php \
includes/config.php \
composer.json composer.lock \
.npmrc \
wizard/shared/tables-*.sql \
wizard/shared/tables-sqlite*.php \
wizard/shared/upgrade-sql.php \
wizard/index.php wizard/headless.php wizard/wizard.js wizard/WizardState.php \
README.md docs/WebCalendar-Database.md
# CLAUDE.md is also updated by bump_version.sh but is untracked; nothing to
# stage, and DocumentedVersionTest skips it when it is absent. It will
# disagree with includes/config.php in any checkout that has it until that
# checkout pulls the release commit.
# Sanity-check what's staged before committing
git diff --cached --stat
git commit -m "chore(release): vX.Y.Z"Then open a pull request against master and merge it once CI is green:
git push -u origin chore/release-vX.Y.Z
gh pr create --base master --head chore/release-vX.Y.Z \
--title "chore(release): vX.Y.Z" --body-file /tmp/release-pr-vX.Y.Z.md
# ... wait for checks, then:
gh pr merge <N> --mergePass --head explicitly. gh pr create otherwise infers the head branch from
the current checkout, which is wrong whenever the bump was made in a worktree
or the tree has been switched back.
Why a pull request rather than committing straight to master. An earlier
version of this skill committed and tagged on master locally, then pushed
master, master:release and the tag in one call. A pull request instead
gives the release commit the same review and the same checks as everything
else in this repository: the diff gets a URL, and master does not move until
the suite is green on the exact commit being shipped.
The cost is that master gains a merge commit that does not exist locally, so
the tag cannot be created before the push. Step 9 handles that.
What a pull request does not buy you: nothing exercises release.yml
itself. It runs only on a push to release, so a bug in the release workflow
reaches you at release time no matter how the commit got to master. That is
how v1.9.24 first failed to cut — release.yml calls five workflows, three of
which shared a concurrency group and so cancelled one of their own jobs, and
no pull request could have shown it. Structural guards are the only cover
here; tests/ReusableWorkflowConcurrencyTest.php is the one for that
particular trap. Expect the first release after any release.yml or
reusable-workflow change to be the test of it, and read the run rather than
assuming a green PR implies a green release.
releaseAfter the merge, the commit to tag is origin/master, not anything local.
Tag it without checking it out — checking it out in a served tree is the
Step 3 hazard again:
git fetch origin
git tag vX.Y.Z origin/master # no working-tree change
git rev-parse vX.Y.Z origin/master # confirm they match
# One round-trip: the tag, then the release fast-forward.
git push origin vX.Y.Z origin/master:refs/heads/releaseThe tag must exist at push time so actions/create-release@v1 reuses it
instead of minting its own. release.yml does tag the branch itself as a
fallback and the result is the same commit, so a release cut without the tag
is not broken — but the tag then comes from the workflow rather than from a
reviewed commit, and the run's own "Check and Delete Existing Tag" step is
what makes that safe. Push the tag.
Confirm the fast-forward before pushing if release has drifted:
git merge-base --is-ancestor origin/release origin/master && echo "fast-forward"
git rev-list --count origin/release..origin/masterThe release branch is a moving pointer at the most recent shipped commit,
not a long-lived branch — a plain fast-forward, never a merge commit. It can
legitimately be many commits behind (158, for v1.9.24); confirm with the user
if the count is unexpectedly high, but a large number is normal when releases
are infrequent.
Pushing to release is what triggers .github/workflows/release.yml: full CI
suite → build zip → manifest and cosign signing → GitHub release. It also
triggers .github/workflows/docker.yml, which builds a multi-arch image and
pushes four Docker Hub tags: <user>/webcalendar:X.Y.Z, X.Y.Z-php8-apache,
latest-php8-apache and latest. No manual Docker step is needed.
Do not git pull in a served checkout afterwards. master now names a
version ahead of that installation's database, which is the wizard redirect
from Step 3. Upgrading a live install is a deployment decision for its
administrator, separate from cutting the release; php bin/webcal.php db check
reports the pending state without applying anything.
# Find the run for the just-pushed commit (note: gh run list does NOT support --branch)
RUN_ID=$(gh run list --workflow=release.yml --limit=5 --json databaseId,headSha,status \
| jq -r --arg sha "$(git rev-parse master)" '.[] | select(.headSha==$sha) | .databaseId' | head -1)
gh run watch "$RUN_ID" --exit-statusIf CI fails: surface the failure URL to the user and stop. Do not retry automatically.
Once the workflow succeeds, actions/create-release@v1 will have created a GitHub release with a placeholder body ("Release of WebCalendar vX.Y.Z"). Replace it with the curated notes.
Preferred (gh ≥ 2.20):
gh release edit vX.Y.Z \
--title "WebCalendar vX.Y.Z" \
--notes-file /tmp/release-notes-vX.Y.Z.mdFallback for older gh (< 2.20 — no release edit subcommand):
RELEASE_ID=$(gh api /repos/craigk5n/webcalendar/releases/tags/vX.Y.Z -q .id)
jq -Rs '{body: .}' < /tmp/release-notes-vX.Y.Z.md \
| gh api -X PATCH "/repos/craigk5n/webcalendar/releases/$RELEASE_ID" --input -Detect via gh release edit --help 2>&1 | grep -q "unknown command" and pick the right path.
Verify:
gh release view vX.Y.ZTell the user:
gh release view vX.Y.Z --json url -q .urlvX.Y.Zmaster, releaseX.Y.Z, X.Y.Z-php8-apache, latest-php8-apache, latest) — spot-check with:
curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:craigk5n/webcalendar:pull" for a token, then HEAD https://registry-1.docker.io/v2/craigk5n/webcalendar/manifests/X.Y.Z (the hub.docker.com tag-listing API lags; the registry API is authoritative)master[Unreleased] section in CHANGELOG.md is emptyupgrade-sql.php entry needs human confirmation (Step 5)release branchgh not authenticatedvX.Y.Z already exists upstreamrelease.yml or migrate off actions/create-release@v1upgrade-sql.php (that's a human judgment call about schema changes)[Unreleased] placeholder entry from upgrade-sql.php for no-DB-change releases — the empty entry is the canonical markerbump_version.sh already handles(Documented here so we don't re-do its work.)
| File | What's updated |
|---|---|
includes/default_config.php | WEBCAL_PROGRAM_VERSION |
wizard/shared/upgrade_matrix.php | $PROGRAM_VERSION |
includes/config.php | $PROGRAM_VERSION, $PROGRAM_DATE |
composer.json + composer.lock | version field |
.npmrc | init-version |
wizard/shared/tables-*.sql | WEBCAL_PROGRAM_VERSION INSERT |
wizard/shared/tables-sqlite*.php | WEBCAL_PROGRAM_VERSION INSERT |
wizard/shared/upgrade-sql.php | appends empty placeholder entry |
wizard/index.php | const PROGRAM_VERSION |
wizard/headless.php | const PROGRAM_VERSION |
wizard/wizard.js | programVersion fallback |
wizard/WizardState.php | programVersion fallback |
README.md | version badge |
docs/WebCalendar-Database.md | **Version:** stamp |
CLAUDE.md | overview line, only if the file is present |
The legacy installer code referenced upgrade-*.sql files with /*upgrade_vX.Y.Z */ C-style comments, plus ChangeLog and NEWS files. All of this is obsolete:
upgrade-*.sql files were replaced by wizard/shared/upgrade-sql.php in v1.9.12.ChangeLog and NEWS were replaced by CHANGELOG.md (Keep a Changelog format).© craigk5n, GPL-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/release of craigk5n/webcalendar.
Open the folder on GitHubat commit c516cb4
Release next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Release this skillcraigk5n/webcalendar | 173 | — | ~5.2k | Automated safety check: Warn | GPL-2.0 | |
| Releaserogerpadilla/uql | 125 | — | ~842 | Automated safety check: Pass | MIT | |
| Turning Engineering Analytics Into InsightsPostHog/posthog | 40k | — | ~2.9k | Automated safety check: Pass | Custom licence | |
| Migrating Oracle To Postgres Stored Proceduresgithub/awesome-copilot | 40k | — | ~788 | Automated safety check: Pass | MIT | |
| Migrating Oracle To Postgres Stored Proceduresboshi-xixixi/TraeSkill | 275 | — | ~576 | Automated safety check: Pass | MIT | |
| Cutting A ReleaseTriliumNext/Trilium | 38k | — | ~3.2k | Automated safety check: Pass | AGPL-3.0 |
rogerpadilla/uql
Cut and publish a uql release - review the change, changelog entry, commit, version bump and tag, GitHub Release, npm publish, docs site.
PostHog/posthog
Converts engineering analytics (PR / CI) data into saved PostHog insights, dashboards, and subscriptions, and explains how to query the product data directly with SQL.
github/awesome-copilot
Migrates Oracle PL/SQL stored procedures to PostgreSQL PL/pgSQL.
boshi-xixixi/TraeSkill
Migrates Oracle PL/SQL stored procedures to PostgreSQL PL/pgSQL.
TriliumNext/Trilium
A skill your agent uses when cutting, preparing, or debugging a Trilium release — bumping the monorepo version, tagging, or diagnosing a failed "Release" workflow run.
tw93/Mole
Runbook for assessing and executing a Mole CLI release: distribution channels, pre-flight checks, capital-V tags, build artifacts and the handoff to curated release notes.
Categories
Create a WebCalendar release — bump version, update CHANGELOG.md, verify DB upgrade SQL, generate GitHub release notes, commit/merge/tag/push to trigger CI, then publish curated release notes. Release is an agent skill from craigk5n/webcalendar.md, verify DB upgrade SQL, generate GitHub release notes, commit/merge/tag/push to trigger CI, then publish curated release notes.
Release fits situations like: then publish curated release notes; the user asks to cut a release.
Run `npx skills add craigk5n/webcalendar --skill release -a claude-code`. Or copy the skill folder (.claude/skills/release in craigk5n/webcalendar) into .claude/skills/release in your project. Claude Code loads it when a task matches its description.
Run `npx skills add craigk5n/webcalendar --skill release -a codex`. Or copy the skill folder (.claude/skills/release in craigk5n/webcalendar) into .agents/skills/release in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add craigk5n/webcalendar --skill release -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/release, .gemini/skills/release, .github/skills/release and .opencode/skills/release in your project.
Going by SKILL.md and its folder, Release needs the command-line tools its instructions call (git, gh, php, jq and curl).
SKILL.md names 2 domains. In commands or code: auth.docker.io and registry-1.docker.io; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md flagged 3 warning(s): mentions a credentials file (ssh keys, cloud or package-manager tokens). Read the flagged lines before installing; the check is not a guarantee either way.
Release is published under the GPL-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.2k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Release: Release (rogerpadilla/uql, 125 stars), Turning Engineering Analytics Into Insights (PostHog/posthog, 40k stars), Migrating Oracle To Postgres Stored Procedures (github/awesome-copilot, 40k stars) and Migrating Oracle To Postgres Stored Procedures (boshi-xixixi/TraeSkill, 275 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
craigk5n (a GitHub user) maintains it in craigk5n/webcalendar, which has 173 GitHub stars. The repository was last updated on October 5, 2026.
Source: craigk5n/webcalendar on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.