Reusable GitHub Actions workflows for personal projects.
Automated versioning and changelog generation for Bun/TypeScript projects.
Usage (basic):
# .github/workflows/release.yml
name: Release
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: write
issues: write
pull-requests: write
jobs:
release:
uses: detailobsessed/ci-components/.github/workflows/semantic-release-bun.yml@main
secrets: inheritUsage (gated on CI):
To ensure releases only happen after CI passes:
# .github/workflows/release.yml
name: Release
on:
workflow_run:
workflows: ["CI"]
branches: [main]
types: [completed]
workflow_dispatch:
permissions:
contents: write
issues: write
pull-requests: write
jobs:
release:
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
uses: detailobsessed/ci-components/.github/workflows/semantic-release-bun.yml@main
secrets: inheritThis prevents broken commits from being released before CI catches failures.
Inputs:
| Input | Default | Description |
|---|---|---|
node-version |
22 |
Node.js version (semantic-release v25 requires ^22.14.0) |
bun-version |
latest |
Bun version |
build-command |
bun run build |
Build command to run before release |
Required in calling repo:
.releaserc.json- semantic-release configurationpackage.jsonwith semantic-release dev dependencies
Publish to npm with OIDC provenance (no NPM_TOKEN secret needed).
⚠️ Important: Do NOT useon: release: types: [published]as the trigger. Releases created withGITHUB_TOKEN(which semantic-release uses) do NOT emitreleaseevents. Useworkflow_runinstead.
Usage:
# .github/workflows/npm-publish.yml
name: NPM Publish
on:
workflow_run:
workflows: ["Release"]
branches: [main]
types: [completed]
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
publish:
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
uses: detailobsessed/ci-components/.github/workflows/npm-publish-bun.yml@mainInputs:
| Input | Default | Description |
|---|---|---|
node-version |
24 |
Node.js version (24+ required for OIDC) |
bun-version |
latest |
Bun version |
build-command |
bun run build |
Build command to run before publish |
Prerequisites:
- Configure npm trusted publishing for your package at npmjs.com
- Set
"publishConfig": { "access": "public" }inpackage.jsonfor scoped packages
Note: Provenance attestations are automatically generated when publishing via trusted publishing from public repos.
- Add
.releaserc.json:
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
["@semantic-release/npm", { "npmPublish": false }],
["@semantic-release/git", {
"assets": ["package.json", "CHANGELOG.md"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}],
"@semantic-release/github"
]
}- Install dependencies:
bun add -d semantic-release @semantic-release/changelog @semantic-release/git- Create
release.ymlworkflow calling the semantic-release workflow.
Use the same setup as above, plus:
- Create
npm-publish.ymlworkflow calling the npm-publish workflow. - Configure npm trusted publishing for your GitHub repo.
Automated versioning and changelog generation for Python projects using uv.
Usage:
# .github/workflows/release.yml
name: release
on:
workflow_run:
workflows: [ci]
types: [completed]
branches: [main]
workflow_dispatch:
permissions:
contents: write
id-token: write
jobs:
release:
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
uses: detailobsessed/ci-components/.github/workflows/semantic-release-uv.yml@main
with:
pypi-publish: "false" # See PyPI publishing section below
secrets: inherit
# PyPI publish must be in calling workflow for trusted publishing to work
pypi-publish:
needs: release
if: needs.release.outputs.released == 'true' && vars.PYPI_PUBLISH == 'true'
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/your-package
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv build
- run: uv publishInputs:
| Input | Default | Description |
|---|---|---|
python-version |
3.13 |
Python version |
runner |
blacksmith-4vcpu-ubuntu-2404 |
GitHub Actions runner |
pypi-publish |
false |
PyPI publish mode: true, test, or false |
Outputs:
| Output | Description |
|---|---|
released |
true if a new release was created, false otherwise |
Required in calling repo:
pyproject.tomlwith[tool.semantic_release]configurationpython-semantic-releasein dev dependencies (uv add --group maintain python-semantic-release)
⚠️ PyPI Trusted Publishing: Thepypi-publishinput in this workflow will NOT work with PyPI trusted publishing because OIDC tokens from reusable workflows contain the reusable workflow's repository in the claims, not the calling repository. You MUST add a separatepypi-publishjob in your calling workflow as shown above.
Publish MCP servers to the official MCP Registry using OIDC authentication.
Usage:
# .github/workflows/mcp-registry-publish.yml
name: MCP Registry Publish
on:
workflow_run:
workflows: ["NPM Publish"]
types: [completed]
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
publish:
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
uses: detailobsessed/ci-components/.github/workflows/mcp-registry-publish-bun.yml@mainInputs:
| Input | Default | Description |
|---|---|---|
runner |
blacksmith-4vcpu-ubuntu-2404 |
Runner to use (Blacksmith works with OIDC) |
Prerequisites:
- Create
server.jsonwith MCP server metadata (schema) - For npm packages: Add
mcpNametopackage.json:"mcpName": "io.github.{org}/{server-name}" - For PyPI packages: Add
<!-- mcp-name: io.github.{org}/{server-name} -->to README.md (ownership validation) - For PyPI packages: Include
versioninpackages[]array (required despite schema saying optional) - For org namespaces, ensure your org membership is public at
https://github.com/orgs/{org}/people - First publish must be done manually:
mcp-publisher login github && mcp-publisher publish
Tip: Use @semantic-release/exec (npm) or version_variables (python-semantic-release) to keep server.json version in sync:
["@semantic-release/exec", {
"prepareCmd": "sed -i'' -e 's/\"version\": \"[^\"]*\"/\"version\": \"${nextRelease.version}\"/g' server.json"
}]Automatically merge Dependabot PRs for minor and patch updates.
Usage:
# .github/workflows/auto-merge.yml
name: Auto Merge Dependabot PRs
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: write
pull-requests: write
jobs:
auto-merge:
uses: detailobsessed/ci-components/.github/workflows/auto-merge-dependabot.yml@main
secrets: inheritInputs:
| Input | Default | Description |
|---|---|---|
merge-method |
merge |
Merge method (merge, squash, rebase) |
update-types |
minor,patch |
Update types to auto-merge (comma-separated) |