rollout-cli 0.4.2__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/mass-update/SKILL.md +8 -1
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/mass-update/scripts/mass-update.sh +32 -4
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/CHANGELOG.md +6 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/PKG-INFO +1 -1
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/pyproject.toml +1 -1
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_mass_update.py +60 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/uv.lock +1 -1
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/agent-config/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/ask-colleague/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/ask-colleague/prompts/review.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/ask-colleague/prompts/write.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/cicd/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/communicate/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/run-tests/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/spec-to-plan/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/think/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/think/scripts/think.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/version-bump/SKILL.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills.local.yaml.example +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.devague/frames/mass-update-now-clones-each-target-repo-into-a-git.json +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.devague/frames/rollout-cli-ships-rollout-define-an-org-wide-chang.json +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.devague/plans/mass-update-now-clones-each-target-repo-into-a-git.json +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.devague/plans/rollout-cli-ships-rollout-define-an-org-wide-chang.json +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.flake8 +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.github/workflows/publish.yml +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.github/workflows/tests.yml +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.gitignore +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/.markdownlint-cli2.yaml +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/AGENTS.colleague.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/CLAUDE.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/LICENSE +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/README.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/culture.yaml +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/docs/plans/2026-06-06-rollout-cli-ships-rollout-define-an-org-wide-chang.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/docs/plans/2026-06-12-mass-update-now-clones-each-target-repo-into-a-git.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/docs/skill-sources.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/docs/specs/2026-06-06-rollout-cli-ships-rollout-define-an-org-wide-chang.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/docs/specs/2026-06-12-mass-update-now-clones-each-target-repo-into-a-git.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/apache-relicense/apply.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/apache-relicense/check.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/apache-relicense/files/LICENSE +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/apache-relicense/manifest.toml +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/README.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/apply.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/check.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/files/SKILL.md.tmpl +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/files/prompts/explore.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/files/prompts/review.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/files/prompts/write.md +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/files/scripts/ask-colleague.sh +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/manifest.toml +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/__init__.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/__main__.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/__init__.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/__init__.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/apply.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/cli.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/doctor.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/explain.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/learn.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/overview.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/plan.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_commands/whoami.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_errors.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/cli/_output.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/__init__.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/bump.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/devex_pr.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/gitops.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/orchestrate.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/preflight.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/recipe.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/report.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/core/targets.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/explain/__init__.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/rollout/explain/catalog.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/sonar-project.properties +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/__init__.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_apache_relicense.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_apply_cmd.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_bump.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_cli.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_cli_introspection.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_cli_wiring.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_devex_pr.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_e2e_apache_relicense.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_explain_catalog.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_gitops.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_orchestrate.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_plan_cmd.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_preflight.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_recipe.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_report.py +0 -0
- {rollout_cli-0.4.2 → rollout_cli-0.5.0}/tests/test_targets.py +0 -0
|
@@ -43,12 +43,18 @@ gone. The new mechanism:
|
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
bash .claude/skills/mass-update/scripts/mass-update.sh \
|
|
46
|
-
--repos <owner/repo[,owner/repo...]> <ops> [--pr] [--keep-clone]
|
|
46
|
+
--repos <owner/repo[,owner/repo...]> <ops> [--slug SLUG] [--pr] [--keep-clone]
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
Run it from the rollout-cli repo root. `--repos` takes comma-separated GitHub
|
|
50
50
|
slugs (e.g. `agentculture/widget-cli`).
|
|
51
51
|
|
|
52
|
+
The work branch defaults to `mass-update/<owner>-<repo>`. Pass `--slug SLUG` to
|
|
53
|
+
suffix it as `mass-update/<owner>-<repo>-<slug>`, so several independent updates
|
|
54
|
+
to the same repo can coexist as distinct branches (and distinct PRs) instead of
|
|
55
|
+
colliding on the one default branch name. `SLUG` must be ref-safe — letters,
|
|
56
|
+
digits, `.`, `_`, `-`; start with a letter or digit; no trailing `.` or `-`.
|
|
57
|
+
|
|
52
58
|
## Op shapes (combinable in one call)
|
|
53
59
|
|
|
54
60
|
| Op | What it does |
|
|
@@ -65,6 +71,7 @@ All ops given in one call are applied to each clone. At least one op is required
|
|
|
65
71
|
|------|--------|
|
|
66
72
|
| *(none)* | **PREVIEW.** Clone, apply ops, print diff, cleanup. **Zero outward effect.** Always start here. |
|
|
67
73
|
| `--pr` | Clone, apply, commit, push, open PR, file a companion tracking issue via `communicate/scripts/post-issue.sh`, cleanup. Both the PR URL and issue URL are printed. |
|
|
74
|
+
| `--slug SLUG` | Suffix the work branch: `mass-update/<owner>-<repo>-<slug>` (default has no suffix). Use when a repo may receive more than one independent mass-update so the branches don't collide. |
|
|
68
75
|
| `--keep-clone` | Retain the scratch clone on exit (debug). |
|
|
69
76
|
|
|
70
77
|
## Worked example — propagate a LICENSE to a sibling repo
|
|
@@ -28,6 +28,9 @@ Targets:
|
|
|
28
28
|
--repos a/b,c/d Comma-separated GitHub slugs (owner/repo). Required.
|
|
29
29
|
|
|
30
30
|
Other:
|
|
31
|
+
--slug SLUG Suffix the work branch: mass-update/<owner>-<repo>-SLUG
|
|
32
|
+
(default: mass-update/<owner>-<repo>). Lets several
|
|
33
|
+
independent updates to the same repo coexist.
|
|
31
34
|
-h, --help Show this help.
|
|
32
35
|
EOF
|
|
33
36
|
}
|
|
@@ -47,6 +50,7 @@ EDITS=()
|
|
|
47
50
|
DO_PR=0
|
|
48
51
|
KEEP_CLONE=0
|
|
49
52
|
PENDING_FILE=""
|
|
53
|
+
SLUG=""
|
|
50
54
|
|
|
51
55
|
_push_file() {
|
|
52
56
|
[[ -n "$PENDING_FILE" ]] || { echo "error: $([[ "$1" == "from" ]] && echo --from || echo --content) given before any --file DEST" >&2; exit 2; }
|
|
@@ -93,6 +97,11 @@ while [[ $# -gt 0 ]]; do
|
|
|
93
97
|
EDITS+=("$2")
|
|
94
98
|
shift 2
|
|
95
99
|
;;
|
|
100
|
+
--slug)
|
|
101
|
+
need_value "$#" "$1"
|
|
102
|
+
SLUG="$2"
|
|
103
|
+
shift 2
|
|
104
|
+
;;
|
|
96
105
|
--pr)
|
|
97
106
|
DO_PR=1
|
|
98
107
|
shift
|
|
@@ -133,6 +142,22 @@ if [[ ${#FILE_DESTS[@]} -eq 0 && ${#EDITS[@]} -eq 0 ]]; then
|
|
|
133
142
|
exit 2
|
|
134
143
|
fi
|
|
135
144
|
|
|
145
|
+
# Validate the optional branch slug — it becomes a git ref suffix, so it must be
|
|
146
|
+
# a valid ref *component*, not merely a "nice-looking" string. Beyond the safe
|
|
147
|
+
# charset and leading/trailing dash/dot rules, git also rejects a '..' sequence
|
|
148
|
+
# and a '.lock' suffix in a ref name; allowing them here would pass validation
|
|
149
|
+
# but blow up later at `checkout -b` / `push` / `pr create --head` (where the
|
|
150
|
+
# failure is swallowed by `|| true`), so reject them up front with a clear error.
|
|
151
|
+
if [[ -n "$SLUG" ]]; then
|
|
152
|
+
if [[ ! "$SLUG" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ \
|
|
153
|
+
|| "$SLUG" == *. || "$SLUG" == *- \
|
|
154
|
+
|| "$SLUG" == *..* || "$SLUG" == *.lock ]]; then
|
|
155
|
+
echo "error: '$SLUG' is not a valid --slug (must be a valid git ref component)" >&2
|
|
156
|
+
echo "hint: letters, digits, '.', '_', '-'; start with a letter/digit; no trailing '.'/'-', no '..' sequence, no '.lock' suffix" >&2
|
|
157
|
+
exit 2
|
|
158
|
+
fi
|
|
159
|
+
fi
|
|
160
|
+
|
|
136
161
|
# ── validate slug format ────────────────────────────────────────────────────
|
|
137
162
|
validate_slug() {
|
|
138
163
|
local slug="$1"
|
|
@@ -314,6 +339,9 @@ for raw in "${TARGETS[@]}"; do
|
|
|
314
339
|
repo="${target#*/}"
|
|
315
340
|
clone_name="${owner}-${repo}"
|
|
316
341
|
clone_dir="$CLONES_DIR/$clone_name"
|
|
342
|
+
# Work branch: mass-update/<owner>-<repo>, with an optional -<slug> suffix so
|
|
343
|
+
# several independent updates to the same repo get distinct branches.
|
|
344
|
+
branch="mass-update/${clone_name}${SLUG:+-$SLUG}"
|
|
317
345
|
|
|
318
346
|
# Check auth before cloning
|
|
319
347
|
if ! gh auth status >/dev/null 2>&1; then
|
|
@@ -337,8 +365,8 @@ for raw in "${TARGETS[@]}"; do
|
|
|
337
365
|
fi
|
|
338
366
|
|
|
339
367
|
# Create work branch
|
|
340
|
-
git -C "$clone_dir" checkout -b "
|
|
341
|
-
git -C "$clone_dir" switch -c "
|
|
368
|
+
git -C "$clone_dir" checkout -b "$branch" 2>/dev/null || \
|
|
369
|
+
git -C "$clone_dir" switch -c "$branch" 2>/dev/null || true
|
|
342
370
|
|
|
343
371
|
# Apply file ops
|
|
344
372
|
apply_file_ops "$clone_dir" || { overall_rc=1; continue; }
|
|
@@ -366,7 +394,7 @@ for raw in "${TARGETS[@]}"; do
|
|
|
366
394
|
fi
|
|
367
395
|
|
|
368
396
|
# Push work branch — a failed push must not be swallowed.
|
|
369
|
-
if ! git -C "$clone_dir" push origin "
|
|
397
|
+
if ! git -C "$clone_dir" push origin "$branch"; then
|
|
370
398
|
echo "error: push failed for $target" >&2
|
|
371
399
|
overall_rc=1
|
|
372
400
|
continue
|
|
@@ -377,7 +405,7 @@ for raw in "${TARGETS[@]}"; do
|
|
|
377
405
|
--repo "$target" \
|
|
378
406
|
--title "mass-update: deterministic update" \
|
|
379
407
|
--body "Automated update via mass-update skill." \
|
|
380
|
-
--head "
|
|
408
|
+
--head "$branch")" || [[ -z "$pr_url" ]]; then
|
|
381
409
|
echo "error: gh pr create failed for $target" >&2
|
|
382
410
|
overall_rc=1
|
|
383
411
|
continue
|
|
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/). This project
|
|
6
6
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.0] - 2026-06-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- mass-update: --slug SLUG flag suffixes the work branch as `mass-update/<owner>-<repo>-<slug>`, so several independent updates to the same repo get distinct branches/PRs instead of colliding on the default branch name. Slug is validated as a valid git ref component — rejecting not just bad charset / leading-trailing dash-or-dot, but also the `..` sequences and `.lock` suffix git refuses (which would otherwise pass validation and only fail later at checkout/push/PR). (Qodo PR #10 bug 1.)
|
|
13
|
+
|
|
8
14
|
## [0.4.2] - 2026-06-13
|
|
9
15
|
|
|
10
16
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rollout-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Cross-repo propagation workflow built on refactor-cli — apply a transformation across many repos at once.
|
|
5
5
|
Project-URL: Homepage, https://github.com/agentculture/rollout-cli
|
|
6
6
|
Project-URL: Issues, https://github.com/agentculture/rollout-cli/issues
|
|
@@ -478,6 +478,66 @@ def test_pr_writes_no_tempfiles_outside_repo(repo, fake_bin, tmp_path):
|
|
|
478
478
|
assert not (repo / ".mass-update").exists()
|
|
479
479
|
|
|
480
480
|
|
|
481
|
+
# --------------------------------------------------------------------------- #
|
|
482
|
+
# --slug: suffix the work branch so several independent updates to the same repo
|
|
483
|
+
# get distinct branches (mass-update/<owner>-<repo>-<slug>).
|
|
484
|
+
# --------------------------------------------------------------------------- #
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def _current_branch(clone: Path) -> str:
|
|
488
|
+
return subprocess.run(
|
|
489
|
+
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
490
|
+
cwd=clone,
|
|
491
|
+
capture_output=True,
|
|
492
|
+
text=True,
|
|
493
|
+
).stdout.strip()
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
def test_default_branch_has_no_slug_suffix(repo, fake_bin):
|
|
497
|
+
r = run(repo, fake_bin, "--repos", SLUG, "--file", "NOTICE", "--content", "x\n", "--keep-clone")
|
|
498
|
+
assert r.returncode == 0, r.stderr
|
|
499
|
+
assert _current_branch(_clone_dir(repo)) == "mass-update/agentculture-widget-cli"
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def test_slug_suffixes_the_work_branch(repo, fake_bin):
|
|
503
|
+
r = run(
|
|
504
|
+
repo,
|
|
505
|
+
fake_bin,
|
|
506
|
+
"--repos",
|
|
507
|
+
SLUG,
|
|
508
|
+
"--file",
|
|
509
|
+
"NOTICE",
|
|
510
|
+
"--content",
|
|
511
|
+
"x\n",
|
|
512
|
+
"--slug",
|
|
513
|
+
"notice-v2",
|
|
514
|
+
"--keep-clone",
|
|
515
|
+
)
|
|
516
|
+
assert r.returncode == 0, r.stderr
|
|
517
|
+
assert _current_branch(_clone_dir(repo)) == "mass-update/agentculture-widget-cli-notice-v2"
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
@pytest.mark.parametrize(
|
|
521
|
+
"bad",
|
|
522
|
+
[
|
|
523
|
+
"-leading",
|
|
524
|
+
"trailing-",
|
|
525
|
+
"has space",
|
|
526
|
+
"has/slash",
|
|
527
|
+
"trailing.",
|
|
528
|
+
"@bad",
|
|
529
|
+
# git rejects these as ref names even though they look benign:
|
|
530
|
+
"dot..dot", # '..' sequence
|
|
531
|
+
"foo.lock", # '.lock' suffix
|
|
532
|
+
],
|
|
533
|
+
)
|
|
534
|
+
def test_invalid_slug_is_rejected(repo, fake_bin, bad):
|
|
535
|
+
r = run(repo, fake_bin, "--repos", SLUG, "--file", "NOTICE", "--content", "x\n", "--slug", bad)
|
|
536
|
+
assert r.returncode == 2, r.stderr
|
|
537
|
+
assert "slug" in (r.stdout + r.stderr).lower()
|
|
538
|
+
assert not (repo / ".mass-update").exists()
|
|
539
|
+
|
|
540
|
+
|
|
481
541
|
# finding 2: when communicate's post-issue.sh is absent, --pr must error (route
|
|
482
542
|
# issues only through /communicate), not silently fall back to `agtag` directly.
|
|
483
543
|
def test_missing_post_issue_script_errors_no_agtag_fallback(repo, fake_bin):
|
|
File without changes
|
{rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/agent-config/data/backend-fingerprints.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/ask-colleague/scripts/ask-colleague.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rollout_cli-0.4.2 → rollout_cli-0.5.0}/.claude/skills/pypi-maintainer/scripts/switch-source.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/files/prompts/explore.md
RENAMED
|
File without changes
|
{rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/files/prompts/review.md
RENAMED
|
File without changes
|
{rollout_cli-0.4.2 → rollout_cli-0.5.0}/recipes/ask-colleague-revendor/files/prompts/write.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|