Skip to content

Commit

Permalink
Merge pull request #162 from smlx/version-type
Browse files Browse the repository at this point in the history
Add optional version type output
  • Loading branch information
smlx authored Dec 4, 2024
2 parents 2c8550d + a9756be commit 7318e2f
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 52 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ jobs:
with:
fetch-depth: 0
- id: ccv
uses: smlx/ccv@d3de774e9b607b079940a7a86952f44643743336 # v0.9.0
uses: smlx/ccv@f1246290d5eba91141b7a3ae9820051449292314 # v0.9.0-23-gf124629
with:
write-tag: false
- run: |
echo "new-tag=$NEW_TAG"
echo "new-tag-version=$NEW_TAG_VERSION"
echo "new-tag-version-type=$NEW_TAG_VERSION_TYPE"
env:
NEW_TAG: ${{steps.ccv.outputs.new-tag}}
NEW_TAG_VERSION: ${{steps.ccv.outputs.new-tag-version}}
NEW_TAG_VERSION_TYPE: ${{steps.ccv.outputs.new-tag-version-type}}
14 changes: 6 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
FROM alpine:3.20
RUN apk --no-cache add curl git jq \
&& (if echo "$TARGETPLATFORM" | grep -q arm; then \
curl -sSL $(curl -s https://api.github.com/repos/smlx/ccv/releases/latest | jq -r '.assets[].browser_download_url | select(test("linux_arm64"))'); \
else \
curl -sSL $(curl -s https://api.github.com/repos/smlx/ccv/releases/latest | jq -r '.assets[].browser_download_url | select(test("linux_amd64"))'); \
fi) \
| tar -xz -C /usr/local/bin ccv
FROM alpine:3.20@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d AS builder
COPY . .
RUN apk --no-cache add go && CGO_ENABLED=0 go build ./cmd/ccv
FROM alpine:3.20@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d
RUN apk --no-cache add git
COPY --from=builder ccv /usr/local/bin/
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ mod-tidy:

.PHONY: build
build:
GOVERSION=$$(go version) \
goreleaser build --clean --debug --single-target --snapshot
goreleaser build --clean --debug --single-target --snapshot

.PHONY: lint
lint:
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Outputs:

* `new-tag`: Either "true" or "false" depending on whether a new tag was pushed. Example: `true`.
* `new-tag-version`: The new version that was tagged. This will only be set if new_tag=true. Example: `v0.1.2`.
* `new-tag-version-type`: The new version type (major, minor, patch) was tagged. This will only be set if new_tag=true. Example: `minor`.

### Example: automatic tagging

Expand Down Expand Up @@ -92,16 +93,19 @@ jobs:
- run: |
echo "new-tag=$NEW_TAG"
echo "new-tag-version=$NEW_TAG_VERSION"
echo "new-tag-version-type=$NEW_TAG_VERSION_TYPE"
env:
NEW_TAG: ${{steps.ccv.outputs.new-tag}}
NEW_TAG_VERSION: ${{steps.ccv.outputs.new-tag-version}}
NEW_TAG_VERSION_TYPE: ${{steps.ccv.outputs.new-tag-version-type}}
```
Gives this output:
```
new-tag=true
new-tag-version=v0.16.0
new-tag-version-type=minor
```

For a fully-functional example, see the [build workflow of this repository](https://github.com/smlx/ccv/blob/main/.github/workflows/build.yaml).
Expand Down
4 changes: 3 additions & 1 deletion action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ outputs:
new-tag:
description: Either "true" or "false" depending on whether a new tag was pushed.
new-tag-version:
description: The new version that was tagged. This will only be set if new_tag=true.
description: The new version that was tagged. This will only be set if new-tag=true.
new-tag-version-type:
description: Describes the semantic version type of the new tag. One of "major", "minor", or "patch". This will only be set if new-tag=true.
runs:
using: docker
image: Dockerfile
Expand Down
31 changes: 28 additions & 3 deletions ccv.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,25 @@ func walkCommits(r *git.Repository, tagRefs map[string]string, order git.LogOrde
return latestVersion, major, minor, patch, nil
}

// NextVersion returns a string containing the next version based on the state
// of the git repository in path. It inspects the most recent tag, and the
// commits made after that tag.
// NextVersion returns a string containing the next version number based on the
// state of the git repository in path. It inspects the most recent tag, and
// the commits made after that tag.
func NextVersion(path string) (string, error) {
return nextVersion(path, false)
}

// NextVersionType returns a string containing the next version type (major,
// minor, patch) based on the state of the git repository in path. It inspects
// the most recent tag, and the commits made after that tag.
func NextVersionType(path string) (string, error) {
return nextVersion(path, true)
}

// nextVersion returns a string containing either the next version number, or
// the next version type (major, minor, patch) based on the state of the git
// repository in path. It inspects the most recent tag, and the commits made
// after that tag.
func nextVersion(path string, versionType bool) (string, error) {
// open repository
r, err := git.PlainOpenWithOptions(path, &git.PlainOpenOptions{DetectDotGit: true})
if err != nil {
Expand All @@ -83,6 +98,9 @@ func NextVersion(path string) (string, error) {
}
if len(tagRefs) == 0 {
// no existing tags
if versionType {
return "minor", nil
}
return "v0.1.0", nil
}
// now we check both main and branch to figure out what the tag should be.
Expand Down Expand Up @@ -114,15 +132,22 @@ func NextVersion(path string) (string, error) {
}
// figure out the highest increment in either parent
var newVersion semver.Version
var newVersionType string
switch {
case majorMain || majorBranch:
newVersion = latestVersion.IncMajor()
newVersionType = "major"
case minorMain || minorBranch:
newVersion = latestVersion.IncMinor()
newVersionType = "minor"
case patchMain || patchBranch:
newVersion = latestVersion.IncPatch()
newVersionType = "patch"
default:
newVersion = *latestVersion
}
if versionType {
return newVersionType, nil
}
return fmt.Sprintf("%s%s", "v", newVersion.String()), nil
}
123 changes: 97 additions & 26 deletions ccv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,72 +10,118 @@ import (

func TestNextVersion(t *testing.T) {
var testCases = map[string]struct {
gitCmds [][]string
expect string
gitCmds [][]string
expectVersion string
expectVersionType string
}{
"none": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "chore: not much"},
}, expect: "v0.1.0"},
},
expectVersion: "v0.1.0",
expectVersionType: "",
},
"patch": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "fix: minor bug"},
}, expect: "v0.1.1"},
},
expectVersion: "v0.1.1",
expectVersionType: "patch",
},
"minor": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "feat: cool new feature"},
}, expect: "v0.2.0"},
},
expectVersion: "v0.2.0",
expectVersionType: "minor",
},
"major": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "feat: major refactor\nBREAKING CHANGE: new stuff"},
}, expect: "v1.0.0"},
},
expectVersion: "v1.0.0",
expectVersionType: "major",
},
"major fix bang": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "fix!: major bug"},
}, expect: "v1.0.0"},
},
expectVersion: "v1.0.0",
expectVersionType: "major",
},
"major feat bang": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "feat!: major change"},
}, expect: "v1.0.0"},
},
expectVersion: "v1.0.0",
expectVersionType: "major",
},
"patch with scope": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "fix(lasers): minor bug"},
}, expect: "v0.1.1"},
},
expectVersion: "v0.1.1",
expectVersionType: "patch",
},
"minor with scope": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "feat(phasers): cool new feature"},
}, expect: "v0.2.0"},
},
expectVersion: "v0.2.0",
expectVersionType: "minor",
},
"major with scope": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "feat(blasters): major refactor\nBREAKING CHANGE: new stuff"},
}, expect: "v1.0.0"},
},
expectVersion: "v1.0.0",
expectVersionType: "major",
},
"major fix bang with scope": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "fix(lightsaber)!: major bug"},
}, expect: "v1.0.0"},
},
expectVersion: "v1.0.0",
expectVersionType: "major",
},
"major feat bang with scope": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"commit", "--allow-empty", "-m", "feat(bowcaster)!: major change"},
}, expect: "v1.0.0"},
},
expectVersion: "v1.0.0",
expectVersionType: "major",
},
"no existing tags feat": {gitCmds: [][]string{
{"commit", "--allow-empty", "-m", "feat: new change"},
}, expect: "v0.1.0"},
},
expectVersion: "v0.1.0",
expectVersionType: "minor",
},
"no existing tags chore": {gitCmds: [][]string{
{"commit", "--allow-empty", "-m", "chore: boring change"},
}, expect: "v0.1.0"},
},
expectVersion: "v0.1.0",
expectVersionType: "minor",
},
"on a branch": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"checkout", "-b", "new-branch"},
{"commit", "--allow-empty", "-m", "fix: minor change"},
}, expect: "v0.1.1"},
},
expectVersion: "v0.1.1",
expectVersionType: "patch",
},
"tag on a branch": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"checkout", "-b", "new-branch"},
{"commit", "--allow-empty", "-m", "fix: minor change"},
{"tag", "v0.1.1"},
{"checkout", "main"},
{"commit", "--allow-empty", "-m", "feat: minor change"},
}, expect: "v0.2.0"},
},
expectVersion: "v0.2.0",
expectVersionType: "minor",
},
"on a branch again": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"checkout", "-b", "new-branch"},
Expand All @@ -85,7 +131,10 @@ func TestNextVersion(t *testing.T) {
{"commit", "--allow-empty", "-m", "feat: minor change"},
{"tag", "v0.2.0"},
{"commit", "--allow-empty", "-m", "fix: minor change"},
}, expect: "v0.2.1"},
},
expectVersion: "v0.2.1",
expectVersionType: "patch",
},
"back on a branch": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"checkout", "-b", "new-branch"},
Expand All @@ -96,7 +145,10 @@ func TestNextVersion(t *testing.T) {
{"tag", "v0.2.0"},
{"checkout", "new-branch"},
{"commit", "--allow-empty", "-m", "fix: minor change"},
}, expect: "v0.1.2"},
},
expectVersion: "v0.1.2",
expectVersionType: "patch",
},
"main after merge": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"checkout", "-b", "new-branch"},
Expand All @@ -105,7 +157,10 @@ func TestNextVersion(t *testing.T) {
{"commit", "--allow-empty", "-m", "chore: boring change"},
{"checkout", "main"},
{"merge", "--no-ff", "new-branch", "-m", "chore: merge"},
}, expect: "v0.1.1"},
},
expectVersion: "v0.1.1",
expectVersionType: "patch",
},
"branch after merge": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"checkout", "-b", "new-branch"},
Expand All @@ -115,7 +170,10 @@ func TestNextVersion(t *testing.T) {
{"tag", "v0.1.2"},
{"checkout", "-b", "new-branch-2"},
{"commit", "--allow-empty", "-m", "feat: major change"},
}, expect: "v0.2.0"},
},
expectVersion: "v0.2.0",
expectVersionType: "minor",
},
"main after merge again": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"checkout", "-b", "new-branch"},
Expand All @@ -127,7 +185,10 @@ func TestNextVersion(t *testing.T) {
{"commit", "--allow-empty", "-m", "feat: major change"},
{"checkout", "main"},
{"merge", "--no-ff", "new-branch-2", "-m", "chore: merge"},
}, expect: "v0.2.0"},
},
expectVersion: "v0.2.0",
expectVersionType: "minor",
},
"branch before tag and merge": {gitCmds: [][]string{
{"tag", "v0.1.0"},
{"checkout", "-b", "new-branch-1"},
Expand All @@ -140,7 +201,10 @@ func TestNextVersion(t *testing.T) {
{"commit", "--allow-empty", "-m", "fix: another minor change"},
{"checkout", "main"},
{"merge", "--no-ff", "new-branch-1", "-m", "chore: merge"},
}, expect: "v0.1.2"},
},
expectVersion: "v0.1.2",
expectVersionType: "patch",
},
}
for name, tc := range testCases {
t.Run(name, func(tt *testing.T) {
Expand Down Expand Up @@ -170,10 +234,17 @@ func TestNextVersion(t *testing.T) {
}
next, err := ccv.NextVersion(dir)
if err != nil {
tt.Fatalf("error from main.nextVersion(): %v", err)
tt.Fatalf("error from main.NextVersion(): %v", err)
}
if next != tc.expect {
tt.Fatalf("expected: %v, got: %v", tc.expect, next)
if next != tc.expectVersion {
tt.Fatalf("expected: %v, got: %v", tc.expectVersion, next)
}
nextType, err := ccv.NextVersionType(dir)
if err != nil {
tt.Fatalf("error from main.NextVersionType(): %v", err)
}
if nextType != tc.expectVersionType {
tt.Fatalf("expected: %v, got: %v", tc.expectVersionType, nextType)
}
})
}
Expand Down
Loading

0 comments on commit 7318e2f

Please sign in to comment.