Skip to content
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

Add GH release workflow and bump-version action, fix hard-coded client version #66

Merged
merged 1 commit into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/bump-version/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entire action was lifted from work @jhamon did previously: pinecone-io/pinecone-python-client#178

I'll call out lines I modified, which should be within action.js and index.js where I got rid of modifying local files via fs.readFileSync and fs.writeFileSync. I'm doing the file manipulating using sed in the release.yaml file.

36 changes: 36 additions & 0 deletions .github/actions/bump-version/action.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const core = require("./core");

function bumpVersion(currentVersion, bumpType, prerelease) {
let newVersion = calculateNewVersion(currentVersion, bumpType);

if (prerelease) {
newVersion = `${newVersion}.${prerelease}`;
}
core.setOutput("previous_version", currentVersion);
core.setOutput("previous_version_tag", `v${currentVersion}`);
core.setOutput("version", newVersion);
core.setOutput("version_tag", `v${newVersion}`);
}
Comment on lines +12 to +13
Copy link
Contributor Author

@austin-denoble austin-denoble Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got rid of the return newVersion here since we're not using it in index.js.


function calculateNewVersion(currentVersion, bumpType) {
const [major, minor, patch] = currentVersion.split(".");
let newVersion;

switch (bumpType) {
case "major":
newVersion = `${parseInt(major) + 1}.0.0`;
break;
case "minor":
newVersion = `${major}.${parseInt(minor) + 1}.0`;
break;
case "patch":
newVersion = `${major}.${minor}.${parseInt(patch) + 1}`;
break;
default:
throw new Error(`Invalid bumpType: ${bumpType}`);
}

return newVersion;
}

module.exports = { bumpVersion };
114 changes: 114 additions & 0 deletions .github/actions/bump-version/action.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const action = require("./action");
const core = require("./core");

jest.mock("./core");

describe("bump-version", () => {
test("bump major", () => {
action.bumpVersion("1.2.3", "major", "");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "1.2.3");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v1.2.3"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "2.0.0");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v2.0.0");
});

test("bump minor: existing minor and patch", () => {
action.bumpVersion("1.2.3", "minor", "");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "1.2.3");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v1.2.3"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "1.3.0");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v1.3.0");
});

test("bump minor: with no patch", () => {
action.bumpVersion("1.2.0", "minor", "");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "1.2.0");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v1.2.0"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "1.3.0");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v1.3.0");
});

test("bump minor: from existing patch", () => {
action.bumpVersion("2.2.3", "minor", "");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "2.2.3");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v2.2.3"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "2.3.0");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v2.3.0");
});

test("bump patch: existing patch", () => {
action.bumpVersion("1.2.3", "patch", "");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "1.2.3");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v1.2.3"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "1.2.4");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v1.2.4");
});

test("bump patch: minor with no patch", () => {
action.bumpVersion("1.2.0", "patch", "");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "1.2.0");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v1.2.0"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "1.2.1");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v1.2.1");
});

test("bump patch: major with no minor or patch", () => {
action.bumpVersion("1.0.0", "patch", "");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "1.0.0");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v1.0.0"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "1.0.1");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v1.0.1");
});

test("bump patch: major with minor", () => {
action.bumpVersion("1.1.0", "patch", "");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "1.1.0");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v1.1.0"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "1.1.1");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v1.1.1");
});

test("prerelease suffix provided", () => {
action.bumpVersion("1.2.3", "patch", "rc1");

expect(core.setOutput).toHaveBeenCalledWith("previous_version", "1.2.3");
expect(core.setOutput).toHaveBeenCalledWith(
"previous_version_tag",
"v1.2.3"
);
expect(core.setOutput).toHaveBeenCalledWith("version", "1.2.4.rc1");
expect(core.setOutput).toHaveBeenCalledWith("version_tag", "v1.2.4.rc1");
});
});
29 changes: 29 additions & 0 deletions .github/actions/bump-version/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: 'pinecone-io/bump-version'

description: 'Bumps a given semantic version number based on a bumpType and prereleaseSuffix'

inputs:
currentVersion:
description: 'The current version of the client to bump from'
required: true
bumpType:
description: 'The type of version bump (major, minor, patch)'
required: true
prereleaseSuffix:
description: 'Optional prerelease identifier to append to the version number'
required: false
default: ''

outputs:
version:
description: 'The new version number'
version_tag:
description: 'The new version tag'
previous_version:
description: 'The previous version number'
previous_version_tag:
description: 'The previous version tag'

runs:
using: 'node20'
main: 'index.js'
79 changes: 79 additions & 0 deletions .github/actions/bump-version/core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copied these commands out of the github actions toolkit
// because actually depending on @actions/core requires me to check
// in node_modules and 34MB of dependencies, which I don't want to do.

const fs = require("fs");
const os = require("os");

function getInput(name, options) {
const val =
process.env[`INPUT_${name.replace(/ /g, "_").toUpperCase()}`] || "";
if (options && options.required && !val) {
throw new Error(`Input required and not supplied: ${name}`);
}

if (options && options.trimWhitespace === false) {
return val;
}

return val.trim();
}

function toCommandValue(input) {
if (input === null || input === undefined) {
return "";
} else if (typeof input === "string" || input instanceof String) {
return input;
}
return JSON.stringify(input);
}

function prepareKeyValueMessage(key, value) {
const delimiter = `delimiter_${Math.floor(Math.random() * 100000)}`;
const convertedValue = toCommandValue(value);

// These should realistically never happen, but just in case someone finds a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

// way to exploit uuid generation let's not allow keys or values that contain
// the delimiter.
if (key.includes(delimiter)) {
throw new Error(
`Unexpected input: name should not contain the delimiter "${delimiter}"`
);
}

if (convertedValue.includes(delimiter)) {
throw new Error(
`Unexpected input: value should not contain the delimiter "${delimiter}"`
);
}

return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
}

function setOutput(name, value) {
const filePath = process.env["GITHUB_OUTPUT"] || "";
if (filePath) {
return issueFileCommand("OUTPUT", prepareKeyValueMessage(name, value));
}

process.stdout.write(os.EOL);
issueCommand("set-output", { name }, toCommandValue(value));
}

function issueFileCommand(command, message) {
const filePath = process.env[`GITHUB_${command}`];
if (!filePath) {
throw new Error(
`Unable to find environment variable for file command ${command}`
);
}
if (!fs.existsSync(filePath)) {
throw new Error(`Missing file at path: ${filePath}`);
}

fs.appendFileSync(filePath, `${toCommandValue(message)}${os.EOL}`, {
encoding: "utf8",
});
}

module.exports = { getInput, setOutput };
8 changes: 8 additions & 0 deletions .github/actions/bump-version/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const action = require("./action");
const core = require("./core");

action.bumpVersion(
core.getInput("currentVersion"),
core.getInput("bumpType"),
core.getInput("prereleaseSuffix")
);
Comment on lines +3 to +8
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got rid of fs.readFileSynx, fs.writeFileSynx, and doing anything with the newVersion that used to get returned from the action.bumpVersion call. bumpVersion uses core.setOutput and then we use the output in the release.yaml workflow.

3 changes: 3 additions & 0 deletions .github/actions/bump-version/jest.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"verbose": true
}
Loading