fix(pre-commit, github-actions): use tag creation date for cooldown instead of commit date#15350
Open
robaiken wants to merge 19 commits into
Open
fix(pre-commit, github-actions): use tag creation date for cooldown instead of commit date#15350robaiken wants to merge 19 commits into
robaiken wants to merge 19 commits into
Conversation
… date Previously, cooldown used the commit's committer date (%cd) to determine when a version was released. This is inaccurate when a tag points to an older commit — for example, when a tag is republished or created long after the commit was authored. In such cases, the cooldown window could be incorrectly bypassed because the commit date is already old. This change uses git for-each-ref with %(creatordate:iso) which returns: - The tagger date for annotated tags (when the tag was actually created) - The commit date for lightweight tags (unchanged behavior) This ensures cooldown evaluates based on when a release was actually made available, not when the underlying commit was originally authored. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mmit date Same fix as pre-commit: the commit_metadata_details method now uses git for-each-ref with %(creatordate:iso) to get the tag creation date instead of git show --format="%cd" which returns the commit date. This prevents cooldown bypass when a tag points to an old commit (e.g., mutable major-version tags like v4 that get force-pushed to new commits). Falls back to commit date if for-each-ref returns empty (e.g., tag ref not found in the bare clone). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds tests for both pre-commit and GitHub Actions ecosystems verifying: - Tag creation date (not commit date) is used for cooldown evaluation - Fallback to commit date when for-each-ref returns empty - Annotated tags pointing to old commits correctly apply cooldown - Mutable tags that are recently re-created are correctly in cooldown Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a three-tier fallback for determining release dates in cooldown: 1. GitHub Release published_at via Octokit (most accurate) 2. Tag creation date via git for-each-ref %(creatordate:iso) 3. Commit date via git show %cd (final fallback) The GitHub Release published_at is the most accurate because it reflects when the release was actually published, even after re-tagging. The releases are cached per finder instance to avoid repeated API calls when iterating multiple candidate versions. When no GitHub Release exists (e.g., non-GitHub repos, tags without releases), falls back to the git-based date detection. Includes tests for both pre-commit and GitHub Actions ecosystems. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves release cooldown accuracy for pre-commit and GitHub Actions git-sourced dependencies by preferring a tag’s creation date (%(creatordate)) over the underlying commit’s committer date, preventing recently created/republished tags that point to older commits from bypassing cooldown.
Changes:
- pre-commit: evaluate cooldown using tag creation date via
git for-each-ref, with fallback togit showcommit date when needed. - GitHub Actions: update SHA-pinned cooldown date lookup to prefer the latest version tag’s creation date via
git for-each-ref, with fallback togit show. - Add/adjust specs to stub
git for-each-refbehavior and validate fallback behavior.
Show a summary per file
| File | Description |
|---|---|
| pre_commit/lib/dependabot/pre_commit/update_checker/latest_version_finder.rb | Switch cooldown evaluation from commit date to tag creation date (with fallback). |
| pre_commit/spec/dependabot/pre_commit/update_checker/latest_version_finder_spec.rb | Update cooldown specs to stub the new git for-each-ref command and add coverage for tag-vs-commit date scenarios. |
| github_actions/lib/dependabot/github_actions/update_checker/latest_version_finder.rb | Prefer tag creation date for SHA-pinned cooldown evaluation, falling back to commit date. |
| github_actions/spec/dependabot/github_actions/update_checker/latest_version_finder_spec.rb | Add direct coverage for commit_metadata_details including for-each-ref and fallback paths. |
Copilot's findings
- Files reviewed: 4/4 changed files
- Comments generated: 3
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ve_messages) - Extract fetch_date_from_git helper to reduce commit_metadata_details size - Use instance_double for Sawyer::Resource and Octokit::Client - Combine multiple stubs with receive_messages Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Normalize tag names (strip 'tags/' prefix) to prevent constructing invalid refs like refs/tags/tags/v1.0.0 - Move GitHub Release check before git clone in pre-commit (avoids unnecessary clone when published_at is available) - Fix memoization bug in GitHub Actions (extract resolve method to avoid return inside ||= block) - Make test assertions deterministic (use exact values instead of Time.now comparisons) - Add GitHub releases stubs to git-fallback tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sawyer::Resource uses dynamic attributes via method_missing, so instance_double cannot verify tag_name/published_at. Switch to plain double with rubocop disable comment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace git show stub with git for-each-ref in update_checker_spec - Add GitHub Releases client stub (empty releases for clone fallback) - Add prerelease: false to Sawyer::Resource doubles to prevent leaking into GitCommitChecker#github_release_prerelease? Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removes rubocop:disable RSpec/VerifiedDoubles comments by using Struct instead of plain doubles for Sawyer::Resource mocks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When only some candidates have GitHub Releases and those are in cooldown, fall back to git clone for the remaining candidates instead of incorrectly marking all as rejected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When falling back to git clone because some candidates lack releases, the clone path now still prefers published_at for candidates that DO have releases, preserving the intended priority: Release published_at > tag creation date > commit date. Also fixes method comment to accurately describe return contract. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace 'return []' with if/else expression inside the ||= block so empty results (non-GitHub sources) are properly cached and the release-fetch logic isn't re-evaluated on every call. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Prevents test failures when run on a different day. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8e022d9 to
a1ff310
Compare
Deduplicates cooldown date resolution logic between pre-commit and GitHub Actions into a common module. Both ecosystems now include Dependabot::GitCooldownDateResolver and implement two bridge methods: - cooldown_source_url: returns the git source URL - cooldown_credentials: returns the credentials array Shared methods: normalize_tag_name, resolve_candidate_date, github_release_published_at, tag_creation_date, cached_github_releases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tests all 5 public methods: - normalize_tag_name (prefix stripping) - tag_creation_date (for-each-ref + commit date fallback) - github_release_published_at (release lookup) - resolve_candidate_date (3-tier priority) - cached_github_releases (caching, non-GitHub, API errors) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Previously, cooldown in the pre-commit and GitHub Actions ecosystems used the commit's committer date (
%cd) to determine when a version was released. This is inaccurate when a tag points to an older commit — for example, when a tag is republished, force-pushed, or created long after the commit was authored.Changes
Implements a three-tier date resolution strategy for cooldown:
published_at(via Octokit) — most accurate, reflects actual publication time even after re-tagginggit for-each-ref %(creatordate:iso)) — tagger date for annotated tagsgit show %cd) — final fallback for lightweight tagsKey implementation details:
cached_github_releases)Why this matters
Testing
Added tests for both ecosystems covering:
published_atused when available (skips git clone)for-each-refwhen no release existsfor-each-refreturns empty