mirror of
https://github.com/anthonyoteri/dredge.git
synced 2026-06-05 15:26:53 -04:00
ci: overhaul CI/CD pipeline and add tooling configs
- Add ci.yml: test matrix (ubuntu/macos/windows), lint, conventional commits check (cocogitto), cargo-deny, MSRV, and semver jobs - Add release.yml: tag-triggered publish to crates.io + GitHub release - Remove stale rust.yml and rust-clippy.yml workflows - Add deny.toml for cargo-deny license/advisory/ban/source checks - Add cog.toml for cocogitto conventional commits and changelog generation - Add Justfile with test, check, fmt, commits, release, push-tag targets - Add CHANGELOG.md seed file - Add PULL_REQUEST_TEMPLATE.md with conventional commits checklist - Update dependabot.yml: weekly schedule with grouped patch/minor updates
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
# Justfile for dredge
|
||||
# Install just: https://just.systems
|
||||
|
||||
# Default: list available recipes
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Run the full test suite
|
||||
test:
|
||||
cargo test
|
||||
|
||||
# Check formatting and lints (mirrors CI)
|
||||
check:
|
||||
cargo fmt --check
|
||||
cargo clippy --all-targets -- -W clippy::pedantic
|
||||
|
||||
# Auto-format the source
|
||||
fmt:
|
||||
cargo fmt
|
||||
|
||||
# Validate conventional commit history
|
||||
commits:
|
||||
cog check
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Release
|
||||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
# Two-step process to work with branch protection on master:
|
||||
#
|
||||
# Step 1 — just release
|
||||
# Runs pre-flight checks, calls `cog bump --auto` on a local release
|
||||
# branch, opens a PR. Review and merge the PR normally.
|
||||
#
|
||||
# Step 2 — just push-tag
|
||||
# After the PR is merged, pulls master, tags the merge commit with the
|
||||
# version from Cargo.toml, and pushes the tag.
|
||||
# The tag push triggers release.yml which publishes to crates.io.
|
||||
#
|
||||
# Prerequisites:
|
||||
# - `cocogitto` installed: cargo install cocogitto
|
||||
# - `gh` CLI installed and authenticated: https://cli.github.com
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Step 1: open a release PR.
|
||||
#
|
||||
# Runs pre-flight checks, bumps the version on a release branch,
|
||||
# generates CHANGELOG.md, and opens a pull request against master.
|
||||
# After the PR is merged, run `just push-tag` to trigger the publish.
|
||||
release:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Guard: must be on master.
|
||||
branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [[ "$branch" != "master" ]]; then
|
||||
echo "error: releases must be cut from master (currently on '$branch')" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Guard: working tree must be clean.
|
||||
if ! git diff --quiet || ! git diff --cached --quiet; then
|
||||
echo "error: working tree has uncommitted changes; commit or stash them first" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Guard: local master must not be behind origin.
|
||||
git fetch --quiet origin master
|
||||
if [[ $(git rev-list --count HEAD..origin/master) -gt 0 ]]; then
|
||||
echo "error: local master is behind origin/master; run 'git pull' first" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run the full test suite before touching anything.
|
||||
echo "==> Running tests..."
|
||||
cargo test
|
||||
|
||||
# Check formatting and lints.
|
||||
echo "==> Checking formatting and lints..."
|
||||
cargo fmt --check
|
||||
cargo clippy --all-targets -- -W clippy::pedantic
|
||||
|
||||
# Determine the next version without making any changes yet.
|
||||
# cog bump --auto --dry-run prints e.g. "v0.1.0" to stdout.
|
||||
echo "==> Determining next version..."
|
||||
next_version=$(cog bump --auto --dry-run)
|
||||
echo " Next version: ${next_version}"
|
||||
|
||||
# Create and switch to a release branch.
|
||||
release_branch="release/${next_version}"
|
||||
git checkout -b "${release_branch}"
|
||||
|
||||
# Bump version, generate CHANGELOG.md, commit, and create the local tag.
|
||||
# cog bump --auto:
|
||||
# - Updates the version field in Cargo.toml
|
||||
# - Writes CHANGELOG.md
|
||||
# - Creates a commit "chore(version): bump to vX.Y.Z"
|
||||
# - Creates an annotated tag vX.Y.Z (local only until push-tag)
|
||||
echo "==> Bumping version with cog..."
|
||||
cog bump --auto
|
||||
|
||||
# Push the release branch (not the tag — that comes after PR merge).
|
||||
echo "==> Pushing release branch..."
|
||||
git push -u origin "${release_branch}"
|
||||
|
||||
# Open the pull request.
|
||||
echo "==> Opening pull request..."
|
||||
gh pr create \
|
||||
--title "chore(release): ${next_version}" \
|
||||
--body "$(cat CHANGELOG.md)" \
|
||||
--base master \
|
||||
--head "${release_branch}"
|
||||
|
||||
echo ""
|
||||
echo "==> Release PR opened."
|
||||
echo " Review and merge the PR, then run:"
|
||||
echo ""
|
||||
echo " just push-tag"
|
||||
echo ""
|
||||
echo " to push the tag and trigger the crates.io publish."
|
||||
|
||||
# Step 2: tag master HEAD and push the tag.
|
||||
#
|
||||
# Run this after the release PR has been merged into master.
|
||||
# Pulls the latest master, reads the version from Cargo.toml, creates an
|
||||
# annotated tag on the current HEAD, and pushes it to trigger release.yml.
|
||||
push-tag:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Must be on master.
|
||||
branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [[ "$branch" != "master" ]]; then
|
||||
echo "error: push-tag must be run from master (currently on '$branch')" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pull so we are at the merge commit.
|
||||
echo "==> Pulling latest master..."
|
||||
git pull --ff-only origin master
|
||||
|
||||
# Derive the version from Cargo.toml (set by `cog bump --auto`).
|
||||
version=$(grep '^version' Cargo.toml | head -1 \
|
||||
| sed 's/version = "\(.*\)"/\1/')
|
||||
if [[ -z "$version" ]]; then
|
||||
echo "error: could not read version from Cargo.toml" >&2
|
||||
exit 1
|
||||
fi
|
||||
tag="v${version}"
|
||||
echo "==> Tagging HEAD as ${tag}..."
|
||||
|
||||
# Guard: tag must not already exist on origin.
|
||||
if git ls-remote --tags origin "${tag}" | grep -q "refs/tags/${tag}$"; then
|
||||
echo "error: tag ${tag} already exists on origin" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Delete stale local tag if present (leftover from the release branch).
|
||||
git tag -d "${tag}" 2>/dev/null || true
|
||||
|
||||
# Create a fresh annotated tag on the current (merged) HEAD.
|
||||
git tag -a "${tag}" -m "chore(release): ${tag}"
|
||||
|
||||
echo "==> Pushing tag ${tag}..."
|
||||
git push origin "${tag}"
|
||||
|
||||
echo "==> Done. Monitor the release workflow at:"
|
||||
echo " https://github.com/anthonyoteri/dredge/actions"
|
||||
Reference in New Issue
Block a user