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): Use existing wrangler installation when appropriate #235

Merged
merged 10 commits into from
May 15, 2024
5 changes: 5 additions & 0 deletions .changeset/tiny-planes-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler-action": minor
---

wrangler-action will now re-use existing wrangler installations when available
43 changes: 23 additions & 20 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Only build app
uses: ./
with:
workingDirectory: "./test/base"
workingDirectory: "./test/only-build"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --dry-run
Expand All @@ -38,12 +38,11 @@ jobs:
uses: ./
with:
quiet: true
workingDirectory: "./test/base"
workingDirectory: "./test/build-quiet"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --dry-run

# START Setup and teardown of Worker Environment Tests
- name: Environment support
uses: ./
with:
Expand All @@ -52,28 +51,20 @@ jobs:
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
environment: dev
preCommands: npx wrangler deploy --env dev # https://github.com/cloudflare/wrangler-action/issues/162
postCommands: npx wrangler delete --name wrangler-action-dev-environment-test --force
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm. I think this is OK. But what happens if this step fails?
We should probably implement a cleanup job that runs on a schedule similar to workers-sdk e2e test cleanup...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that sounds like something we should add. Do you want me to do it in this PR? If not I'm happy to make another PR after this one to add it in.

secrets: |
SECRET1
SECRET2
env:
SECRET1: ${{ secrets.SECRET1 }}
SECRET2: ${{ secrets.SECRET2 }}

- name: Clean up Deployed Environment Worker
uses: ./
with:
workingDirectory: "./test/base"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: delete --name wrangler-action-dev-environment-test --force
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this actually a test we want to do? i.e. run the delete command?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a great question. We actually do have a delete command below when cleaing up the secret test workers. I figured this change along with another one down below would give us the chance to test out postCommands. Since there wasn't a previous use of it in this script.


# END Setup and teardown of Worker Environment Tests
# START Setup and teardown of Workers w/ Secrets Tests
- name: Deploy app secrets w/ hardcoded Wrangler v2
uses: ./
with:
wranglerVersion: "2.20.0"
workingDirectory: "./test/base"
workingDirectory: "./test/secrets-v2"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
secrets: |
Expand All @@ -84,13 +75,13 @@ jobs:
SECRET2: ${{ secrets.SECRET2 }}

- name: Health Check Deployed Worker
run: node .github/workflows/workerHealthCheck.cjs
run: node .github/workflows/workerHealthCheck.cjs wrangler-action-test-secrets-v2
shell: bash

- name: Deploy app secrets w/ default version
uses: ./
with:
workingDirectory: "./test/base"
workingDirectory: "./test/secrets-default"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
secrets: |
Expand All @@ -101,22 +92,23 @@ jobs:
SECRET2: ${{ secrets.SECRET2 }}

- name: Health Check Deployed Worker
run: node .github/workflows/workerHealthCheck.cjs
run: node .github/workflows/workerHealthCheck.cjs wrangler-action-test-secrets-default
shell: bash

- name: Clean Up Deployed Workers
uses: ./
with:
workingDirectory: "./test/base"
workingDirectory: "./test/secrets-default"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: delete --name wrangler-action-test --force
command: delete --name wrangler-action-test-secrets-v2 --force
postCommands: npx wrangler delete --name wrangler-action-test-secrets-default --force
# END Setup and teardown of Workers w/ Secrets Tests

- name: Support packageManager variable
uses: ./
with:
workingDirectory: "./test/empty"
workingDirectory: "./test/specify-package-manager"
packageManager: "npm"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
Expand All @@ -125,7 +117,7 @@ jobs:
- name: Support unspecified packageManager with no lockfile
uses: ./
with:
workingDirectory: "./test/empty"
workingDirectory: "./test/unspecified-package-manager"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --dry-run
Expand Down Expand Up @@ -159,3 +151,14 @@ jobs:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --dry-run

- name: Change directory to pre-installed-wrangler and install dependencies
run: |
cd ./test/pre-installed-wrangler
npm install

- name: Support pre-installed wrangler
uses: ./
with:
workingDirectory: "./test/pre-installed-wrangler"
command: action-test
16 changes: 12 additions & 4 deletions .github/workflows/workerHealthCheck.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const { execSync } = require("child_process");

function workerHealthCheck() {
const url =
"https://wrangler-action-test.devprod-testing7928.workers.dev/secret-health-check";
function workerHealthCheck(workerName) {
const url = `https://${workerName}.devprod-testing7928.workers.dev/secret-health-check`;

const buffer = execSync(`curl ${url}`);

Expand All @@ -17,4 +16,13 @@ function workerHealthCheck() {
return response;
}

workerHealthCheck();
const args = Array.from(process.argv);
const workerName = args.pop();

if (!workerName) {
throw new Error(
"Please provide the worker name as an argument when calling this program.",
);
}

workerHealthCheck(workerName);
61 changes: 61 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
setFailed,
setOutput,
} from "@actions/core";
import { getExecOutput } from "@actions/exec";
import semverEq from "semver/functions/eq";
import { exec, execShell } from "./exec";
import { checkWorkingDirectory, semverCompare } from "./utils";
import { getPackageManager } from "./packageManagers";
Expand All @@ -21,6 +23,7 @@ const DEFAULT_WRANGLER_VERSION = "3.13.2";
*/
const config = {
WRANGLER_VERSION: getInput("wranglerVersion") || DEFAULT_WRANGLER_VERSION,
didUserProvideWranglerVersion: Boolean(getInput("wranglerVersion")),
secrets: getMultilineInput("secrets"),
workingDirectory: checkWorkingDirectory(getInput("workingDirectory")),
CLOUDFLARE_API_TOKEN: getInput("apiToken"),
Expand Down Expand Up @@ -82,6 +85,64 @@ async function installWrangler() {
);
}

startGroup("🔍 Checking for existing Wrangler installation");
let installedVersion = "";
let installedVersionSatisfiesRequirement = false;
try {
const { stdout } = await getExecOutput(
packageManager.exec,
["wrangler", "--version"],
{
cwd: config["workingDirectory"],
silent: config.QUIET_MODE,
},
);
// There are two possible outputs from `wrangler --version`:
// ` ⛅️ wrangler 3.48.0 (update available 3.53.1)`
// and
// `3.48.0`
const versionMatch =
stdout.match(/wrangler (\d+\.\d+\.\d+)/) ??
stdout.match(/^(\d+\.\d+\.\d+)/);
if (versionMatch) {
installedVersion = versionMatch[1];
}
if (config.didUserProvideWranglerVersion) {
installedVersionSatisfiesRequirement = semverEq(
installedVersion,
config["WRANGLER_VERSION"],
);
}
if (!config.didUserProvideWranglerVersion && installedVersion) {
info(
`✅ No wrangler version specified, using pre-installed wrangler version ${installedVersion}`,
true,
);
endGroup();
return;
}
if (
config.didUserProvideWranglerVersion &&
installedVersionSatisfiesRequirement
) {
info(`✅ Using Wrangler ${installedVersion}`, true);
endGroup();
return;
}
info(
"⚠️ Wrangler not found or version is incompatible. Installing...",
true,
);
} catch (error) {
debug(`Error checking Wrangler version: ${error}`);
info(
"⚠️ Wrangler not found or version is incompatible. Installing...",
true,
);
} finally {
endGroup();
}

startGroup("📥 Installing Wrangler");
try {
await exec(
Expand Down
1 change: 0 additions & 1 deletion test/base/index.ts → test/build-quiet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default {
return new Response("OK");
}

// @ts-expect-error
return Response.json({
...request,
headers: Object.fromEntries(request.headers),
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions test/build-quiet/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name = "wrangler-action-test-build-quiet"
main = "./index.ts"
compatibility_date = "2023-07-07"
workers_dev = true
1 change: 0 additions & 1 deletion test/bun/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default {
return new Response("OK");
}

// @ts-expect-error
return Response.json({
...request,
headers: Object.fromEntries(request.headers),
Expand Down
1 change: 0 additions & 1 deletion test/environment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default {
return new Response(`${SECRET1} ${SECRET2}`);
}

// @ts-expect-error
return Response.json({
...request,
headers: Object.fromEntries(request.headers),
Expand Down
1 change: 0 additions & 1 deletion test/npm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default {
return new Response("OK");
}

// @ts-expect-error
return Response.json({
...request,
headers: Object.fromEntries(request.headers),
Expand Down
25 changes: 25 additions & 0 deletions test/only-build/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
type Env = {
SECRET1?: string;
SECRET2?: string;
};

export default {
fetch(request: Request, env: Env) {
const url = new URL(request.url);

if (url.pathname === "/secret-health-check") {
const { SECRET1, SECRET2 } = env;

if (SECRET1 !== "SECRET_1_VALUE" || SECRET2 !== "SECRET_2_VALUE") {
throw new Error("SECRET1 or SECRET2 is not defined");
}

return new Response("OK");
}

return Response.json({
...request,
headers: Object.fromEntries(request.headers),
});
},
};
10 changes: 10 additions & 0 deletions test/only-build/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions test/only-build/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "wrangler-action-test",
"license": "MIT",
"private": true
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name = "wrangler-action-test"
name = "wrangler-action-test-only-build"
main = "./index.ts"
compatibility_date = "2023-07-07"
workers_dev = true
1 change: 0 additions & 1 deletion test/pnpm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default {
return new Response("OK");
}

// @ts-expect-error
return Response.json({
...request,
headers: Object.fromEntries(request.headers),
Expand Down
25 changes: 25 additions & 0 deletions test/pre-installed-wrangler/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
type Env = {
SECRET1?: string;
SECRET2?: string;
};

export default {
fetch(request: Request, env: Env) {
const url = new URL(request.url);

if (url.pathname === "/secret-health-check") {
const { SECRET1, SECRET2 } = env;

if (SECRET1 !== "SECRET_1_VALUE" || SECRET2 !== "SECRET_2_VALUE") {
throw new Error("SECRET1 or SECRET2 is not defined");
}

return new Response("OK");
}

return Response.json({
...request,
headers: Object.fromEntries(request.headers),
});
},
};
18 changes: 18 additions & 0 deletions test/pre-installed-wrangler/mock_packages/wrangler/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env node
"use strict";

const args = Array.from(process.argv);
const command = args.pop();
switch (command) {
case "--version":
console.log(`
⛅️ wrangler 1.1.1 (update available 1.2.3)
------------------------------------------`);
process.exit(0);
case "action-test":
console.log("Test successful.");
process.exit(0);
default:
console.error("Invalid command");
process.exit(1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"private": true,
"name": "wrangler",
"version": "1.1.1",
"main": "index.js",
"bin": "index.js"
}
Loading
Loading