Skip to content

fix: correct bounds out of range error#130

Merged
sethvargo merged 1 commit into
sethvargo:mainfrom
aaronhurt:ahurt/fix-panic
Apr 21, 2026
Merged

fix: correct bounds out of range error#130
sethvargo merged 1 commit into
sethvargo:mainfrom
aaronhurt:ahurt/fix-panic

Conversation

@aaronhurt

Copy link
Copy Markdown
Contributor

The Actions.LatestVersion function previously assumed that release.TagName and githubRef.ref had the same precision. This was not always true.

In some cases the release is on a floating tag like v3 and the GitHub ref comes back as v3.0.0 - in this case the LatestVersion function panics with a slice bounds out of range error. This is corrected by checking the precision of the release tag against the GitHub ref prior to manipulation.

Test file:

name: Test Thing
on:
  workflow_dispatch:
jobs:
  test:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6.0.2
      - name: Authenticate with Google Cloud
        uses: google-github-actions/auth@v3.0.0
        with:
          project_id: 'test'
          workload_identity_provider: "projects/12345/locations/global/workloadIdentityPools/my-pool/providers/github-actions"
          service_account: "test@test.iam.gserviceaccount.com"

Current behavior:

$ ratchet upgrade test.yaml
panic: runtime error: slice bounds out of range [:3] with capacity 1

goroutine 6 [running]:
github.com/sethvargo/ratchet/resolver.(*Actions).LatestVersion(0x140000581e8, {0x1053dd378, 0x14000107440}, {0x140000186fa, 0x21})
        github.com/sethvargo/ratchet/resolver/actions.go:114 +0x3d8
github.com/sethvargo/ratchet/resolver.(*DefaultResolver).LatestVersion(0x140000266d0, {0x1053dd378, 0x14000107440}, {0x140000186f0, 0x2b})
        github.com/sethvargo/ratchet/resolver/resolver.go:67 +0xe0
github.com/sethvargo/ratchet/parser.Upgrade.func1()
        github.com/sethvargo/ratchet/parser/parser.go:239 +0x200
created by github.com/sethvargo/ratchet/parser.Upgrade in goroutine 1
        github.com/sethvargo/ratchet/parser/parser.go:217 +0x11c

New behavior:

$ go run main.go upgrade test.yaml
$ cat test.yaml 
name: Test Thing
on:
  workflow_dispatch:
jobs:
  test:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6.0.2
      - name: Authenticate with Google Cloud
        uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # ratchet:google-github-actions/auth@v3.0.0
        with:
          project_id: 'test'
          workload_identity_provider: "projects/12345/locations/global/workloadIdentityPools/my-pool/providers/github-actions"
          service_account: "test@test.iam.gserviceaccount.com"

All existing test cases still pass without modification.

@davidizzy

Copy link
Copy Markdown

In addition to the example shared above, this change would resolve panic issues for other heavily used actions, such as actions/github-script v8.0.0 release (which is tied to tag v8 but currently shares same sha as tag v8.0.0).

Merging this fix would remove a reoccurring burden when setting up new workflows!

@sethvargo sethvargo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Could you add a test or two for this? I think this might be introducing another subtle bug.

Comment thread resolver/actions.go Outdated
Comment on lines +111 to +116
if strings.Count(version, ".") < strings.Count(githubRef.ref, ".") {
version = githubRef.ref
}
if strings.HasPrefix(ref, "v") {
refPrecision := strings.Count(githubRef.ref, ".")
versionParts := strings.Split(*release.TagName, ".")
versionParts := strings.Split(version, ".")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Does this produce the correct result when the latest release has a different major version with fewer dots? If *release.TagName is v4 and githubRef.ref is v3.0.0, the condition strings.Count("v4", ".") < strings.Count("v3.0.0", ".") is true, so version becomes v3.0.0. The function then returns the user's stale ref instead of the latest release. The dot-count comparison assumes both values refer to the same version at different precisions, but nothing enforces that. A bounds check on versionParts before slicing (or padding the release tag with .0 segments) would fix the panic without this risk.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, this should be addressed in the newest commit. Thanks for the review.

When a GitHub release uses a floating tag (e.g. v3) but the workflow
references a specific version (e.g. v3.0.0), LatestVersion panicked
with a slice bounds out of range error. To fix this, we pad the release
tag with .0 segments to match the requested precision. This ensures
version upgrades work correctly for different prevision levels.
@sethvargo sethvargo merged commit c7c5808 into sethvargo:main Apr 21, 2026
3 checks passed
@aaronhurt aaronhurt deleted the ahurt/fix-panic branch April 21, 2026 21:15
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.

3 participants