Skip to content

Commit

Permalink
Merge pull request #161 from cloudflare/cina/throw-on-failures
Browse files Browse the repository at this point in the history
Refactor error handling to stop execution on errors
  • Loading branch information
1000hz committed Aug 30, 2023
2 parents b076e88 + d7637bf commit 47d4afd
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 167 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-spiders-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler-action": patch
---

Refactored error handling to stop execution when action fails. Previously, the action would continue executing to completion if one of the steps encountered an error. Fixes #160.
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
environment: dev
preCommands: npx wrangler deploy --env dev # https://github.com/cloudflare/wrangler-action/issues/162
secrets: |
SECRET1
SECRET2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ jobs:
- uses: actions/add-to-project@v0.5.0
with:
project-url: https://github.com/orgs/cloudflare/projects/1
github-token: ${{ secrets.GH_ACCESS_TOKEN }}
github-token: ${{ secrets.GH_ACCESS_TOKEN }}
1 change: 0 additions & 1 deletion action-env-setup.ts

This file was deleted.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
"scripts": {
"build": "npx ncc build ./src/index.ts && mv ./dist/index.js ./dist/index.mjs",
"test": "vitest",
"format": "prettier --write . --ignore-path ./dist/**",
"check": "prettier --check . --ignore-path ./dist/**"
"format": "prettier --write .",
"check": "prettier --check ."
},
"dependencies": {
"@actions/core": "^1.10.0"
Expand Down
216 changes: 87 additions & 129 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import {
getBooleanInput,
} from "@actions/core";
import { execSync, exec } from "node:child_process";
import { existsSync } from "node:fs";
import * as path from "node:path";
import { checkWorkingDirectory, getNpxCmd, semverCompare } from "./utils";
import * as util from "node:util";
const execAsync = util.promisify(exec);

Expand All @@ -31,10 +30,6 @@ const config = {
QUIET_MODE: getBooleanInput("quiet"),
} as const;

function getNpxCmd() {
return process.env.RUNNER_OS === "Windows" ? "npx.cmd" : "npx";
}

function info(message: string, bypass?: boolean): void {
if (!config.QUIET_MODE || bypass) {
originalInfo(message);
Expand All @@ -59,34 +54,19 @@ function endGroup(): void {
}
}

/**
* A helper function to compare two semver versions. If the second arg is greater than the first arg, it returns true.
*/
function semverCompare(version1: string, version2: string) {
if (version2 === "latest") return true;

const version1Parts = version1.split(".");
const version2Parts = version2.split(".");

for (const version1Part of version1Parts) {
const version2Part = version2Parts.shift();

if (version1Part !== version2Part && version2Part) {
return version1Part < version2Part ? true : false;
}
}

return false;
}

async function main() {
installWrangler();
authenticationSetup();
await execCommands(getMultilineInput("preCommands"), "pre");
await uploadSecrets();
await wranglerCommands();
await execCommands(getMultilineInput("postCommands"), "post");
info("🏁 Wrangler Action completed", true);
try {
installWrangler();
authenticationSetup();
await execCommands(getMultilineInput("preCommands"), "pre");
await uploadSecrets();
await wranglerCommands();
await execCommands(getMultilineInput("postCommands"), "post");
info("🏁 Wrangler Action completed", true);
} catch (err: unknown) {
err instanceof Error && error(err.message);
setFailed("🚨 Action failed");
}
}

async function runProcess(
Expand All @@ -103,29 +83,14 @@ async function runProcess(
} catch (err: any) {
err.stdout && info(err.stdout.toString());
err.stderr && error(err.stderr.toString(), true);
throw err;
}
}

function checkWorkingDirectory(workingDirectory = ".") {
try {
const normalizedPath = path.normalize(workingDirectory);
if (existsSync(normalizedPath)) {
return normalizedPath;
} else {
setFailed(`🚨 Directory ${workingDirectory} does not exist.`);
}
} catch (error) {
setFailed(
`🚨 While checking/creating directory ${workingDirectory} received ${error}`,
);
throw new Error(`\`${command}\` returned non-zero exit code.`);
}
}

function installWrangler() {
if (config["WRANGLER_VERSION"].startsWith("1")) {
setFailed(
`🚨 Wrangler v1 is no longer supported by this action. Please use major version 2 or greater`,
throw new Error(
`Wrangler v1 is no longer supported by this action. Please use major version 2 or greater`,
);
}
startGroup("📥 Installing Wrangler");
Expand All @@ -145,40 +110,39 @@ async function execCommands(commands: string[], cmdType: string) {
if (!commands.length) {
return;
}
startGroup(`🚀 Running ${cmdType}Commands`);

const arrPromises = commands.map(async (command) => {
const cmd = command.startsWith("wrangler")
? `${getNpxCmd()} ${command}`
: command;
startGroup(`🚀 Running ${cmdType}Commands`);
try {
const arrPromises = commands.map(async (command) => {
const cmd = command.startsWith("wrangler")
? `${getNpxCmd()} ${command}`
: command;

info(`🚀 Executing command: ${cmd}`);
info(`🚀 Executing command: ${cmd}`);

return await runProcess(cmd, {
cwd: config["workingDirectory"],
env: process.env,
return await runProcess(cmd, {
cwd: config["workingDirectory"],
env: process.env,
});
});
});

await Promise.all(arrPromises).catch((result) => {
result.stdout && info(result.stdout.toString());
result.stderr && error(result.stderr.toString(), true);
setFailed(`🚨 ${cmdType}Commands failed`);
});
endGroup();
await Promise.all(arrPromises);
} finally {
endGroup();
}
}

/**
* A helper function to get the secret from the environment variables.
*/
function getSecret(secret: string) {
if (!secret) {
setFailed("No secret provided");
throw new Error("Secret name cannot be blank.");
}

const value = process.env[secret];
if (!value) {
setFailed(`Secret ${secret} not found`);
throw new Error(`Value for secret ${secret} not found.`);
}

return value;
Expand All @@ -189,26 +153,22 @@ async function legacyUploadSecrets(
environment?: string,
workingDirectory?: string,
) {
try {
const arrPromises = secrets
.map((secret) => {
const command = `echo ${getSecret(
secret,
)} | ${getNpxCmd()} wrangler secret put ${secret}`;
return environment ? command.concat(` --env ${environment}`) : command;
})
.map(
async (command) =>
await execAsync(command, {
cwd: workingDirectory,
env: process.env,
}),
);
const arrPromises = secrets
.map((secret) => {
const command = `echo ${getSecret(
secret,
)} | ${getNpxCmd()} wrangler secret put ${secret}`;
return environment ? command.concat(` --env ${environment}`) : command;
})
.map(
async (command) =>
await execAsync(command, {
cwd: workingDirectory,
env: process.env,
}),
);

await Promise.all(arrPromises);
} catch {
setFailed(`🚨 Error uploading secrets`);
}
await Promise.all(arrPromises);
}

async function uploadSecrets() {
Expand All @@ -219,9 +179,10 @@ async function uploadSecrets() {
if (!secrets.length) {
return;
}
try {
startGroup("🔑 Uploading Secrets");

startGroup("🔑 Uploading secrets...");

try {
if (semverCompare(config["WRANGLER_VERSION"], "3.4.0"))
return legacyUploadSecrets(secrets, environment, workingDirectory);

Expand All @@ -244,9 +205,11 @@ async function uploadSecrets() {
env: process.env,
stdio: "ignore",
});

info(`✅ Uploaded secrets`);
} catch {
setFailed(`🚨 Error uploading secrets`);
} catch (err) {
error(`❌ Upload failed`);
throw new Error(`Failed to upload secrets.`);
} finally {
endGroup();
}
Expand All @@ -258,7 +221,7 @@ function getVarArgs() {
if (process.env[envVar] && process.env[envVar]?.length !== 0) {
return `${envVar}:${process.env[envVar]!}`;
} else {
setFailed(`🚨 ${envVar} not found in variables.`);
throw new Error(`Value for var ${envVar} not found in environment.`);
}
});

Expand All @@ -267,55 +230,50 @@ function getVarArgs() {

async function wranglerCommands() {
startGroup("🚀 Running Wrangler Commands");
const commands = config["COMMANDS"];
const environment = config["ENVIRONMENT"];

if (!commands.length) {
const wranglerVersion = config["WRANGLER_VERSION"];
const deployCommand = semverCompare("2.20.0", wranglerVersion)
? "deploy"
: "publish";
commands.push(deployCommand);
}

const arrPromises = commands.map(async (command) => {
if (environment.length > 0 && !command.includes(`--env`)) {
command = command.concat(` --env ${environment}`);
try {
const commands = config["COMMANDS"];
const environment = config["ENVIRONMENT"];

if (!commands.length) {
const wranglerVersion = config["WRANGLER_VERSION"];
const deployCommand = semverCompare("2.20.0", wranglerVersion)
? "deploy"
: "publish";
commands.push(deployCommand);
}

const cmd = `${getNpxCmd()} wrangler ${command} ${
(command.startsWith("deploy") || command.startsWith("publish")) &&
!command.includes(`--var`)
? getVarArgs()
: ""
}`.trim();
const arrPromises = commands.map(async (command) => {
if (environment.length > 0 && !command.includes(`--env`)) {
command = command.concat(` --env ${environment}`);
}

info(`🚀 Executing command: ${cmd}`);
const cmd = `${getNpxCmd()} wrangler ${command} ${
(command.startsWith("deploy") || command.startsWith("publish")) &&
!command.includes(`--var`)
? getVarArgs()
: ""
}`.trim();

return await runProcess(cmd, {
cwd: config["workingDirectory"],
env: process.env,
});
});
info(`🚀 Executing command: ${cmd}`);

await Promise.all(arrPromises).catch((result) => {
result.stdout && info(result.stdout.toString());
result.stderr && error(result.stderr.toString());
setFailed(`🚨 Command failed`);
});
return await runProcess(cmd, {
cwd: config["workingDirectory"],
env: process.env,
});
});

endGroup();
await Promise.all(arrPromises);
} finally {
endGroup();
}
}

main().catch(() => setFailed("🚨 Action failed"));
main();

export {
wranglerCommands,
execCommands,
uploadSecrets,
authenticationSetup,
installWrangler,
checkWorkingDirectory,
getNpxCmd,
semverCompare,
};
Loading

0 comments on commit 47d4afd

Please sign in to comment.