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
Version File Plugin #2107
Merged
Merged
Version File Plugin #2107
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
5558326
Core hooks scaffolded out
KetanReddy 136ec9d
canary and next hooks
KetanReddy 7923405
use echo rather than fs to write version to file
KetanReddy 7b134e0
Fix canary versioning
KetanReddy 1ed6139
Test for next release hook
KetanReddy 3b025e6
Rename to be more accurate. Make releaseScript optional, update tests.
KetanReddy da1d63b
include the version-file plugin with the cli
KetanReddy 6055c44
Fix straggling naming reference
KetanReddy 163c082
rename releaseScript to publishScript to keep naming consistant
KetanReddy c645dc8
Fix issue with getting last release in canary builds with no previous…
KetanReddy 5f1618e
change plugin name to match convention
KetanReddy 367ddcd
remove duplicate dash in canary version names
KetanReddy 475950b
fix failing test
KetanReddy 59292fb
Fix version in commit string not being replaced. Align versioning sch…
KetanReddy ceba7a2
Make sure quotes are included in commit message
KetanReddy a9cac5d
Fix more tests
KetanReddy File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,9 @@ | |
}, | ||
{ | ||
"path": "../../plugins/released" | ||
}, | ||
{ | ||
"path": "../../plugins/version-file" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Version File Plugin | ||
|
||
For managing versions in a repository that maintains the version primarily in a flat file. | ||
Agnostic to the primary language of the repository. | ||
Optional input for a release script to call during the publish/canary/next hooks. | ||
|
||
## Installation | ||
|
||
This plugin is included with the `auto` CLI so you do not have to install it. To install if you are using the `auto` API directly: | ||
|
||
```bash | ||
npm i --save-dev @auto-it/version-file | ||
# or | ||
yarn add -D @auto-it/version-file | ||
``` | ||
|
||
## Options | ||
|
||
- versionFile (optional, default="VERSION"): Path to where the version is stored in the repository. It should be a file containing just the semver. | ||
- releaseScript: (optional, default=None): Path to script that runs the publish actions in your repository. If not supplied nothing will be called. If supplied will be called during the `publish`,`canary` and `next` hooks. For the `publish` hook the first parameter passed to the script will be `release` to indicate that a regular release is being called. For `canary` and `next` hooks the first parameter will be `snapshot` to indicate a prerelease version. | ||
|
||
## Usage | ||
|
||
### With default options | ||
```json | ||
{ | ||
"plugins": [ | ||
"version-file" | ||
// other plugins | ||
] | ||
} | ||
``` | ||
### With optional arguments | ||
```json | ||
{ | ||
"plugins": [ | ||
"version-file", {"versionFile": "./tools/Version.txt", "releaseScript":"./tools/publish.sh"} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,305 @@ | ||
import Auto, { SEMVER } from '@auto-it/core'; | ||
import mockFs from "mock-fs"; | ||
import fs from "fs"; | ||
import BazelPlugin from '../src'; | ||
import { makeHooks } from '@auto-it/core/dist/utils/make-hooks'; | ||
import { dummyLog } from "@auto-it/core/dist/utils/logger"; | ||
|
||
// Mocks | ||
const execPromise = jest.fn(); | ||
jest.mock( | ||
"../../../packages/core/dist/utils/exec-promise", | ||
() => (...args: any[]) => execPromise(...args) | ||
); | ||
jest.mock("../../../packages/core/dist/utils/get-current-branch", () => ({ | ||
getCurrentBranch: () => "main", | ||
})); | ||
|
||
beforeEach(() => { | ||
execPromise.mockClear(); | ||
}); | ||
afterEach(() => { | ||
mockFs.restore(); | ||
}) | ||
|
||
describe('Version File Read Operations', () => { | ||
test("It should return the value in the default file", async () => { | ||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
} as Auto); | ||
|
||
expect(await hooks.getPreviousVersion.promise()).toBe("1.0.0"); | ||
}); | ||
|
||
test("It should return the value in the specified file", async () => { | ||
mockFs({ | ||
"VERSIONFILE": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({versionFile: "VERSIONFILE"}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
} as Auto); | ||
|
||
expect(await hooks.getPreviousVersion.promise()).toBe("1.0.0"); | ||
}); | ||
}); | ||
|
||
describe("Version File Write Operations", () => { | ||
test("It should version the file properly for major releases", async () => { | ||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
} as Auto); | ||
|
||
await hooks.version.promise({bump: SEMVER.major}) | ||
expect(fs.readFileSync("VERSION", "utf-8")).toStrictEqual("2.0.0") | ||
// check that the proper git operations were performed | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "git", ["commit", "-am", "\"Bump version to: v2.0.0 [skip ci]\""]); | ||
expect(execPromise).toHaveBeenNthCalledWith(2, "git", ["tag", "v2.0.0"]); | ||
}); | ||
|
||
test("It should version the file properly for minor releases", async () => { | ||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
} as Auto); | ||
|
||
await hooks.version.promise({bump: SEMVER.minor}) | ||
expect(fs.readFileSync("VERSION", "utf-8")).toStrictEqual("1.1.0"); | ||
// check that the proper git operations were performed | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "git", ["commit", "-am", "\"Bump version to: v1.1.0 [skip ci]\""]); | ||
expect(execPromise).toHaveBeenNthCalledWith(2, "git", ["tag", "v1.1.0"]); | ||
}); | ||
|
||
test("It should version the file properly for patch releases", async () => { | ||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
} as Auto); | ||
|
||
await hooks.version.promise({bump: SEMVER.patch}) | ||
expect(fs.readFileSync("VERSION", "utf-8")).toStrictEqual("1.0.1"); | ||
// check that the proper git operations were performed | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "git", ["commit", "-am", "\"Bump version to: v1.0.1 [skip ci]\""]); | ||
expect(execPromise).toHaveBeenNthCalledWith(2, "git", ["tag", "v1.0.1"]); | ||
}); | ||
}) | ||
|
||
describe("Test Release Types", () => { | ||
test("Full release with no release script", async () => { | ||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
} as Auto); | ||
|
||
await hooks.publish.promise({bump: SEMVER.major}) | ||
|
||
// check release script was not called but check changes would be pushed | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "git", ["push", "origin", "main", "--tags"]); | ||
}); | ||
|
||
test("Full release with release script", async () => { | ||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({publishScript:"./tools/release.sh"}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
} as Auto); | ||
|
||
await hooks.publish.promise({bump: SEMVER.major}) | ||
|
||
// check release script was called | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "./tools/release.sh", ["release"]); | ||
|
||
// check changes would be pushed | ||
expect(execPromise).toHaveBeenNthCalledWith(2, "git", ["push", "origin", "main", "--tags"]); | ||
}); | ||
|
||
test("Canary release with no release script", async () => { | ||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply(({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
getCurrentVersion: () => "1.0.0", | ||
git: { | ||
getLatestRelease: () => "1.0.0", | ||
getLatestTagInBranch: () => Promise.resolve("1.0.0"), | ||
}, | ||
} as unknown) as Auto); | ||
|
||
await hooks.canary.promise({bump: SEMVER.minor, canaryIdentifier: "canary.368.1"}) | ||
|
||
// check release script was not called and local changes were reverted | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "git", ["reset", "--hard", "HEAD"]); | ||
|
||
// Check the right version was written | ||
expect(fs.readFileSync("VERSION", "utf-8")).toStrictEqual("1.1.0-canary.368.1") | ||
}); | ||
|
||
test("Canary release with release script", async () => { | ||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({publishScript:"./tools/release.sh"}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply(({ | ||
hooks, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
getCurrentVersion: () => "1.0.0", | ||
git: { | ||
getLatestRelease: () => "1.0.0", | ||
getLatestTagInBranch: () => Promise.resolve("1.0.0"), | ||
}, | ||
} as unknown) as Auto); | ||
|
||
await hooks.canary.promise({bump: SEMVER.minor, canaryIdentifier: "canary.368.1"}) | ||
|
||
// check release script was called | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "./tools/release.sh", ["snapshot"]); | ||
|
||
// check local changes were reverted | ||
expect(execPromise).toHaveBeenNthCalledWith(2, "git", ["reset", "--hard", "HEAD"]); | ||
|
||
// Check the right version was written | ||
expect(fs.readFileSync("VERSION", "utf-8")).toStrictEqual("1.1.0-canary.368.1") | ||
}); | ||
|
||
test("Next release with no release script", async () => { | ||
|
||
const prefixRelease: (a: string) => string = (version: string) => { | ||
return `v${version}`; | ||
}; | ||
|
||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply(({ | ||
hooks, | ||
config: { prereleaseBranches: ["next"] }, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
prefixRelease, | ||
getCurrentVersion: () => "1.0.0", | ||
git: { | ||
getLastTagNotInBaseBranch: async () => undefined, | ||
getLatestRelease: () => "1.0.0", | ||
getLatestTagInBranch: () => Promise.resolve("1.0.0"), | ||
}, | ||
} as unknown) as Auto); | ||
|
||
await hooks.next.promise(["1.0.0"], {bump: SEMVER.major, fullReleaseNotes:"", releaseNotes:"", commits:[]}) | ||
|
||
// check release script was not called but git ops were performed | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "git", ["tag", "v2.0.0-next.0"]); | ||
expect(execPromise).toHaveBeenNthCalledWith(2, "git", ["push", "origin", "main", "--tags"]); | ||
|
||
// Check the right version was written | ||
expect(fs.readFileSync("VERSION", "utf-8")).toStrictEqual("v2.0.0-next.0") | ||
}); | ||
|
||
test("Next release with release script", async () => { | ||
|
||
const prefixRelease: (a: string) => string = (version: string) => { | ||
return `v${version}`; | ||
}; | ||
|
||
mockFs({ | ||
"VERSION": `1.0.0`, | ||
}); | ||
const plugin = new BazelPlugin({publishScript:"./tools/release.sh"}); | ||
const hooks = makeHooks(); | ||
|
||
plugin.apply(({ | ||
hooks, | ||
config: { prereleaseBranches: ["next"] }, | ||
remote: "origin", | ||
baseBranch: "main", | ||
logger: dummyLog(), | ||
prefixRelease, | ||
getCurrentVersion: () => "1.0.0", | ||
git: { | ||
getLastTagNotInBaseBranch: async () => undefined, | ||
getLatestRelease: () => "1.0.0", | ||
getLatestTagInBranch: () => Promise.resolve("1.0.0"), | ||
}, | ||
} as unknown) as Auto); | ||
|
||
await hooks.next.promise(["1.0.0"], {bump: SEMVER.major, fullReleaseNotes:"", releaseNotes:"", commits:[]}) | ||
|
||
// check release script was called | ||
expect(execPromise).toHaveBeenNthCalledWith(1, "./tools/release.sh", ["snapshot"]); | ||
|
||
// Check git ops | ||
expect(execPromise).toHaveBeenNthCalledWith(2, "git", ["tag", "v2.0.0-next.0"]); | ||
expect(execPromise).toHaveBeenNthCalledWith(3, "git", ["push", "origin", "main", "--tags"]); | ||
|
||
// Check the right version was written | ||
expect(fs.readFileSync("VERSION", "utf-8")).toStrictEqual("v2.0.0-next.0") | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that you've called it out, should probably keep naming consistent here. If this is only called in the
publish
hook, then it'd be more appropriately namedpublishScript
or something like that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I will make it more explicit. Changes are pushed and rebuilding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KetanReddy looks like you did update the naming in the actual plugin. Can you update the docs to reflect those changes?