Jaypore CI

> Jaypore CI: Minimal, Offline, Local CI system.
Log | Files | Refs | README | LICENSE

commit 5fd3252890f9f6d9433fe3cf728d4da919fd61c7
parent 41e49247af2ee8f30b45cad1d31454498cdda584
Author: Arjoonn@exe.dev <arjoonn+exe.dev@midpathsoftware.com>
Date:   Wed, 25 Feb 2026 07:17:35 +0000

Remove single-run mode, always use unique run IDs

- Every run now gets a unique ID (timestamp-random)
- Results always stored in refs/jci-runs/<commit>/<runid>
- Remove --multi flag (now the default behavior)
- Backward compatible: still reads old refs/jci/ refs

Co-authored-by: Shelley <shelley@exe.dev>

Diffstat:
Mcmd/git-jci/main.go | 7+++----
Minternal/jci/cron.go | 2+-
Minternal/jci/git.go | 12+++---------
Minternal/jci/run.go | 36++++++------------------------------
4 files changed, 13 insertions(+), 44 deletions(-)

diff --git a/cmd/git-jci/main.go b/cmd/git-jci/main.go @@ -51,8 +51,7 @@ func printUsage() { Usage: git jci <command> [options] Commands: - run [--multi] Run CI for the current commit and store results - --multi: Allow multiple runs per commit (uses timestamp ID) + run Run CI for the current commit and store results web Start a web server to view CI results push Push CI results to remote pull Pull CI results from remote @@ -60,6 +59,6 @@ Commands: cron ls List cron jobs for this repository cron sync Sync .jci/crontab with system cron -CI results are stored in refs/jci/<commit> namespace. -With --multi, results are stored in refs/jci/<commit>/<runid>.`) +CI results are stored in refs/jci-runs/<commit>/<runid> namespace. +Each run gets a unique ID (timestamp + random suffix).`) } diff --git a/internal/jci/cron.go b/internal/jci/cron.go @@ -136,7 +136,7 @@ func cronSync() error { if e.Branch != "" { cmd += fmt.Sprintf("git checkout --quiet %s 2>/dev/null && git pull --quiet 2>/dev/null; ", shellEscape(e.Branch)) } - cmd += fmt.Sprintf("%s run --multi", jciBinary) + cmd += fmt.Sprintf("%s run", jciBinary) comment := e.Name if comment == "" { diff --git a/internal/jci/git.go b/internal/jci/git.go @@ -37,8 +37,7 @@ func RefExists(ref string) bool { return err == nil } -// StoreTree stores a directory as a tree object and creates a commit under refs/jci/<commit> -// If runID is non-empty, stores under refs/jci/<commit>/<runID> instead +// StoreTree stores a directory as a tree object and creates a commit under refs/jci-runs/<commit>/<runID> func StoreTree(dir string, commit string, message string, runID string) error { repoRoot, err := GetRepoRoot() if err != nil { @@ -64,13 +63,8 @@ func StoreTree(dir string, commit string, message string, runID string) error { } commitID := strings.TrimSpace(string(commitOut)) - // Update ref - // Single runs: refs/jci/<commit> - // Multi runs: refs/jci-runs/<commit>/<runid> - ref := "refs/jci/" + commit - if runID != "" { - ref = "refs/jci-runs/" + commit + "/" + runID - } + // Update ref: refs/jci-runs/<commit>/<runid> + ref := "refs/jci-runs/" + commit + "/" + runID if _, err := git("update-ref", ref, commitID); err != nil { return fmt.Errorf("git update-ref: %v", err) } diff --git a/internal/jci/run.go b/internal/jci/run.go @@ -11,16 +11,8 @@ import ( ) // Run executes CI for the current commit -// With --multi flag, allows multiple runs per commit (uses timestamp+random suffix) +// Each run gets a unique ID (timestamp+random suffix) stored in refs/jci-runs/<commit>/<runid> func Run(args []string) error { - // Parse flags - multiRun := false - for _, arg := range args { - if arg == "--multi" { - multiRun = true - } - } - // Get current commit commit, err := GetCurrentCommit() if err != nil { @@ -29,19 +21,9 @@ func Run(args []string) error { fmt.Printf("Running CI for commit %s\n", commit[:12]) - // Generate run ID for multi-run mode - var runID string - if multiRun { - runID = generateRunID() - fmt.Printf("Run ID: %s\n", runID) - } else { - // Check if CI already ran for this commit (single-run mode) - ref := "refs/jci/" + commit - if RefExists(ref) { - fmt.Printf("CI results already exist for %s\n", commit[:12]) - return nil - } - } + // Generate unique run ID + runID := generateRunID() + fmt.Printf("Run ID: %s\n", runID) repoRoot, err := GetRepoRoot() if err != nil { @@ -81,10 +63,7 @@ func Run(args []string) error { } // Store results in git - msg := fmt.Sprintf("CI results for %s", commit[:12]) - if runID != "" { - msg = fmt.Sprintf("CI results for %s (run %s)", commit[:12], runID) - } + msg := fmt.Sprintf("CI results for %s (run %s)", commit[:12], runID) if storeErr := StoreTree(outputDir, commit, msg, runID); storeErr != nil { return fmt.Errorf("failed to store CI results: %w", storeErr) } @@ -92,10 +71,7 @@ func Run(args []string) error { // Clean up the output directory after storing in git os.RemoveAll(outputDir) - ref := "refs/jci/" + commit - if runID != "" { - ref = "refs/jci-runs/" + commit + "/" + runID - } + ref := "refs/jci-runs/" + commit + "/" + runID fmt.Printf("CI results stored at %s\n", ref) if err != nil { return fmt.Errorf("CI failed (results stored): %w", err)