diff --git a/README.md b/README.md index 048be7d2..4dc832b0 100644 --- a/README.md +++ b/README.md @@ -228,10 +228,17 @@ be one of: type, (e.g. `alpha` vs. `beta`), the type is switched and the prerelease version is reset to `1`. If the version is *not* already a pre-release, then `pre` is added, starting at `1`. - - The value of `pre` can be anything you like; the value will be `pre`-pended (_hah_) to a numeric value. For example, `pre: build` will result in a semver of `x.y.z-build.`, `pre: alpha` becomes `x.y.z-alpha.`, and `pre: my-preferred-naming-convention` becomes `x.y.z-my-preferred-naming-convention.` - If `pre_without_version` is set as `true`, the value will be `pre` and no version number. So `SNAPSHOT` will still be as `SNAPSHOT`, + The value of `pre` can be anything you like; the value will be `pre`-pended (_hah_) to a numeric value. For example, `pre: foo` will result in a semver of `x.y.z-foo.`, `pre: alpha` becomes `x.y.z-alpha.`, and `pre: my-preferred-naming-convention` becomes `x.y.z-my-preferred-naming-convention.` + +* `build`: *Optional.* Same as `pre` but for build labels (e.g. `build: foo` + will result in a semver of `x.y.z+foo.`, `build: alpha` becomes + `x.y.z+alpha.`. + + It is valid for a semver to be both a prerelease and a build, for example, + `pre: alpha, build: test` results in `x.y.z-alpha.+test.` +* `pre_without_version`: *Optional.* When bumping to a prerelease, drop the + version if set to `true`. Examples: * Major version bump: version file = 1.2.4-SNAPSHOT, release version = 2.0.0 * Minor version bump: version file = 1.2.4-SNAPSHOT, release version = 1.3.0 diff --git a/in/in_test.go b/in/in_test.go index fe1c0985..48f871ec 100644 --- a/in/in_test.go +++ b/in/in_test.go @@ -14,7 +14,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" "github.com/concourse/semver-resource/models" - "github.com/nu7hatch/gouuid" + uuid "github.com/nu7hatch/gouuid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" diff --git a/in/main.go b/in/main.go index a3fb4a1f..63f5f02a 100644 --- a/in/main.go +++ b/in/main.go @@ -37,9 +37,12 @@ func main() { } bumped := version.BumpFromParams( - request.Params.Bump, + request.Params.Bump, request.Params.Pre, - request.Params.PreWithoutVersion).Apply(inputVersion) + request.Params.PreWithoutVersion, + request.Params.Build, + request.Params.BuildWithoutVersion, + ).Apply(inputVersion) if !bumped.Equals(inputVersion) { fmt.Fprintf(os.Stderr, "bumped locally from %s to %s\n", inputVersion, bumped) diff --git a/models/models.go b/models/models.go index d053eb57..91aa4887 100644 --- a/models/models.go +++ b/models/models.go @@ -16,9 +16,11 @@ type InResponse struct { } type InParams struct { - Bump string `json:"bump"` - Pre string `json:"pre"` - PreWithoutVersion bool `json:"pre_without_version"` + Bump string `json:"bump"` + Pre string `json:"pre"` + Build string `json:"build"` + PreWithoutVersion bool `json:"pre_without_version"` + BuildWithoutVersion bool `json:"build_without_version"` } type OutRequest struct { @@ -35,9 +37,11 @@ type OutResponse struct { type OutParams struct { File string `json:"file"` - Bump string `json:"bump"` - Pre string `json:"pre"` - PreWithoutVersion bool `json:"pre_without_version"` + Bump string `json:"bump"` + Pre string `json:"pre"` + Build string `json:"build"` + PreWithoutVersion bool `json:"pre_without_version"` + BuildWithoutVersion bool `json:"build_without_version"` } type CheckRequest struct { diff --git a/out/main.go b/out/main.go index 45b926c2..fc2d97a4 100644 --- a/out/main.go +++ b/out/main.go @@ -58,9 +58,12 @@ func main() { } } else if request.Params.Bump != "" || request.Params.Pre != "" { bump := version.BumpFromParams( - request.Params.Bump, - request.Params.Pre, - request.Params.PreWithoutVersion) + request.Params.Bump, + request.Params.Pre, + request.Params.PreWithoutVersion, + request.Params.Build, + request.Params.BuildWithoutVersion, + ) newVersion, err = driver.Bump(bump) if err != nil { diff --git a/out/out_test.go b/out/out_test.go index 8b41b307..109bd0cc 100644 --- a/out/out_test.go +++ b/out/out_test.go @@ -15,7 +15,7 @@ import ( "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" "github.com/concourse/semver-resource/models" - "github.com/nu7hatch/gouuid" + uuid "github.com/nu7hatch/gouuid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" @@ -269,5 +269,142 @@ var _ = Describe("Out", func() { }) }) }) + + Context("when bumping the version to a build", func() { + BeforeEach(func() { + request.Params.Build = "build" + }) + + Context("when the version is not a build", func() { + BeforeEach(func() { + putVersion("1.2.3") + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.2.3+build.1")) + }) + + It("saves the contents of the file in the configured bucket", func() { + Expect(getVersion()).To(Equal("1.2.3+build.1")) + }) + + Context("when doing a semantic bump at the same time", func() { + BeforeEach(func() { + request.Params.Bump = "minor" + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.3.0+build.1")) + }) + + It("saves the contents of the file in the configured bucket", func() { + Expect(getVersion()).To(Equal("1.3.0+build.1")) + }) + }) + }) + + Context("when the version is the same build", func() { + BeforeEach(func() { + putVersion("1.2.3+build.2") + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.2.3+build.3")) + }) + + It("saves the contents of the file in the configured bucket", func() { + Expect(getVersion()).To(Equal("1.2.3+build.3")) + }) + + Context("when doing a semantic bump at the same time", func() { + BeforeEach(func() { + request.Params.Bump = "minor" + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.3.0+build.1")) + }) + + It("saves the contents of the file in the configured bucket", func() { + Expect(getVersion()).To(Equal("1.3.0+build.1")) + }) + }) + }) + + Context("when the version is a different build", func() { + BeforeEach(func() { + putVersion("1.2.3-beta.2") + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.2.3+build.1")) + }) + + It("saves the contents of the file in the configured bucket", func() { + Expect(getVersion()).To(Equal("1.2.3+build.1")) + }) + + Context("when doing a semantic bump at the same time", func() { + BeforeEach(func() { + request.Params.Bump = "minor" + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.3.0+build.1")) + }) + + It("saves the contents of the file in the configured bucket", func() { + Expect(getVersion()).To(Equal("1.3.0+build.1")) + }) + }) + }) + }) + + Context("when bumping the version to a prerelease and build", func() { + BeforeEach(func() { + request.Params.Pre = "alpha" + request.Params.Build = "build" + }) + + Context("when the version is just a base version", func() { + BeforeEach(func() { + putVersion("1.2.3") + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.2.3-alpha.1+build.1")) + }) + }) + + Context("when the version has a prerelease", func() { + BeforeEach(func() { + putVersion("1.2.3-alpha.1") + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.2.3-alpha.2+build.1")) + }) + }) + + Context("when the version has a build", func() { + BeforeEach(func() { + putVersion("1.2.3+build.1") + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.2.3-alpha.1+build.2")) + }) + }) + + Context("when the version has a build and prerelease", func() { + BeforeEach(func() { + putVersion("1.2.3-alpha.1+build.1") + }) + + It("reports the bumped version as the version", func() { + Expect(response.Version.Number).To(Equal("1.2.3-alpha.2+build.2")) + }) + }) + }) }) }) diff --git a/test/helpers.sh b/test/helpers.sh index 05014e2d..30bfe753 100644 --- a/test/helpers.sh +++ b/test/helpers.sh @@ -152,7 +152,8 @@ put_uri_with_bump() { }, params: { bump: $(echo $3 | jq -R .), - pre: $(echo $4 | jq -R .) + pre: $(echo $4 | jq -R .), + build: $(echo $5 | jq -R .) } }" | ${resource_dir}/out "$2" | tee /dev/stderr } @@ -168,7 +169,8 @@ put_uri_with_bump_and_initial() { }, params: { bump: $(echo $4 | jq -R .), - pre: $(echo $5 | jq -R .) + pre: $(echo $5 | jq -R .), + build: $(echo $6 | jq -R .) } }" | ${resource_dir}/out "$2" | tee /dev/stderr } @@ -180,11 +182,12 @@ put_uri_with_bump_and_message() { uri: $(echo $1 | jq -R .), branch: \"master\", file: \"some-file\", - commit_message: \"$(echo $5)\" + commit_message: \"$(echo $6)\" }, params: { bump: $(echo $3 | jq -R .), - pre: $(echo $4 | jq -R .) + pre: $(echo $4 | jq -R .), + build: $(echo $5 | jq -R .) } }" | ${resource_dir}/out "$2" | tee /dev/stderr } diff --git a/test/put.sh b/test/put.sh index 62289dfe..e82cd993 100755 --- a/test/put.sh +++ b/test/put.sh @@ -76,15 +76,15 @@ it_can_put_and_bump_first_version() { # cannot push to repo while it's checked out to a branch git -C $repo checkout refs/heads/master - put_uri_with_bump $repo $src minor alpha | jq -e " - .version == {number: \"0.1.0-alpha.1\"} + put_uri_with_bump $repo $src minor alpha build | jq -e " + .version == {number: \"0.1.0-alpha.1+build.1\"} " # switch back to master git -C $repo checkout master test -e $repo/some-file - test "$(cat $repo/some-file)" = 0.1.0-alpha.1 + test "$(cat $repo/some-file)" = 0.1.0-alpha.1+build.1 } it_can_put_and_bump_first_version_with_initial() { @@ -95,15 +95,15 @@ it_can_put_and_bump_first_version_with_initial() { # cannot push to repo while it's checked out to a branch git -C $repo checkout refs/heads/master - put_uri_with_bump_and_initial $repo $src 1.2.3 minor alpha | jq -e " - .version == {number: \"1.3.0-alpha.1\"} + put_uri_with_bump_and_initial $repo $src 1.2.3 minor alpha build | jq -e " + .version == {number: \"1.3.0-alpha.1+build.1\"} " # switch back to master git -C $repo checkout master test -e $repo/some-file - test "$(cat $repo/some-file)" = 1.3.0-alpha.1 + test "$(cat $repo/some-file)" = 1.3.0-alpha.1+build.1 } it_can_put_and_bump_over_existing_version() { @@ -116,15 +116,15 @@ it_can_put_and_bump_over_existing_version() { # cannot push to repo while it's checked out to a branch git -C $repo checkout refs/heads/master - put_uri_with_bump $repo $src minor alpha | jq -e " - .version == {number: \"1.3.0-alpha.1\"} + put_uri_with_bump $repo $src minor alpha build | jq -e " + .version == {number: \"1.3.0-alpha.1+build.1\"} " # switch back to master git -C $repo checkout master test -e $repo/some-file - test "$(cat $repo/some-file)" = 1.3.0-alpha.1 + test "$(cat $repo/some-file)" = 1.3.0-alpha.1+build.1 } it_can_put_and_bump_with_message_over_existing_version() { @@ -139,15 +139,15 @@ it_can_put_and_bump_with_message_over_existing_version() { # cannot push to repo while it's checked out to a branch git -C $repo checkout refs/heads/master - put_uri_with_bump_and_message $repo $src minor alpha "$message" | jq -e " - .version == {number: \"1.3.0-alpha.1\"} + put_uri_with_bump_and_message $repo $src minor alpha build "$message" | jq -e " + .version == {number: \"1.3.0-alpha.1+build.1\"} " # switch back to master git -C $repo checkout master test -e $repo/some-file - test "$(cat $repo/some-file)" = 1.3.0-alpha.1 + test "$(cat $repo/some-file)" = 1.3.0-alpha.1+build.1 test "$(git -C $repo log -n1 --pretty=%B)" = "$message" } @@ -163,17 +163,17 @@ it_can_put_and_bump_with_message_and_replace_over_existing_version() { # cannot push to repo while it's checked out to a branch git -C $repo checkout refs/heads/master - put_uri_with_bump_and_message $repo $src minor alpha "$message" | jq -e " - .version == {number: \"1.3.0-alpha.1\"} + put_uri_with_bump_and_message $repo $src minor alpha build "$message" | jq -e " + .version == {number: \"1.3.0-alpha.1+build.1\"} " # switch back to master git -C $repo checkout master - local expected_message="This is a commit message on some-file with 1.3.0-alpha.1" + local expected_message="This is a commit message on some-file with 1.3.0-alpha.1+build.1" test -e $repo/some-file - test "$(cat $repo/some-file)" = 1.3.0-alpha.1 + test "$(cat $repo/some-file)" = 1.3.0-alpha.1+build.1 test "$(git -C $repo log -n1 --pretty=%B)" = "$expected_message" } diff --git a/version/build_bump.go b/version/build_bump.go new file mode 100644 index 00000000..01ab4f4c --- /dev/null +++ b/version/build_bump.go @@ -0,0 +1,39 @@ +package version + +import ( + "strconv" + + "github.com/blang/semver" +) + +type BuildBump struct { + Build string + BuildWithoutVersion bool +} + +func (bump BuildBump) Apply(v semver.Version) semver.Version { + if bump.BuildWithoutVersion { + v.Build = []string{ + bump.Build, + } + } else if v.Build == nil || len(v.Build) < 2 || v.Build[0] != bump.Build { + // no build, no build version, different build id -> set build to 1 + v.Build = []string{ + bump.Build, strconv.Itoa(1), + } + } else { + version, err := strconv.Atoi(v.Build[1]) + if err != nil { + // invalid build version -> set build to 1 + v.Build = []string{ + bump.Build, strconv.Itoa(1), + } + } + + v.Build = []string{ + bump.Build, strconv.Itoa(version + 1), + } + } + + return v +} diff --git a/version/build_bump_test.go b/version/build_bump_test.go new file mode 100644 index 00000000..6a49181b --- /dev/null +++ b/version/build_bump_test.go @@ -0,0 +1,166 @@ +package version_test + +import ( + "github.com/blang/semver" + "github.com/concourse/semver-resource/version" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("BuildBump", func() { + var inputVersion semver.Version + var bump version.BuildBump + var outputVersion semver.Version + + BeforeEach(func() { + inputVersion = semver.Version{ + Major: 1, + Minor: 2, + Patch: 3, + } + + bump = version.BuildBump{} + }) + + JustBeforeEach(func() { + outputVersion = bump.Apply(inputVersion) + }) + + Context("when the build is without version number", func() { + BeforeEach(func() { + bump.Build = "omega" + bump.BuildWithoutVersion = true + }) + + Context("when the input is not a build", func() { + BeforeEach(func() { + inputVersion.Build = nil + }) + + It("bmps the build without version number", func() { + Expect(outputVersion).To(Equal(semver.Version{ + Major: 1, + Minor: 2, + Patch: 3, + Build: []string{ + "omega", + }, + })) + }) + }) + + Context("when the input is a build", func() { + Context("when the bump is a different build type", func() { + BeforeEach(func() { + inputVersion.Build = []string{ + "alpha", + } + }) + + It("bmps the build without version number", func() { + Expect(outputVersion).To(Equal(semver.Version{ + Major: 1, + Minor: 2, + Patch: 3, + Build: []string{ + "omega", + }, + })) + }) + }) + + Context("when the bump is the same build type", func() { + BeforeEach(func() { + inputVersion.Build = []string{ + "omega", "1", + } + }) + + It("bmps the build without version number", func() { + Expect(outputVersion).To(Equal(semver.Version{ + Major: 1, + Minor: 2, + Patch: 3, + Build: []string{ + "omega", + }, + })) + }) + }) + }) + }) + + Context("when the version is a build", func() { + BeforeEach(func() { + inputVersion.Build = []string{ + "alpha", "1", + } + }) + + Context("when the bump is the same build type", func() { + BeforeEach(func() { + bump.Build = "alpha" + }) + + It("bumps the build version number", func() { + Expect(outputVersion).To(Equal(semver.Version{ + Major: 1, + Minor: 2, + Patch: 3, + Build: []string{ + "alpha", "2", + }, + })) + }) + + It("does not mutate the input version", func() { + Expect(inputVersion).To(Equal(semver.Version{ + Major: 1, + Minor: 2, + Patch: 3, + Build: []string{ + "alpha", "1", + }, + })) + }) + }) + + Context("when the bump is a different build type", func() { + BeforeEach(func() { + bump.Build = "beta" + }) + + It("bumps bumps to version 1 of the new build type", func() { + Expect(outputVersion).To(Equal(semver.Version{ + Major: 1, + Minor: 2, + Patch: 3, + Build: []string{ + "beta", "1", + }, + })) + }) + }) + }) + + Context("when the version is not a build", func() { + BeforeEach(func() { + inputVersion.Build = nil + }) + + BeforeEach(func() { + bump.Build = "beta" + }) + + It("bumps bumps to version 1 of the new build type", func() { + Expect(outputVersion).To(Equal(semver.Version{ + Major: 1, + Minor: 2, + Patch: 3, + Build: []string{ + "beta", "1", + }, + })) + }) + }) +}) diff --git a/version/bump_from_params.go b/version/bump_from_params.go index fc10c40e..d0e68b0f 100644 --- a/version/bump_from_params.go +++ b/version/bump_from_params.go @@ -1,8 +1,6 @@ package version - - -func BumpFromParams(bumpStr string, preStr string, preWithoutVersion bool) Bump { +func BumpFromParams(bumpStr string, preStr string, preWithoutVersion bool, buildStr string, BuildWithoutVersion bool) Bump { var semverBump Bump switch bumpStr { @@ -25,5 +23,8 @@ func BumpFromParams(bumpStr string, preStr string, preWithoutVersion bool) Bump bump = append(bump, PreBump{preStr, preWithoutVersion}) } + if buildStr != "" { + bump = append(bump, BuildBump{buildStr, BuildWithoutVersion}) + } return bump } diff --git a/version/bump_from_params_test.go b/version/bump_from_params_test.go index ca56190d..6baf80b2 100644 --- a/version/bump_from_params_test.go +++ b/version/bump_from_params_test.go @@ -14,9 +14,11 @@ var _ = Describe("BumpForParams", func() { var ( version semver.Version - bumpParam string - preParam string - preWithoutVersionParam bool + bumpParam string + preParam string + buildParam string + preWithoutVersionParam bool + buildWithoutVersionParam bool ) BeforeEach(func() { @@ -28,11 +30,13 @@ var _ = Describe("BumpForParams", func() { bumpParam = "" preParam = "" + buildParam = "" preWithoutVersionParam = false + buildWithoutVersionParam = false }) JustBeforeEach(func() { - version = BumpFromParams(bumpParam, preParam, preWithoutVersionParam).Apply(version) + version = BumpFromParams(bumpParam, preParam, preWithoutVersionParam, buildParam, buildWithoutVersionParam).Apply(version) }) for bump, result := range map[string]string{ diff --git a/version/pre_bump.go b/version/pre_bump.go index 57e00599..9358f2f2 100644 --- a/version/pre_bump.go +++ b/version/pre_bump.go @@ -3,7 +3,7 @@ package version import "github.com/blang/semver" type PreBump struct { - Pre string + Pre string PreWithoutVersion bool } @@ -12,16 +12,13 @@ func (bump PreBump) Apply(v semver.Version) semver.Version { v.Pre = []semver.PRVersion{ {VersionStr: bump.Pre}, } - } else if v.Pre == nil || v.Pre[0].VersionStr != bump.Pre { + } else if v.Pre == nil || len(v.Pre) < 2 || v.Pre[0].VersionStr != bump.Pre { + // no pre-release, no pre-release version, or different pre-release id -> set version to 1 v.Pre = []semver.PRVersion{ {VersionStr: bump.Pre}, {VersionNum: 1, IsNum: true}, } } else { - if len(v.Pre) < 2 { - v.Pre = append(v.Pre, semver.PRVersion{VersionNum: 0, IsNum: true}) - } - v.Pre = []semver.PRVersion{ {VersionStr: bump.Pre}, {VersionNum: v.Pre[1].VersionNum + 1, IsNum: true},