From cb3fc007bb86956c0221b8e1809e29b859b496cf Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 23 Dec 2025 15:08:57 -0600 Subject: [PATCH] Update version_branch.yml --- .github/workflows/version_branch.yml | 258 +-------------------------- 1 file changed, 1 insertion(+), 257 deletions(-) diff --git a/.github/workflows/version_branch.yml b/.github/workflows/version_branch.yml index 7dce7d9..9fdaa16 100644 --- a/.github/workflows/version_branch.yml +++ b/.github/workflows/version_branch.yml @@ -404,260 +404,4 @@ jobs: root = Path('.').resolve() header_re = re.compile(r'(?im)(VERSION[ ]*:[ ]*)([0-9]{2}[.][0-9]{2}[.][0-9]{2})') - - manifest_marker_re = re.compile(r'(?is))([^<]*?)()') - xml_date_res = [ - re.compile(r'(?is)()([^<]*?)()'), - re.compile(r'(?is)()([^<]*?)()'), - re.compile(r'(?is)()([^<]*?)()'), - ] - - skip_ext = { - '.json', '.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico', '.pdf', - '.zip', '.7z', '.tar', '.gz', '.woff', '.woff2', '.ttf', '.otf', - '.mp3', '.mp4' - } - skip_dirs = {'.git', '.github', 'node_modules', 'vendor', '.venv', 'dist', 'build'} - - counters = defaultdict(int) - - updated_files = [] - updated_manifests = [] - would_update_files = [] - would_update_manifests = [] - - def should_skip(p: Path) -> bool: - if p.suffix.lower() in skip_ext: - counters['skipped_by_ext'] += 1 - return True - parts = {x.lower() for x in p.parts} - if any(d in parts for d in skip_dirs): - counters['skipped_by_dir'] += 1 - return True - return False - - for p in root.rglob('*'): - if not p.is_file(): - continue - if should_skip(p): - continue - - # Release only artifacts at repo root - if p.parent == root and p.name.lower() in {'update.xml', 'updates.xml'}: - counters['skipped_release_artifacts'] += 1 - continue - - try: - text = p.read_text(encoding='utf-8', errors='replace') - except Exception: - counters['skipped_read_error'] += 1 - continue - - original = text - - # Header style markers: VERSION: NN.NN.NN - text, n1 = header_re.subn(lambda m: m.group(1) + new_version, text) - if n1: - counters['header_replacements'] += n1 - - # Joomla manifest XML only () - is_manifest = (p.suffix.lower() == '.xml' and manifest_marker_re.search(original) is not None) - if is_manifest: - text2, n2 = xml_version_re.subn(lambda m: m.group(1) + new_version + m.group(3), text) - text = text2 - if n2: - counters['xml_version_replacements'] += n2 - - for rx in xml_date_res: - text3, n3 = rx.subn(lambda m: m.group(1) + stamp + m.group(3), text) - text = text3 - if n3: - counters['xml_date_replacements'] += n3 - - if text != original: - would_update_files.append(str(p)) - if is_manifest: - would_update_manifests.append(str(p)) - - if not report_only: - p.write_text(text, encoding='utf-8') - updated_files.append(str(p)) - if is_manifest: - updated_manifests.append(str(p)) - - report = { - 'mode': 'report_only' if report_only else 'apply', - 'new_version': new_version, - 'stamp_utc': stamp, - 'counters': dict(counters), - 'updated_files': updated_files, - 'updated_manifests': updated_manifests, - 'would_update_files': would_update_files, - 'would_update_manifests': would_update_manifests, - } - - Path('.github').mkdir(parents=True, exist_ok=True) - Path('.github/version-bump-report.json').write_text(json.dumps(report, indent=2), encoding='utf-8') - - print('[INFO] Mode: ' + ('report_only' if report_only else 'apply')) - print('[INFO] Would update files: ' + str(len(would_update_files))) - print('[INFO] Would update manifests: ' + str(len(would_update_manifests))) - print('[INFO] Updated files: ' + str(len(updated_files))) - print('[INFO] Updated manifests: ' + str(len(updated_manifests))) - - if report_only: - raise SystemExit(0) - - if not updated_files: - print('[INFO] No eligible files updated. Skipping version bump without failure.') - raise SystemExit(0) - PY - - - name: Enforce update feed XML is release generated only (delete update.xml and updates.xml) - if: ${{ env.REPORT_ONLY != 'true' }} - run: | - source "$CI_HELPERS" - moko_init "Enforce update feed XML is release generated only" - - echo "[INFO] Removing release-generated update feeds from repo root" - - # Prefer git-aware removal for tracked files - git rm -f --ignore-unmatch "update.xml" "updates.xml" || true - - # Defense in depth for untracked or regenerated files - rm -f "update.xml" "updates.xml" || true - - # Hard verification - if [[ -f "update.xml" || -f "updates.xml" ]]; then - echo "[FATAL] Update feed XML still present after deletion attempt." >&2 - ls -la "update.xml" "updates.xml" 2>/dev/null || true - exit 2 - fi - - if git ls-files --error-unmatch "update.xml" >/dev/null 2>&1; then - echo "[FATAL] update.xml is still tracked after git rm." >&2 - exit 2 - fi - - if git ls-files --error-unmatch "updates.xml" >/dev/null 2>&1; then - echo "[FATAL] updates.xml is still tracked after git rm." >&2 - exit 2 - fi - - echo "[INFO] Update feed XML removed and untracked as required." - git status --porcelain=v1 || true - - - name: Change scope guard (block .github edits) - run: | - source "$CI_HELPERS" - moko_init "Change scope guard" - - if [[ -z "$(git status --porcelain=v1)" ]]; then - echo "[INFO] No changes detected. Scope guard skipped." - exit 0 - fi - - echo "[INFO] Evaluating changed paths" - git diff --name-only > /tmp/changed_paths.txt - - bad=0 - while IFS= read -r p; do - if [[ "$p" == .github/* ]] && [[ "$p" != .github/version-bump-report.json ]]; then - echo "[ERROR] .github change is not permitted by this workflow: $p" >&2 - bad=1 - fi - done < /tmp/changed_paths.txt - - if [[ "$bad" -ne 0 ]]; then - echo "[FATAL] Change scope guard failed. Workflow attempted to modify .github content." >&2 - echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) | Change scope guard | attempted .github modifications" >> "$ERROR_LOG" || true - exit 2 - fi - - echo "[INFO] Scope guard passed" - - - name: Publish audit trail to job summary - if: always() - run: | - source "$CI_HELPERS" - moko_init "Publish audit trail" - - echo "# Version branch run" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "- Repository: $GITHUB_REPOSITORY" >> "$GITHUB_STEP_SUMMARY" - echo "- Base branch: ${BASE_BRANCH}" >> "$GITHUB_STEP_SUMMARY" - echo "- New branch: ${BRANCH_NAME:-}" >> "$GITHUB_STEP_SUMMARY" - echo "- Version: ${NEW_VERSION}" >> "$GITHUB_STEP_SUMMARY" - echo "- Commit changes: ${COMMIT_CHANGES}" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - - if [[ -f ".github/version-bump-report.json" ]]; then - echo "## Bump report" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "\`\`\`json" >> "$GITHUB_STEP_SUMMARY" - head -c 12000 ".github/version-bump-report.json" >> "$GITHUB_STEP_SUMMARY" || true - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY" - fi - - echo "## Error summary" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - - if [[ -f "$ERROR_LOG" && -s "$ERROR_LOG" ]]; then - echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY" - tail -n 200 "$ERROR_LOG" >> "$GITHUB_STEP_SUMMARY" || true - echo "\`\`\`" >> "$GITHUB_STEP_SUMMARY" - else - echo "No errors recorded." >> "$GITHUB_STEP_SUMMARY" - fi - - - name: Show git status - run: | - source "$CI_HELPERS" - moko_init "Show git status" - - git status --porcelain=v1 - - - name: Commit changes - id: commit - if: ${{ env.REPORT_ONLY != 'true' }} - run: | - source "$CI_HELPERS" - moko_init "Commit changes" - - git rev-parse --is-inside-work-tree >/dev/null 2>&1 || { echo "[ERROR] Not inside a git work tree" >&2; exit 2; } - - if [[ -z "$(git status --porcelain=v1)" ]]; then - echo "[INFO] No changes detected. Skipping commit and push." - echo "committed=false" >> "$GITHUB_OUTPUT" - exit 0 - fi - - echo "[INFO] Staging all changes except .github" - git add -A -- . ":(exclude).github" - - git commit -m "chore(release): bump version to ${NEW_VERSION}" - echo "committed=true" >> "$GITHUB_OUTPUT" - - - name: Push branch - if: ${{ env.REPORT_ONLY != 'true' }} - run: | - source "$CI_HELPERS" - moko_init "Push branch" - - if [[ -z "${BRANCH_NAME:-}" ]]; then - echo "[FATAL] BRANCH_NAME is not set. Branch creation step may have failed." >&2 - exit 2 - fi - - echo "[INFO] Pushing branch and commits to origin/${BRANCH_NAME}" - git push --set-upstream origin "${BRANCH_NAME}" - - - name: Output branch name - if: always() - run: | - source "$CI_HELPERS" - moko_init "Output branch name" - - echo "[INFO] Created branch: ${BRANCH_NAME:-}" + manifest_marker_re = re.compile(r'(?is)