Accept dot-separated prerelease identifiers in OCI versions

Closes #473 (closed)

Closes #475 (closed)

GitLab Functions can now use SemVer prerelease versions with dots, like 0.1.0-alpha.1 or 1.2.3-rc.1. Before, only one word after the dash worked (0.1.0-alpha), and building a function with a dotted version failed:

parse version 0.1.0-alpha.1: does not conform to semver major.minor.patch

SemVer 2.0.0 item 9 allows a series of dot-separated identifiers, and both #473 (closed) and #475 (closed) ran into this. Building, publishing and pulling a function all use the same version check, so all three accept dotted versions now. I updated the OCI build and resource resolution specs to match.

Decisions I made. Please tell me if you want any of them changed:

  1. Empty identifiers are still rejected (1.2.3-beta..1, 1.2.3-beta., 1.2.3-.beta), as the spec requires.
  2. A dash with nothing after it (1.2.3-) is still accepted, because an existing test expects that.
  3. Build metadata (1.2.3+build.1) is still rejected. OCI tags can't contain +, so such a version couldn't be pushed as a tag anyway.
  4. Leading zeros (1.2.3-alpha.01) are still accepted. The main version numbers (01.02.03) are just as lenient today, so I kept that.
  5. An existing test listed 1.2.3-alpha.1.beta as invalid. I moved it to the valid cases, because it's the exact format the issues ask for.

Promote still ignores prerelease tags, dotted ones too, when it decides whether to move the 1.2, 1 and latest tags.

The CHANGELOG entry is in a second commit, under a new ## v0.46.0 heading.

I built step-runner from main and from this branch, and ran the same function with each. It has one step, taken from #475 (closed):

run:
  - name: build
    func: builtin://function/oci/build
    inputs:
      version: "0.1.0-alpha.1"
      platforms:
        linux/amd64:
          files:
            hello.sh: /hello.sh

Built from main:

$ step-runner run ./fn --job CI_PROJECT_DIR=$PWD
Running step name=build
Error: step "step": step "build": exec: parsing step inputs: parse version 0.1.0-alpha.1: does not conform to semver major.minor.patch

Built from this branch:

$ step-runner run ./fn --job CI_PROJECT_DIR=$PWD
Running step name=build
building image platform=linux/amd64
building image index
built function image archive file=.../function-image.tar size=8704

The archive's index.json has "org.opencontainers.image.version":"0.1.0-alpha.1". I didn't publish or pull by hand, because that needs a registry.

I added tests for parsing and matching dotted versions, building with 0.1.0-alpha.1, packing 1.0.0-beta.1 for publishing, and pulling a dotted tag. With only the test files copied onto main, the parsing, build and publish tests fail. I ran the 4 touched packages:

$ go test -count=1 ./pkg/runner/resource/oci/
ok  	gitlab.com/gitlab-org/step-runner/pkg/runner/resource/oci	0.905s
$ go test -count=1 ./dist/steps/step/oci/build/
ok  	gitlab.com/gitlab-org/step-runner/dist/steps/step/oci/build	0.016s
$ go test -count=1 ./dist/steps/step/oci/internal/
ok  	gitlab.com/gitlab-org/step-runner/dist/steps/step/oci/internal	0.008s
$ go test -count=1 ./dist/steps/step/oci/internal/promote/
ok  	gitlab.com/gitlab-org/step-runner/dist/steps/step/oci/internal/promote	0.003s

gofmt -l and go vet printed nothing, and golangci-lint run on those packages reported 0 issues. I didn't run make test or make go-lint locally, so I'm relying on the pipeline for those and for changelog-format.

Two things I noticed but left out of this MR:

  • Partial versions are matched as a text prefix, so asking for 1.2 also accepts 1.20.0.
  • The promote step has its own, looser version check. It already accepts dotted prereleases, but it doesn't share the same rule.

Happy to open follow-up issues for these.

Implemented with AI assistance; I reviewed and tested the changes.

Edited by Hamza Hassanain

Merge request reports

Loading
Loading