From a630d4e210e7001f18a408d622c744d8f8879540 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 10:31:35 +0100 Subject: [PATCH 01/14] feat: configure git to use GITHUB_TOKEN for authentication in update process --- .../workflows/auto-update-precommit-hooks.yml | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index 0863d4a..b6724ed 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -588,7 +588,7 @@ jobs: with open('configs/precommit-update-tracking.json', 'r') as f: tracking = json.load(f) except FileNotFoundError: - tracking = {'last_updated': datetime.utcnow().isoformat() + 'Z', 'hooks': {}} + tracking = {'last_updated': datetime.now(timezone.utc).isoformat() + 'Z', 'hooks': {}} # Create a mapping of repo URLs to new SHAs update_map = {update['repo']: update for update in release_info} @@ -606,9 +606,9 @@ jobs: 'current_sha': update['new_sha'], 'current_version': update['new_version'], 'semver_levels': { - 'major': datetime.utcnow().isoformat() + 'Z', - 'minor': datetime.utcnow().isoformat() + 'Z', - 'patch': datetime.utcnow().isoformat() + 'Z' + 'major': datetime.now(timezone.utc).isoformat() + 'Z', + 'minor': datetime.now(timezone.utc).isoformat() + 'Z', + 'patch': datetime.now(timezone.utc).isoformat() + 'Z' } } else: @@ -616,9 +616,9 @@ jobs: tracking['hooks'][repo_url]['current_sha'] = update['new_sha'] tracking['hooks'][repo_url]['current_version'] = update['new_version'] if semver != 'unknown': - tracking['hooks'][repo_url]['semver_levels'][semver] = datetime.utcnow().isoformat() + 'Z' + tracking['hooks'][repo_url]['semver_levels'][semver] = datetime.now(timezone.utc).isoformat() + 'Z' - tracking['hooks'][repo_url]['last_updated'] = datetime.utcnow().isoformat() + 'Z' + tracking['hooks'][repo_url]['last_updated'] = datetime.now(timezone.utc).isoformat() + 'Z' # Write updated files with open('.pre-commit-config.yaml', 'w') as f: @@ -743,18 +743,26 @@ jobs: pr_body = generate_pr_body(release_info, skipped, cooldown_config) # Create branch and commit - branch_name = f"chore/precommit-updates-{datetime.utcnow().strftime('%Y%m%d')}" + branch_name = f"chore/precommit-updates-{datetime.now(timezone.utc).strftime('%Y%m%d')}" subprocess.run(['git', 'config', 'user.name', 'github-actions[bot]'], check=True) subprocess.run(['git', 'config', 'user.email', '41898282+github-actions[bot]@users.noreply.github.com'], check=True) + + # Configure git to use GITHUB_TOKEN for authentication (secure alternative to persist-credentials) + github_token = os.environ.get('GITHUB_TOKEN', '') + subprocess.run( + ['git', 'config', '--global', 'url.https://x-access-token:' + github_token + '@github.com/.insteadOf', 'https://github.com/'], + check=True + ) + subprocess.run(['git', 'checkout', '-b', branch_name], check=True) subprocess.run(['git', 'add', '.pre-commit-config.yaml', 'configs/precommit-update-tracking.json'], check=True) commit_msg = f"chore(pre-commit): auto-update hooks\n\nUpdated {len(release_info)} pre-commit hook(s)" subprocess.run(['git', 'commit', '-m', commit_msg], check=True) - # Push branch - subprocess.run(['git', 'push', '-u', 'origin', branch_name], check=True, env={**os.environ, 'GIT_TRACE': '1'}) + # Push branch (git authentication already configured via credential helper) + subprocess.run(['git', 'push', '-u', 'origin', branch_name], check=True) # Create PR using GitHub CLI pr_result = subprocess.run( From 7436743120bd5fe5e0d559f454ce509fe76bb9c9 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 10:42:41 +0100 Subject: [PATCH 02/14] feat: update git push command to use --force-with-lease for safer branch updates --- .github/workflows/auto-update-precommit-hooks.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index b6724ed..325cf5f 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -761,8 +761,9 @@ jobs: commit_msg = f"chore(pre-commit): auto-update hooks\n\nUpdated {len(release_info)} pre-commit hook(s)" subprocess.run(['git', 'commit', '-m', commit_msg], check=True) - # Push branch (git authentication already configured via credential helper) - subprocess.run(['git', 'push', '-u', 'origin', branch_name], check=True) + # Push branch with force-with-lease to handle existing remote branch safely + # (useful when multiple runs occur on the same day during testing) + subprocess.run(['git', 'push', '--force-with-lease', '-u', 'origin', branch_name], check=True) # Create PR using GitHub CLI pr_result = subprocess.run( From 08da0d1a9d345af5076d62d25dedfc169cb73990 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 10:45:17 +0100 Subject: [PATCH 03/14] feat: update setup-python action to version 7.0.0 for improved functionality --- .github/workflows/auto-update-precommit-hooks.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index 325cf5f..3a87c2a 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -83,7 +83,7 @@ jobs: persist-credentials: false - name: Set up Python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.11" @@ -312,7 +312,7 @@ jobs: persist-credentials: false - name: Set up Python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.11" @@ -421,7 +421,7 @@ jobs: persist-credentials: false - name: Set up Python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.11" @@ -539,7 +539,7 @@ jobs: persist-credentials: false - name: Set up Python - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: "3.11" From c2c03f5f4fac430be452c6c1228da0fe7b0eac0a Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 10:46:10 +0100 Subject: [PATCH 04/14] feat: update git configuration to use GITHUB_TOKEN via HTTP header for improved reliability --- .github/workflows/auto-update-precommit-hooks.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index 3a87c2a..3d9c5b4 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -748,10 +748,11 @@ jobs: subprocess.run(['git', 'config', 'user.name', 'github-actions[bot]'], check=True) subprocess.run(['git', 'config', 'user.email', '41898282+github-actions[bot]@users.noreply.github.com'], check=True) - # Configure git to use GITHUB_TOKEN for authentication (secure alternative to persist-credentials) + # Configure git to use GITHUB_TOKEN for authentication via HTTP header + # This is more reliable than URL rewriting in GitHub Actions environments github_token = os.environ.get('GITHUB_TOKEN', '') subprocess.run( - ['git', 'config', '--global', 'url.https://x-access-token:' + github_token + '@github.com/.insteadOf', 'https://github.com/'], + ['git', 'config', '--global', 'http.extraheader', f'Authorization: token {github_token}'], check=True ) From 60e4e3c17c5351d547f3cd840504c925e9a9cd94 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 10:49:23 +0100 Subject: [PATCH 05/14] feat: update git push command to use token in URL for improved security --- .../workflows/auto-update-precommit-hooks.yml | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index 3d9c5b4..1811d85 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -747,24 +747,22 @@ jobs: subprocess.run(['git', 'config', 'user.name', 'github-actions[bot]'], check=True) subprocess.run(['git', 'config', 'user.email', '41898282+github-actions[bot]@users.noreply.github.com'], check=True) - - # Configure git to use GITHUB_TOKEN for authentication via HTTP header - # This is more reliable than URL rewriting in GitHub Actions environments - github_token = os.environ.get('GITHUB_TOKEN', '') - subprocess.run( - ['git', 'config', '--global', 'http.extraheader', f'Authorization: token {github_token}'], - check=True - ) - subprocess.run(['git', 'checkout', '-b', branch_name], check=True) subprocess.run(['git', 'add', '.pre-commit-config.yaml', 'configs/precommit-update-tracking.json'], check=True) commit_msg = f"chore(pre-commit): auto-update hooks\n\nUpdated {len(release_info)} pre-commit hook(s)" subprocess.run(['git', 'commit', '-m', commit_msg], check=True) - # Push branch with force-with-lease to handle existing remote branch safely - # (useful when multiple runs occur on the same day during testing) - subprocess.run(['git', 'push', '--force-with-lease', '-u', 'origin', branch_name], check=True) + # Push branch using token in URL (temporary, safe because token is already exposed via env) + # Get repository info from environment + repo = os.environ.get('GITHUB_REPOSITORY', '') + github_token = os.environ.get('GITHUB_TOKEN', '') + remote_url = f'https://x-access-token:{github_token}@github.com/{repo}.git' + subprocess.run( + ['git', 'push', '--force-with-lease', '-u', remote_url, branch_name], + check=True, + env={**os.environ, 'GIT_TRACE': '0'} # Disable tracing to avoid logging token + ) # Create PR using GitHub CLI pr_result = subprocess.run( From eb4e22bfe3950eabd17866b5c6ec021dc23b8608 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 11:51:34 +0100 Subject: [PATCH 06/14] feat: update push command to use GitHub CLI for authentication and simplify remote URL handling --- .github/workflows/auto-update-precommit-hooks.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index 1811d85..c79ed39 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -753,15 +753,14 @@ jobs: commit_msg = f"chore(pre-commit): auto-update hooks\n\nUpdated {len(release_info)} pre-commit hook(s)" subprocess.run(['git', 'commit', '-m', commit_msg], check=True) - # Push branch using token in URL (temporary, safe because token is already exposed via env) - # Get repository info from environment - repo = os.environ.get('GITHUB_REPOSITORY', '') - github_token = os.environ.get('GITHUB_TOKEN', '') - remote_url = f'https://x-access-token:{github_token}@github.com/{repo}.git' + # Use GitHub CLI to authenticate git for pushing + # gh auth setup-git configures git to use gh's stored credentials + subprocess.run(['gh', 'auth', 'setup-git'], check=True) + + # Push branch subprocess.run( - ['git', 'push', '--force-with-lease', '-u', remote_url, branch_name], - check=True, - env={**os.environ, 'GIT_TRACE': '0'} # Disable tracing to avoid logging token + ['git', 'push', '--force-with-lease', '-u', 'origin', branch_name], + check=True ) # Create PR using GitHub CLI From 05385b3cc7ee00eb76288912fa99ab6e3a82e0e3 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 11:59:23 +0100 Subject: [PATCH 07/14] feat: refine update detection to only track semantic versioned releases and skip repos without tagged releases --- .../workflows/auto-update-precommit-hooks.yml | 42 +++---------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index c79ed39..fc12291 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -142,29 +142,6 @@ jobs: return None - def get_latest_commit_sha(repo_url: str, branch: str = 'HEAD') -> Optional[str]: - """Fetch latest commit SHA from a repository.""" - try: - match = re.search(r'github\.com/([^/]+)/(.+?)(?:\.git)?$', repo_url) - if not match: - return None - - owner, repo = match.groups() - - cmd = [ - 'gh', 'api', '--paginate', - f'repos/{owner}/{repo}/commits', - '-q', '.[0].sha' - ] - - result = subprocess.run(cmd, capture_output=True, text=True, timeout=10) - if result.returncode == 0 and result.stdout.strip(): - return result.stdout.strip() - except Exception as e: - print(f"Warning: Error fetching latest commit for {repo_url}: {e}") - - return None - def resolve_sha_to_tag(repo_url: str, sha: str) -> Optional[str]: """Resolve a commit SHA to its tag, if one exists.""" try: @@ -236,7 +213,8 @@ jobs: print(f"Checking updates for: {repo_url}") - # Try to get latest release first + # Only check tagged releases (Dependabot behavior) + # Skips repositories without semantic versioning release_info = get_latest_release(repo_url) if release_info: @@ -268,19 +246,9 @@ jobs: }) print(f" Update available: {old_version} -> {latest_tag}") else: - # Fall back to latest commit if no releases - latest_sha = get_latest_commit_sha(repo_url) - if latest_sha and latest_sha != current_sha: - print(f" Update available (commit): {current_sha[:7]} -> {latest_sha[:7]}") - updates.append({ - 'repo': repo_url, - 'old_sha': current_sha, - 'new_sha': latest_sha, - 'old_version': current_sha[:7], - 'new_version': latest_sha[:7], - 'semver_level': 'patch', # Default to patch for commits - 'commit_range': f'{current_sha}...{latest_sha}' - }) + # No tagged releases found - skip this repo (Dependabot-aligned behavior) + # This ensures we only track semantic versioned hooks + print(f" ⊘ Skipped: No tagged releases found (only tagged versions are tracked, like Dependabot)") # Output results if updates: From a7a66e84b1a62ffc36320a969a02e53aba915d94 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 12:06:05 +0100 Subject: [PATCH 08/14] feat: add force update option to bypass cooldown periods in PR generation --- .../workflows/auto-update-precommit-hooks.yml | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index fc12291..866baa3 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -520,6 +520,7 @@ jobs: RELEASE_INFO: ${{ needs.fetch-release-info.outputs.release_info }} SKIPPED_UPDATES: ${{ needs.apply-cooldown.outputs.skipped_updates }} GITHUB_TOKEN: ${{ github.token }} + FORCE_UPDATE: ${{ github.event.inputs.force_update || false }} COOLDOWN_MAJOR: ${{ github.event.inputs.cooldown_major_days || '28' }} COOLDOWN_MINOR: ${{ github.event.inputs.cooldown_minor_days || '14' }} COOLDOWN_PATCH: ${{ github.event.inputs.cooldown_patch_days || '7' }} @@ -535,6 +536,7 @@ jobs: # Load release info release_info = json.loads(os.environ['RELEASE_INFO']) skipped = json.loads(os.environ['SKIPPED_UPDATES'] or '[]') + force_update = os.environ.get('FORCE_UPDATE', 'false').lower() == 'true' cooldown_config = { 'major': int(os.environ['COOLDOWN_MAJOR']), @@ -603,7 +605,7 @@ jobs: return match.group(1) return repo_url - def generate_pr_body(updates: list, skipped: list, cooldown_config: dict) -> str: + def generate_pr_body(updates: list, skipped: list, cooldown_config: dict, force_update: bool = False) -> str: """Generate comprehensive PR body.""" now = datetime.now(timezone.utc) @@ -686,15 +688,24 @@ jobs: lines.append("> Some updates have cooldown periods less than 7 days, which may increase vulnerability to supply chain attacks. Longer cooldown periods provide greater stability and more time to detect potential supply chain issues.") lines.append("") - # Cooldown summary - lines.append("### Cooldown Periods Applied") - lines.append("") - lines.append(f"- **Major versions**: {cooldown_config['major']} days") - lines.append(f"- **Minor versions**: {cooldown_config['minor']} days") - lines.append(f"- **Patch versions**: {cooldown_config['patch']} days") - lines.append("") + # Cooldown summary (only show if not overridden by force_update) + if force_update: + lines.append("### Update Policy") + lines.append("") + lines.append("> [!NOTE]") + lines.append("> **Force Update Override**") + lines.append(">") + lines.append("> Cooldown periods were bypassed via `force_update: true`. All eligible updates were applied regardless of cooldown state.") + lines.append("") + else: + lines.append("### Cooldown Periods Applied") + lines.append("") + lines.append(f"- **Major versions**: {cooldown_config['major']} days") + lines.append(f"- **Minor versions**: {cooldown_config['minor']} days") + lines.append(f"- **Patch versions**: {cooldown_config['patch']} days") + lines.append("") - # Skipped updates + # Skipped updates (only relevant if not force_update) if skipped: lines.append("### Skipped Updates") lines.append("") @@ -708,7 +719,7 @@ jobs: return "\n".join(lines) # Generate PR body - pr_body = generate_pr_body(release_info, skipped, cooldown_config) + pr_body = generate_pr_body(release_info, skipped, cooldown_config, force_update) # Create branch and commit branch_name = f"chore/precommit-updates-{datetime.now(timezone.utc).strftime('%Y%m%d')}" From 8a6116b2f40e548f8cf8bdcee7c59ec5426c1f90 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 12:08:09 +0100 Subject: [PATCH 09/14] feat: replace pyyaml with ruamel.yaml for improved YAML handling and comment preservation --- .../workflows/auto-update-precommit-hooks.yml | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index 866baa3..ccffc0a 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -89,7 +89,7 @@ jobs: - name: Install dependencies run: | - pip install pyyaml + pip install ruamel.yaml - name: Detect available updates id: detect @@ -97,7 +97,7 @@ jobs: GH_TOKEN: ${{ github.token }} run: | python3 << 'EOF' - import yaml + from ruamel.yaml import YAML import json import subprocess import os @@ -286,7 +286,7 @@ jobs: - name: Install dependencies run: | - pip install pyyaml + pip install ruamel.yaml - name: Apply cooldown filters id: cooldown @@ -513,7 +513,7 @@ jobs: - name: Install dependencies run: | - pip install pyyaml + pip install ruamel.yaml - name: Update configs and create PR env: @@ -528,10 +528,10 @@ jobs: python3 << 'EOF' import json import os - import yaml import subprocess import re from datetime import datetime, timezone + from ruamel.yaml import YAML # Load release info release_info = json.loads(os.environ['RELEASE_INFO']) @@ -549,9 +549,13 @@ jobs: print("No updates to apply") exit(0) - # Load and update .pre-commit-config.yaml + # Load and update .pre-commit-config.yaml with comment preservation + yaml = YAML() + yaml.preserve_quotes = True + yaml.default_flow_style = False + with open('.pre-commit-config.yaml', 'r') as f: - config = yaml.safe_load(f) + config = yaml.load(f) # Update tracking file try: @@ -570,6 +574,10 @@ jobs: update = update_map[repo_url] repo_entry['rev'] = update['new_sha'] + # Add version as inline comment (e.g., # frozen: v1.2.3) + if hasattr(repo_entry, 'ca'): + repo_entry.ca.comment[None] = [None, f' frozen: {update["new_version"]}'] + # Update tracking if repo_url not in tracking['hooks']: tracking['hooks'][repo_url] = { @@ -590,9 +598,9 @@ jobs: tracking['hooks'][repo_url]['last_updated'] = datetime.now(timezone.utc).isoformat() + 'Z' - # Write updated files + # Write updated files with comment preservation with open('.pre-commit-config.yaml', 'w') as f: - yaml.dump(config, f, default_flow_style=False, sort_keys=False) + yaml.dump(config, f) with open('configs/precommit-update-tracking.json', 'w') as f: json.dump(tracking, f, indent=2) From 5b7ac71c43d7f884094cd5e601a98099d48ca1f8 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 12:12:02 +0100 Subject: [PATCH 10/14] fix: revert to pyyaml for dependency installation and YAML parsing --- .github/workflows/auto-update-precommit-hooks.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index ccffc0a..0935b78 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -89,7 +89,7 @@ jobs: - name: Install dependencies run: | - pip install ruamel.yaml + pip install pyyaml - name: Detect available updates id: detect @@ -97,7 +97,7 @@ jobs: GH_TOKEN: ${{ github.token }} run: | python3 << 'EOF' - from ruamel.yaml import YAML + import yaml import json import subprocess import os From 5d48b91ec8ac28b05873be567608b82b7b01ca52 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 12:14:44 +0100 Subject: [PATCH 11/14] fix: handle potential errors when adding comments to repo entries --- .github/workflows/auto-update-precommit-hooks.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index 0935b78..f575795 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -575,8 +575,14 @@ jobs: repo_entry['rev'] = update['new_sha'] # Add version as inline comment (e.g., # frozen: v1.2.3) - if hasattr(repo_entry, 'ca'): - repo_entry.ca.comment[None] = [None, f' frozen: {update["new_version"]}'] + try: + if hasattr(repo_entry, 'ca') and repo_entry.ca is not None: + if repo_entry.ca.comment is None: + repo_entry.ca.comment = {} + repo_entry.ca.comment[None] = [None, f' frozen: {update["new_version"]}'] + except Exception as e: + # If comment fails, silently continue - comments are optional + pass # Update tracking if repo_url not in tracking['hooks']: From 74ef6e05966350ae068cf019e40c84fd414e33c8 Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 12:17:13 +0100 Subject: [PATCH 12/14] refactor: remove inline comment addition for version tracking in repo entries --- .github/workflows/auto-update-precommit-hooks.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index f575795..e93725e 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -574,16 +574,6 @@ jobs: update = update_map[repo_url] repo_entry['rev'] = update['new_sha'] - # Add version as inline comment (e.g., # frozen: v1.2.3) - try: - if hasattr(repo_entry, 'ca') and repo_entry.ca is not None: - if repo_entry.ca.comment is None: - repo_entry.ca.comment = {} - repo_entry.ca.comment[None] = [None, f' frozen: {update["new_version"]}'] - except Exception as e: - # If comment fails, silently continue - comments are optional - pass - # Update tracking if repo_url not in tracking['hooks']: tracking['hooks'][repo_url] = { From 63290a6fe14828daa1c3e2700e94e84afbd5a8fe Mon Sep 17 00:00:00 2001 From: Colin Daglish Date: Thu, 10 Sep 2026 12:21:30 +0100 Subject: [PATCH 13/14] fix: skip updates if version hasn't changed to prevent unnecessary processing --- .github/workflows/auto-update-precommit-hooks.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/auto-update-precommit-hooks.yml b/.github/workflows/auto-update-precommit-hooks.yml index e93725e..d456e63 100644 --- a/.github/workflows/auto-update-precommit-hooks.yml +++ b/.github/workflows/auto-update-precommit-hooks.yml @@ -235,6 +235,11 @@ jobs: if not old_version: old_version = current_sha[:7] + # Skip if version hasn't actually changed (SHA may differ but tag is same) + if old_version == latest_tag: + print(f" ⊘ Skipped: Version unchanged ({old_version})") + continue + updates.append({ 'repo': repo_url, 'old_sha': current_sha, From d8b7ad52c0400792433bb452542a1f4f41639fff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2026 11:24:42 +0000 Subject: [PATCH 14/14] chore(pre-commit): auto-update hooks Updated 1 pre-commit hook(s) --- .pre-commit-config.yaml | 20 ++++++++++---------- configs/precommit-update-tracking.json | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eb454fb..6aab591 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - - repo: https://github.com/zizmorcore/zizmor-pre-commit - rev: 451b56af716f9f0d0c2b816503a3fd0cf8b036fa # frozen: v1.29.0 - hooks: - - id: zizmor - args: [--fix, --persona=pedantic] - - repo: https://github.com/compilerla/conventional-pre-commit - rev: 3db014c16a9d31997ab8c07a4d61fcce936c8f0d # frozen: v4.4.0 - hooks: - - id: conventional-pre-commit - stages: [commit-msg] \ No newline at end of file +- repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: fa412071e4f5d44d44f9e365f4676f9df92456a2 # frozen: v1.29.0 + hooks: + - id: zizmor + args: [--fix, --persona=pedantic] +- repo: https://github.com/compilerla/conventional-pre-commit + rev: 3db014c16a9d31997ab8c07a4d61fcce936c8f0d # frozen: v4.4.0 + hooks: + - id: conventional-pre-commit + stages: [commit-msg] diff --git a/configs/precommit-update-tracking.json b/configs/precommit-update-tracking.json index 6cb4bfd..400a94e 100644 --- a/configs/precommit-update-tracking.json +++ b/configs/precommit-update-tracking.json @@ -2,12 +2,12 @@ "last_updated": "2026-09-10T00:00:00Z", "hooks": { "https://github.com/zizmorcore/zizmor-pre-commit": { - "last_updated": "2026-09-10T00:00:00Z", - "current_sha": "451b56af716f9f0d0c2b816503a3fd0cf8b036fa", - "current_version": "v1.29.0", + "last_updated": "2026-09-10T11:24:42.825334+00:00Z", + "current_sha": "fa412071e4f5d44d44f9e365f4676f9df92456a2", + "current_version": "v1.30.1", "semver_levels": { "major": "2026-09-10T00:00:00Z", - "minor": "2026-09-10T00:00:00Z", + "minor": "2026-09-10T11:24:42.825323+00:00Z", "patch": "2026-09-10T00:00:00Z" } }, @@ -22,4 +22,4 @@ } } } -} +} \ No newline at end of file