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
73 changes: 14 additions & 59 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,76 +1,31 @@
# Cuts a release from main: tags the current commit and creates the GitHub Release with notes
# from git-cliff. Run it from the Actions tab.
# It creates the tag through the Releases API rather than pushing, because main's ruleset blocks bot pushes,
# so no release commit is made and package.json's version isn't bumped.
# Cuts a release from main with the shared bun-npm-release workflow: bumps the version, updates
# CHANGELOG.md, commits and tags it, publishes to npm and creates the GitHub Release.
# Run it from the Actions tab.
# npm trusted publishing (OIDC) matches this workflow by file name, so keep it `release.yml`.
name: Release

on:
workflow_dispatch:
inputs:
version:
description: Version to release, like 0.2.0. Leave empty to work it out from the commits.
description: Version to release, like 1.2.3. Leave empty to work it out from the commits.
required: false
type: string

permissions:
# Create the tag and the GitHub Release.
contents: write
contents: read
# OIDC token for npm trusted publishing and provenance.
id-token: write

concurrency:
group: release
cancel-in-progress: false

jobs:
release:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
# git-cliff reads every commit and tag since the last release.
fetch-depth: 0
persist-credentials: false

- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.3

- run: bun install --frozen-lockfile

- run: bun run check

- name: Pick the version
id: version
env:
REQUESTED: ${{ inputs.version }}
run: |
latest="$(git describe --tags --abbrev=0 --match 'v[0-9]*' 2> /dev/null || true)"
if [ -n "$REQUESTED" ]; then
version="${REQUESTED#v}"
else
version="$(bunx git-cliff --bumped-version)"
version="${version#v}"
fi
if ! echo "$version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "\"$version\" isn't a version like 1.2.3" >&2
exit 1
fi
# git-cliff returns the latest version when every commit since it is skipped (deps, chores).
if [ "v$version" = "$latest" ]; then
echo "Nothing to release: no feat, fix, perf, docs or breaking commits since $latest" >&2
exit 1
fi
if git rev-parse -q --verify "refs/tags/v$version" > /dev/null; then
echo "Tag v$version already exists" >&2
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Create the release
env:
VERSION: ${{ steps.version.outputs.version }}
GH_TOKEN: ${{ github.token }}
run: |
bunx git-cliff --unreleased --tag "v$VERSION" --strip all > "$RUNNER_TEMP/notes.md"
gh release create "v$VERSION" --target "$GITHUB_SHA" --title "v$VERSION" --notes-file "$RUNNER_TEMP/notes.md"
uses: BrianEstrada/.github/.github/workflows/bun-npm-release.yml@a3365073142d6188b8e60334052183ae289b4ba3 # main
with:
version: ${{ inputs.version }}
app-client-id: ${{ vars.RELEASE_APP_CLIENT_ID }}
secrets:
app-private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ AGENTS.md strategy: this file is for coding agents, and it's loaded into every s

## Rules

- Use Bun for everything (`bun`, `bun run`, `bunx`), not node, npm, ts-node, or dotenv. Bun loads `.env` itself.
- Use Bun for everything (`bun`, `bun run`, `bunx`), not node, npm, ts-node, or dotenv. Bun loads `.env` itself. The one exception is `npm publish` in the release workflow.
- Prefer Bun APIs over npm packages: `` Bun.$`git ...` ``, `Bun.file`, `Bun.serve`.
- Parse data from outside the process (GitHub API, event payloads, harness metadata) with a Zod schema, and get its type from `z.infer`. GitHub responses go through `schema.safeParse` and `unwrapResponse`.
- Keep the reviewer agent in `src/agent/claude-code/claude-code-agent.ts` read-only (`read`, `glob`, `grep`, `permissionMode: "allow-reads"`). Never give it write or shell tools.
Expand All @@ -38,8 +38,8 @@ Before writing or keeping a comment or JSDoc block, walk this:
## Releasing

- Release only when asked. Preview with `bunx git-cliff --bumped-version` and `bun run release-notes`.
- Run `gh workflow run release.yml --ref main` (add `-f version=X.Y.Z` to override), then `gh run watch`. It tags the commit and creates the GitHub Release. Never tag or create releases by hand.
- Notes come from commit subjects (PR titles after a squash merge): `feat`, `fix`, `perf`, `docs` and breaking changes; the rest is skipped. Use those types only for changes the action's users notice.
- Run `gh workflow run release.yml --ref main` (add `-f version=X.Y.Z` to override), then `gh run watch`. The shared `bun-npm-release` workflow bumps `package.json`, prepends to `CHANGELOG.md`, commits `chore(release): vX.Y.Z`, tags, publishes to npm and creates the GitHub Release. Never do any of those steps by hand: don't edit `version`, run `bun run changelog`, tag, or run `npm publish`.
- Notes come from commit subjects (PR titles after a squash merge): `feat`, `fix`, `perf`, `docs` and breaking changes; the rest is skipped. Use those types only for changes the CLI's or action's users notice.

## PRs

Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Changelog

All notable changes to this project are documented here. Generated by [git-cliff](https://git-cliff.org) from the commit history.

<!-- git-cliff: end of header -->

## [0.1.0](https://github.com/BrianEstrada/diffcop/releases/tag/v0.1.0) - 2026-10-11

First release.

### Documentation

- Add diffcop branding ([#4](https://github.com/BrianEstrada/diffcop/pull/4))
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,13 @@ for your subscription and set it as `CLAUDE_CODE_OAUTH_TOKEN`. To pay per token
`ANTHROPIC_API_KEY`.

```bash
git clone https://github.com/BrianEstrada/diffcop.git
cd diffcop
bun install
bun link # puts `diffcop` on your PATH (~/.bun/bin)

cd ../your-repo
diffcop review "review this code"
cd your-repo
bunx diffcop review "review this code"
```

To keep `diffcop` on your PATH, install it with `bun add --global diffcop`. It runs on Bun, so
`npx diffcop` works only where Bun is installed.

## Usage

```bash
Expand Down
2 changes: 0 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion cliff.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# git-cliff config: builds release notes from Conventional Commits. https://git-cliff.org/docs/configuration
# git-cliff config: builds CHANGELOG.md from Conventional Commits. https://git-cliff.org/docs/configuration

[changelog]
header = """
# Changelog

All notable changes to this project are documented here. Generated by [git-cliff](https://git-cliff.org) from the commit history.

<!-- git-cliff: end of header -->
"""
# `--prepend` swaps everything above this marker for the new header.
header_marker = "<!-- git-cliff: end of header -->"
body = """
{% if version -%}
## [{{ version | trim_start_matches(pat="v") }}]\
Expand Down
27 changes: 22 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
{
"name": "diffcop",
"version": "0.1.0",
"private": true,
"description": "An opinionated, local-first AI code reviewer that runs on the coding agent you already use.",
"keywords": [
"ai",
"claude-code",
"cli",
"code-review"
],
"homepage": "https://github.com/BrianEstrada/diffcop#readme",
"bugs": "https://github.com/BrianEstrada/diffcop/issues",
"license": "MIT",
"author": "Brian Estrada",
"repository": {
"type": "git",
"url": "git+https://github.com/BrianEstrada/diffcop.git"
},
"bin": {
"diffcop": "./src/cli.ts"
"diffcop": "src/cli.ts"
},
"files": [
"src",
"!src/**/*.test.ts",
"tsconfig.json"
],
"type": "module",
"imports": {
"#package.json": "./package.json"
Expand All @@ -18,6 +36,7 @@
"lint": "oxlint",
"lint:fix": "oxlint --fix",
"check": "bun run typecheck && bun run lint && bun run fmt:check && bun test --pass-with-no-tests",
"changelog": "if grep -qF \"## [$npm_package_version]\" CHANGELOG.md; then echo \"CHANGELOG.md already has $npm_package_version\"; exit 1; fi; git-cliff --unreleased --tag v$npm_package_version --prepend CHANGELOG.md && oxfmt CHANGELOG.md",
"release-notes": "git-cliff --unreleased --strip all"
},
"dependencies": {
Expand All @@ -43,9 +62,7 @@
"oxfmt": "0.72.0",
"oxlint": "1.87.0",
"oxlint-plugin-deslopify": "0.5.0",
"oxlint-tsgolint": "7.0.2004"
},
"peerDependencies": {
"oxlint-tsgolint": "7.0.2004",
"typescript": "7.0.2"
}
}
Loading