Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
{
"name": "engineering-practices",
"description": "Git commits, conventional releases, refactoring, test-driven development, and engineering ways of working skills",
"version": "1.1.2",
"version": "1.1.3",
"source": "./plugins/engineering-practices"
},
{
Expand Down
2 changes: 1 addition & 1 deletion .github/plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
{
"name": "engineering-practices",
"description": "Git commits, conventional releases, refactoring, test-driven development, and engineering ways of working skills",
"version": "1.1.2",
"version": "1.1.3",
"source": "./plugins/engineering-practices"
},
{
Expand Down
15 changes: 12 additions & 3 deletions .github/workflows/update-agent-skills.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@ on:
options:
- all
- agentic-engineering
- engineering-practices
schedule:
- cron: "0 6 * * *"

permissions:
contents: write
pull-requests: write
permissions: {}

# All scopes can update the same per-skill branches. Keep their digest/version
# follow-ups inside the same non-cancelling queue as the updater itself.
concurrency:
group: agent-plugins-skill-sync-${{ github.repository }}
cancel-in-progress: false
queue: max

jobs:
scope:
Expand All @@ -40,6 +46,9 @@ jobs:

update:
needs: scope
permissions:
contents: write # The shared updater writes the signed skill-sync commits.
pull-requests: write # The shared updater opens per-skill update proposals.
uses: devantler-tech/.github/.github/workflows/update-agent-skills.yaml@e271b7ff25d4ce97b067612e7ba0c5d657b6a17a # v6.1.0
with:
dir: ${{ needs.scope.outputs.dir }}
Expand Down
12 changes: 8 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ which records the true upstream in the skill's `metadata.github-*` frontmatter (
`anthropics/skills`, our own sibling [`devantler-tech/agent-skills`](https://github.com/devantler-tech/agent-skills),
…), each tracked independently. The daily
[`update-agent-skills.yaml`](.github/workflows/update-agent-skills.yaml) workflow runs
[`gh skill update --all`](https://github.com/devantler-tech/actions/tree/main/update-agent-skills) via
the [`update-agent-skills`](https://github.com/devantler-tech/actions/blob/main/.github/workflows/update-agent-skills.yaml)
[`gh skill update --all`](https://github.com/devantler-tech/.github/tree/main/actions/update-agent-skills) via
the [`update-agent-skills`](https://github.com/devantler-tech/.github/blob/main/.github/workflows/update-agent-skills.yaml)
reusable workflow and opens one PR per drifted skill, from `deps/agent-skills-update-<slug>`, so a
blocked update holds back only its own skill — **no lockfile, no sync bot, no custom metadata.** Never hand-edit anything inside a bundled skill — not the `SKILL.md`, and not the
`references/`, `scripts/` and `assets/` files beside it, which are equally the upstream's and equally
Expand All @@ -143,9 +143,13 @@ distributed notice. A changed notice or incomplete read refuses validation; refr
a reviewed curation change rather than replacing the notice silently. Run
`bash scripts/check-matt-skill-license.test.sh` for its offline source and notice regressions.
For a portfolio-owned repair, dispatch `update-agent-skills.yaml` with
`scope=agentic-engineering` to update only that plugin's skills through the same programmed
PRs. The default `all` scope and scheduled updates cover the full catalogue. Unsupported
`scope=agentic-engineering` or `scope=engineering-practices` to update only the selected plugin's
skills through the same programmed, per-skill PRs. Each scope retains the canonical branch
identity and existing one-skill edit boundary. The default `all` scope and scheduled updates
cover the full catalogue. Unsupported
scope observations refuse before the updater starts.
All scopes share one non-cancelling workflow queue, including their digest, version and release-note
follow-ups, so overlapping selections cannot rewrite the same update branch concurrently.
`guard-bundled-skill-edits.sh` covers the rest of the tree: a PR that changes any file inside a
synced skill fails and names the upstream to fix it in, so the edit is refused at review instead of
being silently reverted by the next sync. The programmed sync PR is exempt for its own skill, a wholly new skill
Expand Down
1 change: 1 addition & 0 deletions docs/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ complete inventory; read a script's header for its arguments and safeguards.
| Check a change | Follow the [validation steps](validation.md), including dependency installation |
| Update versions and release notes | Use [bump-plugin-version.sh](../scripts/bump-plugin-version.sh) and add a matching changelog entry; skill syncs use [plugin-changelog.sh write](../scripts/plugin-changelog.sh) |
| Refresh generated resource digests | [refresh-desired-state-digests.sh](../scripts/refresh-desired-state-digests.sh) |
| Synchronize one curated plugin | Dispatch [Update Agent Skills](../.github/workflows/update-agent-skills.yaml) with `agentic-engineering` or `engineering-practices`; [skill-update-scope.sh](../scripts/skill-update-scope.sh) resolves only declared selections before the normal per-skill updater runs. Default and scheduled `all` updates still cover the full catalogue. |
| Prepare or inspect a marketplace release | [Release guide](marketplace-releases.md) and [prepare-marketplace-release.sh](../scripts/prepare-marketplace-release.sh) |
| Propose or publish a marketplace release | [Release guide](marketplace-releases.md), which explains the separate opt-in steps and recovery |
| Recheck open pull requests after changing CI | [recheck-open-prs.sh](../scripts/recheck-open-prs.sh) |
Expand Down
2 changes: 1 addition & 1 deletion plugins/engineering-practices/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "engineering-practices",
"description": "Git commits, conventional releases, refactoring, test-driven development, and engineering ways of working skills",
"version": "1.1.2",
"version": "1.1.3",
"author": {
"name": "devantler-tech",
"url": "https://github.com/devantler-tech"
Expand Down
4 changes: 4 additions & 0 deletions plugins/engineering-practices/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog — `engineering-practices`

## 1.1.3 — 2026-10-23

**Changed** — sync `ways-of-working` from `https://github.com/devantler-tech/agent-skills` at `refs/tags/v1.27.1`.

## 1.1.2 — 2026-10-15

**Changed** — sync `write-readme` from `https://github.com/devantler-tech/agent-skills` at `refs/tags/v1.24.1`.
Expand Down
2 changes: 1 addition & 1 deletion plugins/engineering-practices/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "engineering-practices",
"description": "Git commits, conventional releases, refactoring, test-driven development, and engineering ways of working skills",
"version": "1.1.2",
"version": "1.1.3",
"author": {
"name": "devantler-tech",
"url": "https://github.com/devantler-tech"
Expand Down
14 changes: 10 additions & 4 deletions plugins/engineering-practices/skills/ways-of-working/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ description: 'Codifies devantler-tech engineering practices: agent-first develop
license: Apache-2.0
metadata:
github-path: ways-of-working
github-ref: refs/tags/v1.5.0
github-ref: refs/tags/v1.27.1
github-repo: https://github.com/devantler-tech/agent-skills
github-tree-sha: 219a45e80e25b47cc23dcfed9febd526655e624c
github-tree-sha: d079ead0a238b051a081616f3bcb0c0b557f518d
name: ways-of-working
---
# Ways of Working
Expand Down Expand Up @@ -90,7 +90,13 @@ Use **GitHub Flow**:

## CI/CD Pipeline

Each repository has two core workflow files — `ci.yaml` and `cd.yaml` — plus a thin `release.yaml` that calls a reusable workflow (see [Releases](#releases)). Reusable logic is extracted into local GitHub Actions under `.github/actions/`:
Keep ordinary workflow entrypoints in the repository that owns their outcome, normally `ci.yaml`, `cd.yaml` and, where needed, `release.yaml`. Choose ownership by the actual production callers:

- **Organization-required workflows:** cross-product PR checks such as shared scanning and linting. A guard used by one product belongs in that product, enforced through its repository ruleset and native required checks.
- **Reusable workflows:** job-level logic called by at least two genuine production jobs. Two real entrypoints in one repository can qualify; matrix cells, test fixtures and invented callers do not establish reuse.
- **Ordinary workflows:** callsites for reusable jobs, or implementations used in one place. Keep a single-use implementation in its calling repository rather than exporting it from a shared automation repository.

Split manageable step-level units into local GitHub Actions under `.github/actions/` when useful:

- **Composite actions** — for simple, self-contained steps.
- **TypeScript actions** — for anything complex, because they are locally testable and avoid hard-to-read bash embedded in YAML.
Expand All @@ -114,7 +120,7 @@ Each repository has two core workflow files — `ci.yaml` and `cd.yaml` — plus

### Releases

Releases are automated via the [`devantler-tech/actions/.github/workflows/create-release.yaml`](https://github.com/devantler-tech/actions/blob/main/.github/workflows/create-release.yaml) reusable workflow. It runs [semantic-release](https://semantic-release.gitbook.io/) on `push` to `main`, calculates the next semver from [conventional commit](https://www.conventionalcommits.org/) history, and creates the tag + GitHub release — which in turn triggers the CD pipeline above.
Repositories using the shared release job invoke [`devantler-tech/.github/.github/workflows/create-release.yaml`](https://github.com/devantler-tech/.github/blob/main/.github/workflows/create-release.yaml) from a repository-owned caller that handles `push` to `main`. The shared workflow runs [semantic-release](https://semantic-release.gitbook.io/), calculates the next semver from [conventional commit](https://www.conventionalcommits.org/) history, and creates the tag and GitHub release, which can trigger the repository's CD pipeline. Preserve a repository-owned release implementation when its requirements differ; a release entrypoint does not by itself justify a new reusable workflow.

For application publishing, always use upstream releasers — e.g. [GoReleaser](https://goreleaser.com/) for Go or [dotnet-releaser](https://github.com/xoofx/dotnet-releaser) for .NET — rather than hand-rolling publish scripts.

Expand Down
1 change: 1 addition & 0 deletions scripts/skill-update-scope.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ refuse() { printf 'skill update scope: unsupported dispatch\n' >&2; exit 2; }
case "$1:${2:-all}" in
schedule:all|workflow_dispatch:all) printf 'dir=plugins\nbranch=deps/agent-skills-update\n' ;;
workflow_dispatch:agentic-engineering) printf 'dir=plugins/agentic-engineering/skills\nbranch=deps/agent-skills-update-agentic-engineering-skills\n' ;;
workflow_dispatch:engineering-practices) printf 'dir=plugins/engineering-practices/skills\nbranch=deps/agent-skills-update-engineering-practices-skills\n' ;;
*) refuse ;;
esac
31 changes: 27 additions & 4 deletions scripts/skill-update-scope.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,38 @@ bash "$here/skill-update-scope.sh" workflow_dispatch all > "$work/out"
[[ $(cat "$work/out") == $'dir=plugins\nbranch=deps/agent-skills-update' ]]
bash "$here/skill-update-scope.sh" workflow_dispatch agentic-engineering > "$work/out"
[[ $(cat "$work/out") == $'dir=plugins/agentic-engineering/skills\nbranch=deps/agent-skills-update-agentic-engineering-skills' ]]
for scope in unknown ../outside $'agentic-engineering\ndir=plugins'; do
bash "$here/skill-update-scope.sh" workflow_dispatch engineering-practices > "$work/out"
[[ $(cat "$work/out") == $'dir=plugins/engineering-practices/skills\nbranch=deps/agent-skills-update-engineering-practices-skills' ]]
# A scoped producer must still create the canonical per-skill branch accepted
# by the existing actor-and-one-skill guard, not a broader exemption.
branch=$(sed -n 's/^branch=//p' "$work/out")
[[ "$branch-ways-of-working" == deps/agent-skills-update-engineering-practices-skills-ways-of-working ]]
for scope in unknown ../outside $'agentic-engineering\ndir=plugins' $'engineering-practices\nbranch=other'; do
rc=0
bash "$here/skill-update-scope.sh" workflow_dispatch "$scope" > "$work/out" 2> "$work/err" || rc=$?
[[ $rc == 2 && ! -s $work/out && -s $work/err ]]
done
rc=0
bash "$here/skill-update-scope.sh" schedule agentic-engineering > "$work/out" 2> "$work/err" || rc=$?
[[ $rc == 2 && ! -s $work/out ]]
for scope in agentic-engineering engineering-practices; do
rc=0
bash "$here/skill-update-scope.sh" schedule "$scope" > "$work/out" 2> "$work/err" || rc=$?
[[ $rc == 2 && ! -s $work/out ]]
done
rc=0
bash "$here/skill-update-scope.sh" pull_request all > "$work/out" 2> "$work/err" || rc=$?
[[ $rc == 2 && ! -s $work/out ]]
printf 'skill update scopes: PASS (9 cases)\n'
options=$(yq -o=json '.on.workflow_dispatch.inputs.scope' "$here/../.github/workflows/update-agent-skills.yaml")
printf '%s\n' "$options" | jq -se 'length == 1 and (.[0] | .type == "choice" and .default == "all" and
(.options | sort) == ["agentic-engineering","all","engineering-practices"])' > /dev/null
workflow=$(yq -o=json '.' "$here/../.github/workflows/update-agent-skills.yaml")
if ! printf '%s\n' "$workflow" | jq -se 'length == 1 and (.[0].concurrency == {
group:"agent-plugins-skill-sync-${{ github.repository }}",
"cancel-in-progress":false, queue:"max"})' > /dev/null; then
printf 'skill update scopes: require one non-cancelling queue across all scopes and follow-up jobs\n' >&2
exit 1
fi
printf '%s\n' "$workflow" | jq -se 'length == 1 and (.[0] |
.permissions == {} and .jobs.scope.permissions == {contents:"read"} and
.jobs.update.permissions == {contents:"write","pull-requests":"write"} and
.jobs."bump-versions".permissions == {contents:"read"})' > /dev/null
printf 'skill update scopes: PASS (declared selections, canonical branch and fail-closed dispatch)\n'
Loading