Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actions: Consider precision of current version when selecting latest #4953

Merged
merged 9 commits into from
Apr 6, 2022

Conversation

mctofu
Copy link
Contributor

@mctofu mctofu commented Apr 5, 2022

This attempts to address #4768

This has become noticeable recently with the release of the v3 versions of many github actions. The existing code to find the latest version did not deal with situations where multiple tags represented the latest version (v3, v3.0.0). Users that had pinned to a patch version were getting swapped to a major version (v2.1.5 -> v3) and some saw the opposite (v2 -> v3.0.0). Also, when v3.0.1 was released users pinned to a major version got updates to a patch version (v2 -> v3.0.1)

To work around this I've added a new method, GitCommitChecker.local_tags_for_latest_version_commit_sha, which returns all the version tags attached to the commit for the latest version. I then updated the Actions UpdateChecker to try and choose the version tag that matches the precision of the current version.

Copy link
Contributor Author

@mctofu mctofu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the cargo failure is unrelated?

latest_tags = git_commit_checker.local_tags_for_latest_version_commit_sha

# Find the latest version with the same precision as the pinned version.
# Falls back to a version with the closest precision if no exact match.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure what to do here but assumed we'd probably run into this somewhere in the wild. A simpler option would be to refuse to update if we couldn't find a match?

Copy link
Contributor

@brrygrdn brrygrdn Apr 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this approach is good, I think both outcomes are mildly surprising but failing over to some kind of update at least alerts the user to the new version and highlights that the tagging strategy on the library has changed.

Cases where we don't do anything are harder to relay to the end user without them reading the logs closely, so I think this is the better outcome.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test that covers the tie break behaviour?

I haven't gone over the existing tests outside the diff, but it occurs to me we might already be testing this as a variation on the current behaviour but I couldn't spot it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, there were not. It's a bit of work to setup test fixtures for each case so I wanted to be sure we were OK with the approach first. I added some tests in aaa7703 by stubbing out the call to GitCommitChecker so the examples are easier to read.

@@ -133,7 +133,7 @@
let(:reference) { "1c24df3" }

let(:repo_url) { "https://api.github.com/repos/actions/setup-node" }
let(:comparison_url) { repo_url + "/compare/v1.1.0...1c24df3" }
let(:comparison_url) { repo_url + "/compare/v1.1...1c24df3" }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a side effect of adding a v1.1 version to the test fixture.

@mctofu mctofu marked this pull request as ready for review April 5, 2022 01:23
@mctofu mctofu requested a review from a team as a code owner April 5, 2022 01:23
@jurre
Copy link
Member

jurre commented Apr 5, 2022

I think the cargo failure is unrelated?

Yeah they look related to git dependencies, but checked on a different branch and locally that the same errors exist, might be testing against some public deps that have changed

Copy link
Contributor

@brrygrdn brrygrdn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a couple of questions, but overall this looks great 🥇

Comment on lines 91 to 96
max_tag = tags.
max_by do |t|
version = t.name.match(VERSION_REGEX).named_captures.
fetch("version")
version_class.new(version)
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a duplication of lines 114-119, is it maybe worth extracting this to a method?

It took me a few minutes for the need to do the transform from the version back to the tags ( which are versions effectively and likely why I did a double-take 😅 ) on the commit sha to click, isolating this as a method might allow us to make it a little more expressive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to improve this in 9d1dafb but open to any other naming suggestions!

latest_tags = git_commit_checker.local_tags_for_latest_version_commit_sha

# Find the latest version with the same precision as the pinned version.
# Falls back to a version with the closest precision if no exact match.
Copy link
Contributor

@brrygrdn brrygrdn Apr 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this approach is good, I think both outcomes are mildly surprising but failing over to some kind of update at least alerts the user to the new version and highlights that the tagging strategy on the library has changed.

Cases where we don't do anything are harder to relay to the end user without them reading the logs closely, so I think this is the better outcome.

context "using the full version" do
let(:reference) { "v1.0.0" }
it { is_expected.to eq(Dependabot::GithubActions::Version.new("2.1.3")) }
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

latest_tags = git_commit_checker.local_tags_for_latest_version_commit_sha

# Find the latest version with the same precision as the pinned version.
# Falls back to a version with the closest precision if no exact match.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test that covers the tie break behaviour?

I haven't gone over the existing tests outside the diff, but it occurs to me we might already be testing this as a variation on the current behaviour but I couldn't spot it.

@jurre
Copy link
Member

jurre commented Apr 5, 2022

I've fixed the cargo things

@mctofu mctofu requested a review from brrygrdn April 6, 2022 00:48
Copy link
Contributor

@brrygrdn brrygrdn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Thanks for addressing those comments, this looks great!

@mctofu mctofu merged commit 98098a4 into main Apr 6, 2022
@mctofu mctofu deleted the mctofu/actions-versions-stability branch April 6, 2022 16:43
@jurre jurre mentioned this pull request Apr 6, 2022
@pzygielo
Copy link

Not sure if this is working as expected. I've just got PR "Bump actions/setup-java from 2 to 3.1.1"

updater | time="2022-04-11T14:14:27Z" level=info msg="starting job..." fetcher_timeout=5m0s job_id=339650753 updater_timeout=45m0s updater_version=0.180.5-fa5bb09ca507cf1caf68ca73cfd011f9620038d6

@pzygielo
Copy link

Not sure if this is working as expected. I've just got existing, open PR "Bump actions/setup-java from 2 to 3" superseded by "Bump actions/setup-java from 2 to 3.1.1"

updater | time="2022-04-11T14:31:40Z" level=info msg="starting job..." fetcher_timeout=5m0s job_id=339675945 updater_timeout=45m0s updater_version=0.180.5-fa5bb09ca507cf1caf68ca73cfd011f9620038d6

@pzygielo
Copy link

The #4953 (comment) and #4953 (comment) happened in the short time while setup-java 3 tag was still pointing at the previous release. Once this 3 was moved to the latest release new PRs consider precision again indeed.

I still do not think, that the case of major-only version not advanced in the same time as point-release should cause observed behaviour.

@mctofu
Copy link
Contributor Author

mctofu commented Apr 11, 2022

Thanks @pzygielo, that's a good catch! A mismatch in the v3 and latest v3.x.x tag would definitely cause an issue when upgrading from a previous major version.

One argument for keeping the current behavior is that creating a PR for the v3 tag would not be updating you to the latest version. Could this cause problems for actions which don't follow the recommend practices for tagging?

An argument against the current behavior is it's inconsistent with the behavior for updates within a major version. If you are currently on the v3 tag which happens to be behind the latest v3.x.x tag you won't get an update. An update from v2 -> v3.x.x is only triggered as part of a major version upgrade.

I think it does make sense to try and preserve consistency and stick to upgrading from v2 -> v3, even when v3 isn't the latest release. We could do that by reworking the version selection to not require the v3 tag is from the same commit as the latest v3.x.x tag.

@pzygielo
Copy link

An update from v2 -> v3.x.x is only triggered as part of a major version upgrade.

That's what happened in my cases, indeed.

Should I accept the change "Bump actions/setup-java from 2 to 3.1.1" I'd be again in the loop of PRs for every bugfix release. (As x.x.x precision would be preferred then.)
While for some, let's say, more trustworthy actions, that are not project's dependencies but CI env only, I'd prefer to implicitly upgrade as the tag is or isn't moved by action vendor.

Thanks for checking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants