Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2107 from KetanReddy/bazel-plugin
Version File Plugin
- Loading branch information
Showing
8 changed files
with
611 additions
and
0 deletions.
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.