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

feat: tag canaries for cocoapods plugin #1702

Merged
merged 10 commits into from
Jan 11, 2021
37 changes: 37 additions & 0 deletions plugins/cocoapods/__tests__/cocoapods.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ describe("Cocoapods Plugin", () => {

expect(getVersion("./Test.podspec")).toBe("0.0.1");
});
test("should return canary version", () => {
mockPodspec(specWithVersion("0.0.1-canary.1.0.0"));

expect(getVersion("./Test.podspec")).toBe("0.0.1-canary.1.0.0");
});
});
describe("updatePodspecVersion", () => {
test("should throw error if there is an error writing file", async () => {
Expand Down Expand Up @@ -235,6 +240,38 @@ describe("Cocoapods Plugin", () => {
});
});

describe("canary hook", () => {
test("should tag with canary version", async () => {
mockPodspec(specWithVersion("0.0.1"));

const plugin = new CocoapodsPlugin(options);
const hook = makeHooks();
plugin.apply(({
hooks: hook,
logger: dummyLog(),
prefixRelease,
git: {
getLatestRelease: async () => "0.0.1",
},
getCurrentVersion: async () => "0.0.1",
} as unknown) as Auto.Auto);

const newVersion = await hook.canary.promise({
bump: "minor" as Auto.SEMVER,
canaryIdentifier: "1.1.1",
});

expect(newVersion).toBe("0.1.0-canary.1.1.1");
expect(exec).toBeCalledTimes(3);
expect(exec).toHaveBeenCalledWith("git", [
"tag",
"0.1.0-canary.1.1.1",
"-m",
"Update version to 0.1.0-canary.1.1.1",
]);
});
});

describe("publish hook", () => {
test("should push to trunk if no specsRepo in options", async () => {
mockPodspec(specWithVersion("0.0.1"));
Expand Down
232 changes: 141 additions & 91 deletions plugins/cocoapods/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import {
Auto,
IPlugin,
execPromise,
getCurrentBranch,
validatePluginConfiguration,
ILogger,
} from "@auto-it/core";

import { inc, ReleaseType } from "semver";
Expand All @@ -14,7 +16,7 @@ import { getPodspecContents, writePodspecContents } from "./utilities";
const logPrefix = "[Cocoapods-Plugin]";

/** Regex used to pull the version line from the spec */
const versionRegex = /\.version\s*=\s*['|"](?<version>\d+\.\d+\.\d+)['|"]/;
const versionRegex = /\.version\s*=\s*['|"](?<version>\d+\.\d+\.\d+.*?)['|"]/;
/**
* Wrapper to add logPrefix to messages
*
Expand Down Expand Up @@ -113,6 +115,9 @@ export default class CocoapodsPlugin implements IPlugin {
/** The name of the plugin */
name = "cocoapods";

/** The auto logger */
logger?: ILogger;

/** The options of the plugin */
readonly options: ICocoapodsPluginOptions;

Expand All @@ -123,6 +128,7 @@ export default class CocoapodsPlugin implements IPlugin {

/** Tap into auto plugin points. */
apply(auto: Auto) {
this.logger = auto.logger;
const isQuiet = auto.logger.logLevel === "quiet";
const isVerbose =
auto.logger.logLevel === "verbose" ||
Expand All @@ -144,34 +150,73 @@ export default class CocoapodsPlugin implements IPlugin {
auto.prefixRelease(getVersion(this.options.podspecPath))
);

auto.hooks.version.tapPromise(this.name, async ({ bump, dryRun, quiet }) => {
const previousVersion = getVersion(this.options.podspecPath);
const releaseVersion = inc(previousVersion, bump as ReleaseType);
auto.hooks.version.tapPromise(
this.name,
async ({ bump, dryRun, quiet }) => {
const previousVersion = getVersion(this.options.podspecPath);
const releaseVersion = inc(previousVersion, bump as ReleaseType);

if (dryRun && releaseVersion) {
if (quiet) {
console.log(releaseVersion);
} else {
auto.logger.log.info(`Would have published: ${releaseVersion}`);
}

if (dryRun && releaseVersion) {
if (quiet) {
console.log(releaseVersion);
} else {
auto.logger.log.info(`Would have published: ${releaseVersion}`);
return;
}

return;
}
if (!releaseVersion) {
throw new Error(
`Could not increment previous version: ${previousVersion}`
);
}

if (!releaseVersion) {
throw new Error(
`Could not increment previous version: ${previousVersion}`
);
await updatePodspecVersion(this.options.podspecPath, releaseVersion);
await execPromise("git", [
"tag",
releaseVersion,
"-m",
`"Update version to ${releaseVersion}"`,
]);
}
);

await updatePodspecVersion(this.options.podspecPath, releaseVersion);
await execPromise("git", [
"tag",
releaseVersion,
"-m",
`"Update version to ${releaseVersion}"`,
]);
});
auto.hooks.canary.tapPromise(
this.name,
async ({ bump, canaryIdentifier, dryRun, quiet }) => {
if (!auto.git) {
return;
}

const lastRelease = await auto.git.getLatestRelease();
const current = await auto.getCurrentVersion(lastRelease);
hborawski marked this conversation as resolved.
Show resolved Hide resolved
const nextVersion = inc(current, bump as ReleaseType);
const canaryVersion = `${nextVersion}-canary.${canaryIdentifier}`;
const branch = getCurrentBranch() || "";

if (dryRun) {
if (quiet) {
console.log(canaryVersion);
} else {
auto.logger.log.info(`Would have published: ${canaryVersion}`);
}

return;
}

await execPromise("git", [
"tag",
canaryVersion,
"-m",
`Update version to ${canaryVersion}`,
]);
await execPromise("git", ["push", auto.remote, branch, "--tags"]);

await this.publishPodSpec(podLogLevel);
return canaryVersion;
}
);

auto.hooks.beforeShipIt.tapPromise(this.name, async ({ dryRun }) => {
if (dryRun) {
Expand All @@ -190,82 +235,43 @@ export default class CocoapodsPlugin implements IPlugin {
});

auto.hooks.publish.tapPromise(this.name, async () => {
const [pod, ...commands] = this.options.podCommand?.split(" ") || ["pod"];

await execPromise("git", [
"push",
"--follow-tags",
"--set-upstream",
auto.remote,
auto.baseBranch,
]);
await this.publishPodSpec(podLogLevel);
});
}

if (!this.options.specsRepo) {
auto.logger.log.info(logMessage(`Pushing to Cocoapods trunk`));
await execPromise(pod, [
...commands,
"trunk",
"push",
...(this.options.flags || []),
this.options.podspecPath,
...podLogLevel,
]);
return;
}

try {
const existingRepos = await execPromise(pod, [
...commands,
"repo",
"list",
]);
if (existingRepos.indexOf("autoPublishRepo") !== -1) {
auto.logger.log.info("Removing existing autoPublishRepo");
await execPromise(pod, [
...commands,
"repo",
"remove",
"autoPublishRepo",
...podLogLevel,
]);
}
} catch (error) {
auto.logger.log.warn(
`Error Checking for existing Specs repositories: ${error}`
);
}

try {
await execPromise(pod, [
...commands,
"repo",
"add",
"autoPublishRepo",
this.options.specsRepo,
...podLogLevel,
]);

auto.logger.log.info(
logMessage(`Pushing to specs repo: ${this.options.specsRepo}`)
);
/**
*
*/
async publishPodSpec(podLogLevel: string[]) {
const [pod, ...commands] = this.options.podCommand?.split(" ") || ["pod"];
if (!this.options.specsRepo) {
this.logger?.log.info(logMessage(`Pushing to Cocoapods trunk`));
await execPromise(pod, [
...commands,
"trunk",
"push",
...(this.options.flags || []),
this.options.podspecPath,
...podLogLevel,
]);
return;
}

await execPromise(pod, [
...commands,
"repo",
"push",
...(this.options.flags || []),
"autoPublishRepo",
this.options.podspecPath,
...podLogLevel,
]);
} catch (error) {
auto.logger.log.error(
logMessage(
`Error pushing to specs repo: ${this.options.specsRepo}. Error: ${error}`
)
);
process.exit(1);
} finally {
try {
const existingRepos = await execPromise(pod, [
...commands,
"repo",
"list",
]);
if (existingRepos.indexOf("autoPublishRepo") !== -1) {
this.logger?.log.info("Removing existing autoPublishRepo");
await execPromise(pod, [
...commands,
"repo",
Expand All @@ -274,6 +280,50 @@ export default class CocoapodsPlugin implements IPlugin {
...podLogLevel,
]);
}
});
} catch (error) {
this.logger?.log.warn(
`Error Checking for existing Specs repositories: ${error}`
);
}

try {
await execPromise(pod, [
...commands,
"repo",
"add",
"autoPublishRepo",
this.options.specsRepo,
...podLogLevel,
]);

this.logger?.log.info(
logMessage(`Pushing to specs repo: ${this.options.specsRepo}`)
);

await execPromise(pod, [
...commands,
"repo",
"push",
...(this.options.flags || []),
"autoPublishRepo",
this.options.podspecPath,
...podLogLevel,
]);
} catch (error) {
this.logger?.log.error(
logMessage(
`Error pushing to specs repo: ${this.options.specsRepo}. Error: ${error}`
)
);
process.exit(1);
} finally {
await execPromise(pod, [
...commands,
"repo",
"remove",
"autoPublishRepo",
...podLogLevel,
]);
}
}
}