Skip to content
Merged
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
26 changes: 26 additions & 0 deletions .github/actions/bootstrap-tools/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: bootstrap-tools
description: Install CI helper tools
runs:
using: composite
steps:
- name: Install just
uses: extractions/setup-just@v3

- name: Install cocogitto
shell: bash
run: |
set -euo pipefail
BIN_DIR="$HOME/.local/bin"
CUR_DIR=$(pwd)
VERSION=6.5.0
mkdir -p "$BIN_DIR"
if command -v cog >/dev/null 2>&1; then exit 0; fi
PLATFORM="unknown-linux-musl"
ARCH="x86_64"
TAR="cocogitto-$VERSION-$ARCH-$PLATFORM.tar.gz"
echo "Downloading cocogitto version $VERSION for $ARCH-$PLATFORM from https://github.com/cocogitto/cocogitto/releases/download/$VERSION/$TAR"
cd "$BIN_DIR" || exit
curl -OL https://github.com/cocogitto/cocogitto/releases/download/"$VERSION"/"$TAR"
tar --strip-components=1 -xzf $TAR "$ARCH-$PLATFORM/cog"
cd "$CUR_DIR" || exit
cog --version
33 changes: 33 additions & 0 deletions .github/actions/bot-setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: bot-setup
description: bot-setup
runs:
using: "composite"
steps:
- name: GitHub Actions Bot Configuration
id: bot_config
env:
GITHUB_BOT_EMAIL: "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com"
GITHUB_BOT_USERNAME: "${{ github.actor }}"
shell: bash -l {0}
run: |
#!/usr/bin/env bash

set -euo pipefail

echo "GITHUB_BOT_EMAIL=${{ env.GITHUB_BOT_EMAIL }}" >> $GITHUB_ENV
echo "GITHUB_BOT_USERNAME=${{ env.GITHUB_BOT_USERNAME }}" >> $GITHUB_ENV

git config --global author.email "${{ env.GITHUB_BOT_EMAIL }}"
git config --global author.name "${{ env.GITHUB_BOT_USERNAME }}"
git config --global committer.email "${{ env.GITHUB_BOT_EMAIL }}"
git config --global committer.name "${{ env.GITHUB_BOT_USERNAME }}"
git config --global init.defaultBranch ${{ github.event.repository.default_branch }}
git config --global pull.ff only
git config --global pull.rebase true
git config --global push.autosetupremote true
git config --global push.followTags true
git config --global user.email "${{ env.GITHUB_BOT_EMAIL }}"
git config --global user.name "${{ env.GITHUB_BOT_USERNAME }}"

echo "bot_email=${{ env.GITHUB_BOT_EMAIL }}" >> $GITHUB_OUTPUT
echo "bot_user=${{ env.GITHUB_BOT_USERNAME }}" >> $GITHUB_OUTPUT
24 changes: 24 additions & 0 deletions .github/coda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,27 @@ dependabot_security_updates: true
# 1Password secrets sync (optional)
secrets_tags: claylo-github-actions
secrets_app: actions

rulesets:
- name: Protect main branch
target: branch # branch or tag
enforcement: active # active, evaluate, or disabled
conditions:
ref_name:
include:
- "~DEFAULT_BRANCH" # or: refs/heads/main, refs/heads/release/*
exclude: []
rules:
- type: pull_request
parameters:
required_approving_review_count: 0
dismiss_stale_reviews_on_push: true
require_code_owner_review: false
- type: required_status_checks
parameters:
strict_required_status_checks_policy: true
required_status_checks:
- context: ci/check
- type: non_fast_forward # Prevent force pushes
- type: deletion # Prevent branch deletion
- type: required_linear_history
26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,29 @@ jobs:
with:
additional_files: 'git-pm'
severity: warning

release:
name: Auto Release
needs: [check]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.RELEASE_TOKEN }}
- name: GitHub Actions Bot Setup
uses: ./.github/actions/bot-setup

- name: Bootstrap tools
uses: ./.github/actions/bootstrap-tools

- name: Bump version (if releasable commits exist)
run: |
if cog bump --auto --dry-run 2>/dev/null; then
echo "Releasable commits found, bumping..."
cog bump --auto
else
echo "No releasable commits since last tag, skipping release"
fi
59 changes: 59 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Release

on:
workflow_dispatch:
push:
tags:
- "v*"

permissions:
contents: write
discussions: write

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: GitHub Actions Bot Setup
uses: ./.github/actions/bot-setup

- name: Bootstrap tools
uses: ./.github/actions/bootstrap-tools

- name: Build
run: just build

- name: Verify build
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
echo "Building release v$VERSION"
./git-pm --version

- name: Generate release notes
run: |
cog changelog --at "$GITHUB_REF_NAME" > RELEASE_NOTES.md
cat >> RELEASE_NOTES.md << 'EOF'

## Installation

```bash
brew install claylo/brew/git-pm
```

Or download the `git-pm` script and place it in your PATH.

## Already Installed? Upgrade

```bash
brew upgrade git-pm
```
EOF

- name: Create Release
uses: softprops/action-gh-release@v2
with:
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
files: git-pm
body_path: RELEASE_NOTES.md
discussion_category_name: announcements
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.DS_Store
commit.txt
.claude/
33 changes: 33 additions & 0 deletions .justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# git-pm justfile
# https://github.com/casey/just

set shell := ["bash", "-euo", "pipefail", "-c"]

# Default recipe: show available tasks
default:
@just --list

# Validate script with shellcheck
check:
shellcheck git-pm

# "Build" the script (inject version, validate, make executable)
build: check
#!/usr/bin/env bash
set -euo pipefail
if [[ -f VERSION ]]; then
version=$(cat VERSION)
sed "s/(development)/$version/" git-pm > git-pm.tmp
mv git-pm.tmp git-pm
echo "Injected version: $version"
fi
chmod +x git-pm
echo "Build complete: git-pm validated and executable"

# Show current version
version:
@./git-pm --version

# Run the script (for testing)
run *ARGS:
./git-pm {{ARGS}}
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0
99 changes: 99 additions & 0 deletions cog.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# =============================================================================
# Cocogitto Configuration
# =============================================================================
#
# Cocogitto (cog) enforces Conventional Commits and automates versioning.
# Full documentation: https://docs.cocogitto.io/
#
# Quick reference:
# cog check - Verify all commits follow conventional format
# cog bump --auto - Bump version based on commit types (feat=minor, fix=patch)
# cog bump --major - Force a major version bump
# cog changelog - Generate/update CHANGELOG.md
# cog install-hook - Install git hooks defined in this file
#
# =============================================================================

# -----------------------------------------------------------------------------
# Commit Validation Settings
# -----------------------------------------------------------------------------

# Skip merge commits when validating commit messages.
# Merge commits are auto-generated by git and don't follow conventional format.
ignore_merge_commits = true

# Only check commits since the latest version tag.
# Avoids failing on legacy commits with non-conventional messages.
from_latest_tag = true

# Only allow version bumps from these branches.
# Prevents accidental releases from feature branches.
branch_whitelist = ["main"]

# -----------------------------------------------------------------------------
# Version Tag Settings
# -----------------------------------------------------------------------------

# Prefix for version tags (e.g., "v1.2.3" instead of "1.2.3").
# This is the most common convention and works well with GitHub releases.
tag_prefix = "v"

# Generate changelog
disable_changelog = false

# -----------------------------------------------------------------------------
# Bump Hooks
# -----------------------------------------------------------------------------
#
# Hooks run during `cog bump`. Available variables:
# {{latest}} - Current version before bump (e.g., "1.2.3")
# {{version}} - New version after bump (e.g., "1.3.0")
#
# Hook execution order:
# 1. pre_bump_hooks run
# 2. CHANGELOG.md is generated/updated
# 3. Version tag is created
# 4. post_bump_hooks run
#
# If any hook fails (non-zero exit), the bump is aborted.
# -----------------------------------------------------------------------------

pre_bump_hooks = [
# Update VERSION file
"echo {{version}} > VERSION",
"echo 'bumping from {{latest|0.0.0}} to {{version}}'",
# Rebuild with new version
"just build",
# Stage VERSION and built script (gh-coda must be in repo for gh ext install)
"git add VERSION git-pm",
]

# Post-bump hooks run after the tag is created
post_bump_hooks = [
"git push",
"git push origin v{{version}}",
]

[changelog]
path = "CHANGELOG.md"
template = "remote"
remote = "github.com"
repository = "git-pm"
owner = "claylo"

# Map commit types to changelog sections
[commit_types]
feat = { changelog_title = "Features" }
fix = { changelog_title = "Bug Fixes" }
docs = { changelog_title = "Documentation" }
style = { changelog_title = "Style" }
refactor = { changelog_title = "Refactoring" }
perf = { changelog_title = "Performance" }
# test = "Tests"
build = { changelog_title = "Build" }
ci = { omit_from_changelog = true }
# chore = "Chores"
# Maintenance tasks (deps, tooling) - don't clutter the changelog
chore = { omit_from_changelog = true }
# Test changes rarely interest end users
test = { omit_from_changelog = true }