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
56 changes: 56 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,59 @@ jobs:
gh release upload "${{ needs.release.outputs.tag }}" \
parsec-${{ needs.release.outputs.version }}-${{ matrix.target }}.${{ matrix.archive }} \
--clobber

snapshot-docs:
name: Snapshot Versioned Docs
needs: release
if: needs.release.outputs.created == 'true'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: main

- name: Create versioned docs snapshot
env:
VERSION: ${{ needs.release.outputs.version }}
run: |
mkdir -p "docs/v/${VERSION}/guide" "docs/v/${VERSION}/reference"

for file in index.html guide/index.html reference/index.html; do
sed \
-e 's/data-doc-version="latest"/data-doc-version="'"${VERSION}"'"/' \
-e 's|<meta charset="UTF-8">|<meta charset="UTF-8">\n <meta name="robots" content="noindex, follow">|' \
-e 's|href="/git-parsec/"|href="/git-parsec/v/'"${VERSION}"'/"|g' \
-e 's|href="/git-parsec/#|href="/git-parsec/v/'"${VERSION}"'/#|g' \
-e 's|href="/git-parsec/reference/|href="/git-parsec/v/'"${VERSION}"'/reference/|g' \
-e 's|href="/git-parsec/guide/|href="/git-parsec/v/'"${VERSION}"'/guide/|g' \
-e 's|src="demo.gif"|src="/git-parsec/demo.gif"|' \
"docs/${file}" > "docs/v/${VERSION}/${file}"
done

- name: Update versions.json
env:
VERSION: ${{ needs.release.outputs.version }}
run: |
DATE=$(date -u +%Y-%m-%d)
jq --arg ver "$VERSION" --arg date "$DATE" \
'.latest = $ver | .versions = [{"version": $ver, "date": $date, "path": ("/git-parsec/v/" + $ver + "/")}] + .versions' \
docs/versions.json > docs/versions.json.tmp
mv docs/versions.json.tmp docs/versions.json

- name: Update sitemap.xml
env:
VERSION: ${{ needs.release.outputs.version }}
run: |
DATE=$(date -u +%Y-%m-%d)
sed -i '/<\/urlset>/i \
<url>\n <loc>https://erishforg.github.io/git-parsec/v/'"${VERSION}"'/</loc>\n <lastmod>'"${DATE}"'</lastmod>\n <changefreq>never</changefreq>\n <priority>0.3</priority>\n </url>\n <url>\n <loc>https://erishforg.github.io/git-parsec/v/'"${VERSION}"'/guide/</loc>\n <lastmod>'"${DATE}"'</lastmod>\n <changefreq>never</changefreq>\n <priority>0.3</priority>\n </url>\n <url>\n <loc>https://erishforg.github.io/git-parsec/v/'"${VERSION}"'/reference/</loc>\n <lastmod>'"${DATE}"'</lastmod>\n <changefreq>never</changefreq>\n <priority>0.3</priority>\n </url>' docs/sitemap.xml

- name: Commit and push versioned docs
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add docs/v/ docs/versions.json docs/sitemap.xml
git commit -m "docs: snapshot versioned docs for v${VERSION}"
git push origin main
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ Cargo.lock
.env
.parsec/
.omc/
.claude/
demo.mp4
90 changes: 90 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# CLAUDE.md — git-parsec Project Instructions

## Project Overview

- **Name**: git-parsec (binary: `parsec`)
- **Language**: Rust (edition 2021)
- **Repo**: https://github.com/erishforG/git-parsec
- **Docs site**: https://erishforg.github.io/git-parsec/ (GitHub Pages from `docs/` on `main`)

## Branch Strategy

- **Main branch**: `main` — production, auto-releases on push
- **Dev branch**: `develop` — development work
- PRs go from `develop` → `main`
- Default branch prefix: `feature/`

## Release Process

### How Releases Work

Releases are **fully automated via CI** (`.github/workflows/release.yml`). The workflow triggers on every push to `main` and:

1. Reads version from `Cargo.toml`
2. Checks if a git tag for that version already exists
3. If new: creates git tag, publishes to crates.io, creates GitHub Release, builds binaries, and snapshots versioned docs

### NEVER Create Tags Manually

**Do NOT run `git tag` or create tags manually.** The CI workflow handles tag creation automatically. Manually creating tags will cause the release workflow to skip (it checks `if tag exists → skip`).

### How to Release a New Version

1. Bump `version` in `Cargo.toml`
2. Ensure all changes are on `develop`
3. Merge `develop` → `main` via PR
4. CI does the rest automatically

### Pre-Release Checklist (MANDATORY)

**CRITICAL: Do NOT merge to `main` without completing ALL items below. Skipping README or docs updates has caused issues in the past.**

Before merging to `main`, verify:

- [ ] `Cargo.toml` version bumped
- [ ] **`README.md` updated** — new commands, changed flags, feature descriptions, command count
- [ ] **`docs/` pages updated** — this is the public-facing site, must reflect current version
- `docs/index.html` — feature list, command count, examples
- `docs/guide/index.html` — installation, workflows, new features
- `docs/reference/index.html` — all commands with correct options/examples
- `softwareVersion` in structured data (`<script type="application/ld+json">`) matches new version
- [ ] `docs/sitemap.xml` `<lastmod>` dates updated if docs changed
- [ ] Integration tests pass (`cargo test`)
- [ ] `cargo build --release` succeeds

If a new command was added or an existing command changed, README and docs MUST be updated in the same PR. Do not defer documentation to a follow-up.

## Architecture

- Output: `dispatch_output!` macro for Human/Json/Quiet modes
- State: `.parsec/state.json` with file locking (atomic writes via temp+rename)
- Oplog: `.parsec/oplog.json` for undo support
- Config: `~/.config/parsec/config.toml` (TOML format)
- Env vars: centralized in `src/env.rs` with priority-based token resolution
- GitHub Enterprise: host-based API URL routing
- Per-repo tracker overrides: `[repos."owner/repo"]` config section
- Worktree layout: Sibling (default, `../repo.ticket/`) or Internal (`.parsec/workspaces/ticket/`)

## Versioned Documentation

The docs site supports versioned documentation:

- `docs/versions.json` — version manifest (latest version + version list)
- `docs/version-switcher.js` — shared dropdown logic
- `docs/v/{VERSION}/` — versioned snapshots (auto-created by CI on release)
- Versioned pages have `noindex` meta tag and canonical pointing to root
- `demo.gif` is referenced via absolute path (`/git-parsec/demo.gif`), not copied per version

## Testing

- Integration tests: `tests/cli_tests.rs`
- Run: `cargo test`
- Dev deps: assert_cmd, predicates, tempfile

## Code Conventions

- Error handling: `anyhow` for application errors, `thiserror` for library-style enums
- CLI: clap 4 with derive macros
- Async: tokio (full features)
- HTTP: reqwest with rustls-tls
- All commands support `--json` for machine-readable output
77 changes: 76 additions & 1 deletion docs/guide/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-doc-version="latest">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Expand Down Expand Up @@ -944,6 +944,80 @@
transition: opacity 0.5s ease-out, transform 0.5s ease-out;
}
.reveal.visible { opacity: 1; transform: translateY(0); }

/* ================================================
VERSION SWITCHER
================================================ */
.version-switcher {
position: relative;
margin-left: 12px;
}
.version-btn {
background: var(--bg-raised);
color: var(--accent-cyan);
border: 1px solid var(--border-accent);
border-radius: var(--radius-sm);
padding: 4px 10px;
font-family: var(--font-mono);
font-size: 0.8rem;
cursor: pointer;
transition: background 0.2s;
display: flex;
align-items: center;
gap: 2px;
}
.version-btn:hover { background: var(--bg-card); }
.version-arrow { font-size: 0.7rem; }
.version-dropdown {
display: none;
position: absolute;
top: calc(100% + 6px);
left: 0;
background: var(--bg-raised);
border: 1px solid var(--border-accent);
border-radius: var(--radius-sm);
min-width: 160px;
z-index: 1000;
box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.version-dropdown.open { display: block; }
.version-dropdown a {
display: block;
padding: 8px 14px;
color: var(--text-secondary);
text-decoration: none;
font-family: var(--font-mono);
font-size: 0.8rem;
transition: background 0.15s, color 0.15s;
}
.version-dropdown a:hover {
background: var(--bg-card);
color: var(--text-primary);
}
.version-dropdown a.active {
color: var(--accent-cyan);
background: var(--accent-glow);
}
.version-banner {
background: rgba(255, 193, 7, 0.12);
border-bottom: 1px solid rgba(255, 193, 7, 0.3);
color: #ffd54f;
text-align: center;
padding: 8px 16px;
font-family: var(--font-body);
font-size: 0.9rem;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 10000;
}
.version-banner a {
color: #fff;
text-decoration: underline;
margin-left: 4px;
}
.version-banner a:hover { color: var(--accent-cyan); }
</style>
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="git-parsec Guide — Installation and Quick Start">
Expand Down Expand Up @@ -1712,5 +1786,6 @@ <h3>Pre-ship hooks</h3>
sections.forEach(el => scrollObserver.observe(el));
});
</script>
<script src="/git-parsec/version-switcher.js"></script>
</body>
</html>
77 changes: 76 additions & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-doc-version="latest">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Expand Down Expand Up @@ -1461,6 +1461,80 @@
width: 100%;
display: block;
}

/* ================================================
VERSION SWITCHER
================================================ */
.version-switcher {
position: relative;
margin-left: 12px;
}
.version-btn {
background: var(--bg-raised);
color: var(--accent-cyan);
border: 1px solid var(--border-accent);
border-radius: var(--radius-sm);
padding: 4px 10px;
font-family: var(--font-mono);
font-size: 0.8rem;
cursor: pointer;
transition: background 0.2s;
display: flex;
align-items: center;
gap: 2px;
}
.version-btn:hover { background: var(--bg-card); }
.version-arrow { font-size: 0.7rem; }
.version-dropdown {
display: none;
position: absolute;
top: calc(100% + 6px);
left: 0;
background: var(--bg-raised);
border: 1px solid var(--border-accent);
border-radius: var(--radius-sm);
min-width: 160px;
z-index: 1000;
box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.version-dropdown.open { display: block; }
.version-dropdown a {
display: block;
padding: 8px 14px;
color: var(--text-secondary);
text-decoration: none;
font-family: var(--font-mono);
font-size: 0.8rem;
transition: background 0.15s, color 0.15s;
}
.version-dropdown a:hover {
background: var(--bg-card);
color: var(--text-primary);
}
.version-dropdown a.active {
color: var(--accent-cyan);
background: var(--accent-glow);
}
.version-banner {
background: rgba(255, 193, 7, 0.12);
border-bottom: 1px solid rgba(255, 193, 7, 0.3);
color: #ffd54f;
text-align: center;
padding: 8px 16px;
font-family: var(--font-body);
font-size: 0.9rem;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 10000;
}
.version-banner a {
color: #fff;
text-decoration: underline;
margin-left: 4px;
}
.version-banner a:hover { color: var(--accent-cyan); }
</style>
</head>
<body>
Expand Down Expand Up @@ -2179,5 +2253,6 @@ <h3>Start building</h3>
});
</script>

<script src="/git-parsec/version-switcher.js"></script>
</body>
</html>
Loading
Loading