Compare commits
157 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ce4fd508df | |||
| 3c6e4da7b3 | |||
| 1c0eef186f | |||
| b19342b08c | |||
| d44c80928a | |||
| cada7a6312 | |||
| 1e92eee7d2 | |||
| e7e5400334 | |||
| d58f116d72 | |||
| 64b6339110 | |||
| ac2fd0ec8f | |||
| 0140ffbc93 | |||
| cc4ede3f06 | |||
| 9bf87caf2b | |||
| 81f8814855 | |||
| 6c6d3321ef | |||
| bc61e66e47 | |||
| 0e2b86ba21 | |||
| 59c0462940 | |||
| 4c3f0c27ea | |||
| 4d045615a9 | |||
| a7a2388d7b | |||
| 95555f6ed0 | |||
| 2171bbdd69 | |||
| 4f4ff59d17 | |||
| 122ee5cf5b | |||
| 44d79edf44 | |||
| b2be7abbfc | |||
| b7158dc9a4 | |||
| 43767e73de | |||
| 10d5b9c1c1 | |||
| c01035706f | |||
| fa96c39bd4 | |||
| 78dad1df07 | |||
| 3ec7f8943e | |||
| cd8a317efb | |||
| 6aa2e8946a | |||
| de0526e09b | |||
| 84316ca95c | |||
| 134b5c2a32 | |||
| 47d51f25c1 | |||
| 93fff4f656 | |||
| 66334dff0a | |||
| 9966912c1b | |||
| 7b9aec5185 | |||
| c0e117f512 | |||
| bcff5386ec | |||
| c15498da36 | |||
| 8bc5c5f050 | |||
| ac21b71592 | |||
| f111269956 | |||
| 570d521df6 | |||
| 174337b3b4 | |||
| a1467a0c8f | |||
| 3ea6e3f132 | |||
| ea11499226 | |||
| 8f2f89521c | |||
| 66efca2cbb | |||
| aa5d18dd1e | |||
| b84268f0e0 | |||
| d1b97ebf4d | |||
| baf8bc61f1 | |||
| 8edd152f63 | |||
| 2d275a8f2d | |||
| 8ef515f899 | |||
| 9b27cf271c | |||
| 405a82610b | |||
| 0545ad285a | |||
| ea5754c9ad | |||
| 983b6349c2 | |||
| b05934f581 | |||
| 31a6263ef3 | |||
| 88906781f0 | |||
| ebef541795 | |||
| 9d4ca0f255 | |||
| 1be73b90f6 | |||
| 180648017b | |||
| 9003b06015 | |||
| fd98a7c990 | |||
| 4bf3047bb8 | |||
| f2c22accd3 | |||
| 0c36639f72 | |||
| d5a1abb013 | |||
| c214b69bae | |||
| bac2829d42 | |||
| 78c994fb95 | |||
| e3434a7e98 | |||
| 08514fdece | |||
| 7451182d38 | |||
| 522c117b7d | |||
| b92719544e | |||
| bbedd8e54f | |||
| ebaf896045 | |||
| 7e684fbad9 | |||
| 2521ec00cc | |||
| ba0f485178 | |||
| 2de0b3dfd8 | |||
| f2d9b652c4 | |||
| 0e62acaf21 | |||
| bd3857047e | |||
| d13856dfc9 | |||
| f88aee4953 | |||
| a5f361f3f0 | |||
| 9aba9c34da | |||
| 9dd38ad790 | |||
| 1599928d8e | |||
| 0fff39f4b7 | |||
| ca0bf5eeba | |||
| 97c920b38e | |||
| 11fa60953d | |||
| 5ee7b681bc | |||
| 74a612d924 | |||
| 0558fc8c04 | |||
| 976ec4d78c | |||
| a8845f6d95 | |||
| 8d6fade5ad | |||
| 65996a5230 | |||
| 2b7ed1316d | |||
| 9554b3575b | |||
| 57159ca2ed | |||
| 7dd5c3621b | |||
| 581e17bc51 | |||
| 21a8414ba3 | |||
| 819ea006e6 | |||
| 473d9cbd29 | |||
| 76d614f400 | |||
| d647227bbc | |||
| 533097350a | |||
| bc7253f187 | |||
| b2e459a047 | |||
| 96c3774b77 | |||
| b00f94ea6f | |||
| c649733249 | |||
| d43f9c81c7 | |||
| 219a0887d7 | |||
| 25b114f472 | |||
| f40a9f5f82 | |||
| bd06b290b1 | |||
| a4509d507c | |||
| 0e6f0d3080 | |||
| 326ba30882 | |||
| 032a7248fa | |||
| 080373bdb6 | |||
| 231d787db1 | |||
| d9a0a00f8b | |||
| 779191a652 | |||
| 556068fb59 | |||
| caa59485d0 | |||
| c2494c1ca6 | |||
| 528687aaf4 | |||
| bd50d10af9 | |||
| 2513ffc6cc | |||
| 9df50d42e4 | |||
| 4611c14c05 | |||
| ac3f259fcf | |||
| b2645622e9 | |||
| f4e6269765 |
@@ -1,7 +1,7 @@
|
||||
# Changesets
|
||||
|
||||
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
||||
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
||||
with multi-package repos, or single-package repos to help you version and deploy your code. You can
|
||||
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
||||
|
||||
We have a quick list of common questions to get you started engaging with this project in
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"wrangler-action": minor
|
||||
---
|
||||
|
||||
Add GitHub deployments and job summaries for parity with pages-action
|
||||
@@ -14,7 +14,8 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "latest"
|
||||
# Pinned due to compatibility issues on 23.2.0
|
||||
node-version: "22"
|
||||
cache: "npm"
|
||||
|
||||
- name: Install modules and build
|
||||
@@ -29,7 +30,7 @@ jobs:
|
||||
- name: Only build app
|
||||
uses: ./
|
||||
with:
|
||||
workingDirectory: "./test/base"
|
||||
workingDirectory: "./src/test/fixtures/only-build"
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy --dry-run
|
||||
@@ -38,20 +39,20 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
quiet: true
|
||||
workingDirectory: "./test/base"
|
||||
workingDirectory: "./src/test/fixtures/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:
|
||||
workingDirectory: "./test/environment"
|
||||
workingDirectory: "./src/test/fixtures/environment"
|
||||
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
|
||||
postCommands: npx wrangler delete --name wrangler-action-dev-environment-test --force
|
||||
secrets: |
|
||||
SECRET1
|
||||
SECRET2
|
||||
@@ -59,21 +60,12 @@ jobs:
|
||||
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
|
||||
|
||||
# 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: "./src/test/fixtures/secrets-v2"
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
secrets: |
|
||||
@@ -84,13 +76,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: "./src/test/fixtures/secrets-default"
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
secrets: |
|
||||
@@ -101,31 +93,40 @@ 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: "./src/test/fixtures/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: "./src/test/fixtures/specify-package-manager"
|
||||
packageManager: "npm"
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy --dry-run
|
||||
|
||||
- name: Support unspecified packageManager with no lockfile
|
||||
uses: ./
|
||||
with:
|
||||
workingDirectory: "./src/test/fixtures/unspecified-package-manager"
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy --dry-run
|
||||
|
||||
- name: Support npm package manager
|
||||
uses: ./
|
||||
with:
|
||||
workingDirectory: "./test/npm"
|
||||
workingDirectory: "./src/test/fixtures/npm"
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy --dry-run
|
||||
@@ -136,7 +137,7 @@ jobs:
|
||||
- name: Support yarn package manager
|
||||
uses: ./
|
||||
with:
|
||||
workingDirectory: "./test/yarn"
|
||||
workingDirectory: "./src/test/fixtures/yarn"
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy --dry-run
|
||||
@@ -147,7 +148,18 @@ jobs:
|
||||
- name: Support pnpm package manager
|
||||
uses: ./
|
||||
with:
|
||||
workingDirectory: "./test/pnpm"
|
||||
workingDirectory: "./src/test/fixtures/pnpm"
|
||||
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 ./src/test/fixtures/pre-installed-wrangler
|
||||
npm install
|
||||
|
||||
- name: Support pre-installed wrangler
|
||||
uses: ./
|
||||
with:
|
||||
workingDirectory: "./src/test/fixtures/pre-installed-wrangler"
|
||||
command: action-test
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
name: Add issues to workers-sdk GH project
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
|
||||
jobs:
|
||||
add-to-project:
|
||||
name: Add issue to project
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/add-to-project@v0.5.0
|
||||
with:
|
||||
project-url: https://github.com/orgs/cloudflare/projects/1
|
||||
github-token: ${{ secrets.GH_ACCESS_TOKEN }}
|
||||
@@ -20,11 +20,15 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "latest"
|
||||
# Pinned due to compatibility issues on 23.2.0
|
||||
node-version: "22"
|
||||
cache: "npm"
|
||||
|
||||
- name: Install modules
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
on:
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
name: Semgrep config
|
||||
jobs:
|
||||
semgrep:
|
||||
name: semgrep/ci
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
SEMGREP_URL: https://cloudflare.semgrep.dev
|
||||
SEMGREP_APP_URL: https://cloudflare.semgrep.dev
|
||||
SEMGREP_VERSION_CHECK_URL: https://cloudflare.semgrep.dev/api/check-version
|
||||
container:
|
||||
image: semgrep/semgrep
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: semgrep ci
|
||||
@@ -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}`);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
dist
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
|
||||
+124
@@ -1,5 +1,129 @@
|
||||
# Changelog
|
||||
|
||||
## 3.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#319](https://github.com/cloudflare/wrangler-action/pull/319) [`59c04629408d58978884fadd18755f1a15f96157`](https://github.com/cloudflare/wrangler-action/commit/59c04629408d58978884fadd18755f1a15f96157) Thanks [@Maximo-Guk](https://github.com/Maximo-Guk)! - Fixes #317: Generate a new output directory with a randomUUID in the tmpDir, so that when the action is executed multiple times, we use the artifacts from that run, opposed to the artifacts from a previous run.
|
||||
|
||||
## 3.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#312](https://github.com/cloudflare/wrangler-action/pull/312) [`122ee5cf5b66847e0b6cfa67ecd9e03e38a67a42`](https://github.com/cloudflare/wrangler-action/commit/122ee5cf5b66847e0b6cfa67ecd9e03e38a67a42) Thanks [@Maximo-Guk](https://github.com/Maximo-Guk)! - This reapplies [303](https://github.com/cloudflare/wrangler-action/pull/303) add parity with pages-action for pages deploy outputs. Thanks @courtney-sims! - Support pages-deployment-id, pages-environment, pages-deployment-alias-url and deployment-url outputs for Pages deploys when wrangler version is >=3.81.0. deployment-alias-url was also deprecated in favour of pages-deployment-alias.
|
||||
|
||||
## 3.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#309](https://github.com/cloudflare/wrangler-action/pull/309) [`10d5b9c1c1826adaec0a9ee49fdf5b91113508ef`](https://github.com/cloudflare/wrangler-action/commit/10d5b9c1c1826adaec0a9ee49fdf5b91113508ef) Thanks [@Maximo-Guk](https://github.com/Maximo-Guk)! - Revert "Add parity with pages-action for pages deploy outputs"
|
||||
|
||||
## 3.10.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#303](https://github.com/cloudflare/wrangler-action/pull/303) [`3ec7f8943ef83351f743cfaa8763a9056ef70993`](https://github.com/cloudflare/wrangler-action/commit/3ec7f8943ef83351f743cfaa8763a9056ef70993) Thanks [@courtney-sims](https://github.com/courtney-sims)! - Support id, environment, url, and alias outputs for Pages deploys.
|
||||
|
||||
## 3.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#298](https://github.com/cloudflare/wrangler-action/pull/298) [`134b5c2a3252d66b8c4d1cddd0b9baaeed6a4daa`](https://github.com/cloudflare/wrangler-action/commit/134b5c2a3252d66b8c4d1cddd0b9baaeed6a4daa) Thanks [@Maximo-Guk](https://github.com/Maximo-Guk)! - Update wrangler version from 3.13.2 to 3.78.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#278](https://github.com/cloudflare/wrangler-action/pull/278) [`47d51f25c113ee9205110728599b43ed6a1e273b`](https://github.com/cloudflare/wrangler-action/commit/47d51f25c113ee9205110728599b43ed6a1e273b) Thanks [@acusti](https://github.com/acusti)! - fix: Detect existing wrangler install even when wrangler version output is multiline
|
||||
|
||||
## 3.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#291](https://github.com/cloudflare/wrangler-action/pull/291) [`a1467a0c8f2a058f8d43a4d0c40a55176ed5efe6`](https://github.com/cloudflare/wrangler-action/commit/a1467a0c8f2a058f8d43a4d0c40a55176ed5efe6) Thanks [@Ambroos](https://github.com/Ambroos)! - Adds `deployment-alias-url` output for Pages deployment aliases (since Wrangler v3.78.0): https://github.com/cloudflare/workers-sdk/pull/6643
|
||||
|
||||
## 3.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#271](https://github.com/cloudflare/wrangler-action/pull/271) [`66efca2cbb82a5a49df6af2e14c4b58d53b0e266`](https://github.com/cloudflare/wrangler-action/commit/66efca2cbb82a5a49df6af2e14c4b58d53b0e266) Thanks [@Maximo-Guk](https://github.com/Maximo-Guk)! - This unreverts #235 ensuring wrangler-action will re-use existing wrangler installations, thanks @AdiRishi! and ensures we don't automatically install wrangler when checking if it present
|
||||
|
||||
## 3.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#265](https://github.com/cloudflare/wrangler-action/pull/265) [`2d275a8f2d279dc91912c1ff8023af109ef3280c`](https://github.com/cloudflare/wrangler-action/commit/2d275a8f2d279dc91912c1ff8023af109ef3280c) Thanks [@Maximo-Guk](https://github.com/Maximo-Guk)! - Reverts #235 which may have caused the latest version of wrangler to be installed, if no wrangler version was found
|
||||
|
||||
## 3.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#235](https://github.com/cloudflare/wrangler-action/pull/235) [`0545ad285acaff2b92053d636ee17fb303b4c5f5`](https://github.com/cloudflare/wrangler-action/commit/0545ad285acaff2b92053d636ee17fb303b4c5f5) Thanks [@AdiRishi](https://github.com/AdiRishi)! - wrangler-action will now re-use existing wrangler installations when available
|
||||
|
||||
## 3.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#255](https://github.com/cloudflare/wrangler-action/pull/255) [`31a6263ef3ec73ff2d03cb4c0260379f96f7598c`](https://github.com/cloudflare/wrangler-action/commit/31a6263ef3ec73ff2d03cb4c0260379f96f7598c) Thanks [@matthewdavidrodgers](https://github.com/matthewdavidrodgers)! - Stop racing secret uploads
|
||||
|
||||
For up to date versions of wrangler, secrets are uploaded via the 'secret:bulk' command, which batches updates in a single API call.
|
||||
|
||||
For versions of wrangler without that capability, the action falls back to the single 'secret put' command for each secret. It races all these with a Promise.all()
|
||||
|
||||
Unfortunately, the single secret API cannot handle concurrency - at best, these calls have to wait on one another, holding requests open all the while. Often it times out and errors.
|
||||
|
||||
This fixes the legacy secret upload errors by making these calls serially instead of concurrently.
|
||||
|
||||
## 3.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#227](https://github.com/cloudflare/wrangler-action/pull/227) [`bbedd8e54f256d36f81f81f1f05b90937d533bb7`](https://github.com/cloudflare/wrangler-action/commit/bbedd8e54f256d36f81f81f1f05b90937d533bb7) Thanks [@AdiRishi](https://github.com/AdiRishi)! - Surface inner exception when secret:bulk upload command fails
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#213](https://github.com/cloudflare/wrangler-action/pull/213) [`d13856dfc92816473ebf47f66e263a2668a97896`](https://github.com/cloudflare/wrangler-action/commit/d13856dfc92816473ebf47f66e263a2668a97896) Thanks [@GrantBirki](https://github.com/GrantBirki)! - This change introduces three new GitHub Actions output variables. These variables are as follows:
|
||||
|
||||
- `command-output` - contains the string results of `stdout`
|
||||
- `command-stderr` - contains the string results of `stderr`
|
||||
- `deployment-url` - contains the string results of the URL that was deployed (ex: `https://<your_pages_site>.pages.dev`)
|
||||
|
||||
These output variables are intended to be used by more advanced workflows that require the output results or deployment url from Wrangler commands in subsequent workflow steps.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#216](https://github.com/cloudflare/wrangler-action/pull/216) [`9aba9c34daabca23a88191a5fe1b81fa721c1f11`](https://github.com/cloudflare/wrangler-action/commit/9aba9c34daabca23a88191a5fe1b81fa721c1f11) Thanks [@Cherry](https://github.com/Cherry)! - Fixes issues with semver comparison, where version parts were treated lexicographically instead of numerically.
|
||||
|
||||
Bulk secret uploading was introduced in wrangler `3.4.0`, and this action tries to check if the version used is greater than `3.4.0`, and then if so, using the new bulk secret API which is faster. Due to a bug in the semver comparison, `3.19.0` was being considered less than `3.4.0`, and then using an older and slower method for uploading secrets.
|
||||
|
||||
Now the semver comparison is fixed, the faster bulk method is used for uploading secrets when available.
|
||||
|
||||
## 3.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#171](https://github.com/cloudflare/wrangler-action/pull/171) [`76d614f`](https://github.com/cloudflare/wrangler-action/commit/76d614f400bd92237ed23c3df559f2c31b14a790) Thanks [@1000hz](https://github.com/1000hz)! - Fixed issues that caused the action to fail if any secret or var values contained shell metacharacters.
|
||||
|
||||
- [#171](https://github.com/cloudflare/wrangler-action/pull/171) [`473d9cb`](https://github.com/cloudflare/wrangler-action/commit/473d9cbd296528b41c653af10062faba6540a7ab) Thanks [@1000hz](https://github.com/1000hz)! - Bumped `DEFAULT_WRANGLER_VERSION` to 3.13.2
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#193](https://github.com/cloudflare/wrangler-action/pull/193) [`a4509d5`](https://github.com/cloudflare/wrangler-action/commit/a4509d507c62dd7f49fba7df7d2db3997222393a) Thanks [@1000hz](https://github.com/1000hz)! - Fixed the package manager not being inferred based on lockfile when the `packageManager` input isn't set.
|
||||
|
||||
## 3.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#188](https://github.com/cloudflare/wrangler-action/pull/188) [`d9a0a00`](https://github.com/cloudflare/wrangler-action/commit/d9a0a00f8bc502ceea2a60e5af258416b35a85b9) Thanks [@simpleauthority](https://github.com/simpleauthority)! - Added support for Bun as a package manager
|
||||
|
||||
## 3.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#190](https://github.com/cloudflare/wrangler-action/pull/190) [`528687a`](https://github.com/cloudflare/wrangler-action/commit/528687aaf436f67565918533ffd15c250f39c47b) Thanks [@1000hz](https://github.com/1000hz)! - Fixed action failure when no `packageManager` specified and no lockfile is found. The action now falls back to using npm.
|
||||
|
||||
## 3.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
* @cloudflare/wrangler
|
||||
* @cloudflare/wrangler @cloudflare/banda-team
|
||||
|
||||
CHANGELOG.md @cloudflare/wrangler-admins
|
||||
CHANGELOG.md @cloudflare/wrangler-admins @cloudflare/banda-team
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Contributing Guide
|
||||
|
||||
## Releases
|
||||
|
||||
### Changesets
|
||||
|
||||
Every non-trivial change to the project - those that should appear in the changelog - must be captured in a "changeset". We use the changesets tool for creating changesets, publishing versions and updating the changelog.
|
||||
|
||||
Create a changeset for the current change.
|
||||
|
||||
> npx changeset
|
||||
> Select which workspaces are affected by the change and whether the version requires a major, minor or patch release.
|
||||
> Update the generated changeset with a description of the change.
|
||||
> Include the generate changeset in the current commit.
|
||||
> git add ./changeset/\*.md
|
||||
|
||||
### Version Packages PRs
|
||||
|
||||
Once you merge your PR, a new Version Packages PR will be opened in the wrangler-action repo. Once that PR is merged, your change will be released. Example: https://github.com/cloudflare/wrangler-action/pull/305
|
||||
|
||||
Note: Version Packages PRs are only generated if there's been at least one PR merged with a changeset.
|
||||
@@ -27,18 +27,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Deploy
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
You'll need to configure Wrangler using GitHub's Secrets feature - go to "Settings -> Secrets" and add your Cloudflare API token (for help finding this, see the [Workers documentation](https://developers.cloudflare.com/workers/quickstart/#api-token)). Your API token is encrypted by GitHub, and the action won't print it into logs, so it should be safe!
|
||||
You'll need to configure Wrangler using GitHub's Secrets feature - go to "Settings -> Secrets" and add your Cloudflare API token (for help finding this, see the [Workers documentation](https://developers.cloudflare.com/workers/wrangler/ci-cd/#api-token)). Your API token is encrypted by GitHub, and the action won't print it into logs, so it should be safe!
|
||||
|
||||
With your API token set as a secret for your repository, pass it to the action in the `with` block of your workflow. Below, I've set the secret name to `CF_API_TOKEN`:
|
||||
With your API token set as a secret for your repository, pass it to the action in the `with` block of your workflow. Below, I've set the secret name to `CLOUDFLARE_API_TOKEN`:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
steps:
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
steps:
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
wranglerVersion: "2.20.0"
|
||||
```
|
||||
|
||||
@@ -72,11 +72,11 @@ jobs:
|
||||
steps:
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
workingDirectory: "subfoldername"
|
||||
```
|
||||
|
||||
[Worker secrets](https://developers.cloudflare.com/workers/tooling/wrangler/secrets/) can optionally be passed in via `secrets` as a string of names separated by newlines. Each secret name must match the name of an environment variable specified in the `env` field. This creates or replaces the value for the Worker secret using the `wrangler secret put` command.
|
||||
[Worker secrets](https://developers.cloudflare.com/workers/tooling/wrangler/secrets/) can optionally be passed in via `secrets` as a string of names separated by newlines. Each secret name must match the name of an environment variable specified in the `env` field. This creates or replaces the value for the Worker secret using the `wrangler secret put` command. It's also possible to specify worker environment using environment parameter.
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
@@ -84,7 +84,8 @@ jobs:
|
||||
steps:
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
environment: production
|
||||
secrets: |
|
||||
SECRET1
|
||||
SECRET2
|
||||
@@ -101,7 +102,7 @@ jobs:
|
||||
steps:
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
preCommands: echo "*** pre command ***"
|
||||
postCommands: |
|
||||
echo "*** post commands ***"
|
||||
@@ -117,10 +118,24 @@ jobs:
|
||||
steps:
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
command: whoami
|
||||
```
|
||||
|
||||
You can also add a command that spans multiple lines:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deploy:
|
||||
steps:
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
command: |
|
||||
pages project list
|
||||
pages deploy .vercel/output/static --project-name=demo-actions --branch=test
|
||||
```
|
||||
|
||||
## Use cases
|
||||
|
||||
### Deploy when commits are merged to main
|
||||
@@ -138,11 +153,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Deploy
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
```
|
||||
|
||||
Note that there are a number of possible events, like `push`, that can be used to trigger a workflow. For more details on the events available, refer to the [GitHub Actions documentation](https://help.github.com/en/articles/workflow-syntax-for-github-actions#on).
|
||||
@@ -158,14 +173,19 @@ jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Deploy
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
command: pages deploy --project-name=example
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy YOUR_DIST_FOLDER --project-name=example
|
||||
# Optional: Enable this if you want to have GitHub Deployments triggered
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
```
|
||||
|
||||
### Deploying on a schedule
|
||||
@@ -182,11 +202,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Deploy app
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
```
|
||||
|
||||
If you need help defining the correct cron syntax, check out [crontab.guru](https://crontab.guru/), which provides a friendly user interface for validating your cron schedule.
|
||||
@@ -208,16 +228,134 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Deploy app
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
command: deploy --env ${{ github.event.inputs.environment }}
|
||||
```
|
||||
|
||||
For more advanced usage or to programmatically trigger the workflow from scripts, refer to [the GitHub documentation](https://docs.github.com/en/rest/reference/actions#create-a-workflow-dispatch-event) for making API calls.
|
||||
|
||||
### Upload a Worker Version
|
||||
|
||||
To create a new version of your Worker that is not deployed immediately, use the `wrangler versions upload` command. Worker versions created in this way can then be deployed all at once at a later time or gradually deployed using the `wranger versions deploy` command or via the Cloudflare dashboard under the Deployments tab. Wrangler v3.40.0 or above is required to use this feature.
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
upload:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Upload Worker Version
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: versions upload
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Setting A Worker Secret for A Specific Environment
|
||||
|
||||
There is an environment parameter that can be set within the workflow to enable this. Example:
|
||||
|
||||
```yaml
|
||||
- uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
command: deploy --env production
|
||||
secrets: |
|
||||
SUPER_SECRET
|
||||
environment: production
|
||||
env:
|
||||
SUPER_SECRET: ${{ secrets.SUPER_SECRET }}
|
||||
```
|
||||
|
||||
### Using Wrangler Command Output in Subsequent Steps
|
||||
|
||||
More advanced workflows may need to parse the resulting output of Wrangler commands. To do this, you can use the `command-output` output variable in subsequent steps. For example, if you want to print the output of the Wrangler command, you can do the following:
|
||||
|
||||
```yaml
|
||||
- name: Deploy
|
||||
id: deploy
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy --project-name=example
|
||||
|
||||
- name: print wrangler command output
|
||||
env:
|
||||
CMD_OUTPUT: ${{ steps.deploy.outputs.command-output }}
|
||||
run: echo $CMD_OUTPUT
|
||||
```
|
||||
|
||||
Now when you run your workflow, you will see the full output of the Wrangler command in your workflow logs. You can also use this output in subsequent workflow steps to parse the output for specific values.
|
||||
|
||||
> Note: the `command-stderr` output variable is also available if you need to parse the standard error output of the Wrangler command.
|
||||
|
||||
### Using the `deployment-url` and `pages-deployment-alias-url` Output Variables
|
||||
|
||||
If you are executing a Wrangler command that results in either a Workers or Pages deployment, you can utilize the `deployment-url` output variable to get the URL of the deployment. For example, if you want to print the deployment URL after deploying your application, you can do the following:
|
||||
|
||||
```yaml
|
||||
- name: Deploy
|
||||
id: deploy
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy --project-name=example
|
||||
|
||||
- name: print deployment-url
|
||||
env:
|
||||
DEPLOYMENT_URL: ${{ steps.deploy.outputs.deployment-url }}
|
||||
run: echo $DEPLOYMENT_URL
|
||||
```
|
||||
|
||||
The resulting output will look something like this:
|
||||
|
||||
```text
|
||||
https://<your_pages_site>.pages.dev
|
||||
```
|
||||
|
||||
Pages deployments will also provide their alias URL (since Wrangler v3.78.0). You can use the `pages-deployment-alias-url` output variable to get the URL of the deployment alias. This is useful for, for example, branch aliases for preview deployments.
|
||||
|
||||
If the sample action above was used to deploy a branch other than main, you could use the following to get the branch URL:
|
||||
|
||||
```yaml
|
||||
- name: print pages-deployment-alias-url
|
||||
env:
|
||||
DEPLOYMENT_ALIAS_URL: ${{ steps.deploy.outputs.pages-deployment-alias-url }}
|
||||
run: echo $DEPLOYMENT_ALIAS_URL
|
||||
```
|
||||
|
||||
Resulting in:
|
||||
|
||||
```text
|
||||
https://new-feature.<your_pages_site>.pages.dev
|
||||
```
|
||||
|
||||
### Using a different package manager
|
||||
|
||||
By default, this action will detect which package manager to use, based on the presence of a `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, or `bun.lockb`/`bun.lock` file.
|
||||
|
||||
If you need to use a specific package manager for your application, you can set the `packageManager` input to `npm`, `yarn`, `pnpm`, or `bun`. You don't need to set this option unless you want to override the default behavior.
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deploy:
|
||||
steps:
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
packageManager: pnpm
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "I just started using Workers/Wrangler and I don't know what this is!"
|
||||
@@ -236,10 +374,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Deploy app
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
```
|
||||
|
||||
+17
-1
@@ -42,5 +42,21 @@ inputs:
|
||||
description: "A string of environment variable names, separated by newlines. These will be bound to your Worker using the values of matching environment variables declared in `env` of this workflow."
|
||||
required: false
|
||||
packageManager:
|
||||
description: "The name of the package manager to install and run wrangler. If not provided, it will be detected via the lock file. Valid values: [npm, pnpm, yarn]"
|
||||
description: "The package manager you'd like to use to install and run wrangler. If not specified, the preferred package manager will be inferred based on the presence of a lockfile or fallback to using npm if no lockfile is found. Valid values are `npm` | `pnpm` | `yarn` | `bun`."
|
||||
required: false
|
||||
gitHubToken:
|
||||
description: "GitHub Token"
|
||||
required: false
|
||||
outputs:
|
||||
command-output:
|
||||
description: "The output of the Wrangler command (comes from stdout)"
|
||||
command-stderr:
|
||||
description: "The error output of the Wrangler command (comes from stderr)"
|
||||
deployment-url:
|
||||
description: "If the command was a Workers or Pages deployment, this will be the URL of the deployment"
|
||||
pages-deployment-alias-url:
|
||||
description: "If the command was a Pages deployment, this will be the URL of the deployment alias (if it exists) - needs wrangler >= 3.78.0"
|
||||
pages-deployment-id:
|
||||
description: "If the command was a Pages deployment, this will be the ID of the deployment - needs wrangler >= 3.81.0"
|
||||
pages-environment:
|
||||
description: "If the command was a Pages deployment, this will be the environment of the deployment - needs wrangler >= 3.81.0"
|
||||
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import { exec as _childProcessExec } from "node:child_process";
|
||||
export { exec } from "@actions/exec";
|
||||
declare const childProcessExec: typeof _childProcessExec.__promisify__;
|
||||
export declare function execShell(command: string, { silent, ...options }?: Parameters<typeof childProcessExec>[1] & {
|
||||
silent?: boolean;
|
||||
}): Promise<number | null>;
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Vendored
+37255
File diff suppressed because one or more lines are too long
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
export interface PackageManager {
|
||||
install: string;
|
||||
exec: string;
|
||||
execNoInstall: string;
|
||||
}
|
||||
export declare function getPackageManager(name: string, { workingDirectory }?: {
|
||||
workingDirectory?: string;
|
||||
}): {
|
||||
readonly install: "npm i";
|
||||
readonly exec: "npx";
|
||||
readonly execNoInstall: "npx --no-install";
|
||||
} | {
|
||||
readonly install: "yarn add";
|
||||
readonly exec: "yarn";
|
||||
readonly execNoInstall: "yarn";
|
||||
} | {
|
||||
readonly install: "pnpm add";
|
||||
readonly exec: "pnpm exec";
|
||||
readonly execNoInstall: "pnpm exec";
|
||||
} | {
|
||||
readonly install: "bun i";
|
||||
readonly exec: "bunx";
|
||||
readonly execNoInstall: "bun run";
|
||||
};
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
import { getOctokit } from "@actions/github";
|
||||
import { OutputEntryPagesDeployment } from "../wranglerArtifactManager";
|
||||
import { WranglerActionConfig } from "../wranglerAction";
|
||||
type Octokit = ReturnType<typeof getOctokit>;
|
||||
export declare function createGitHubDeployment({ config, octokit, productionBranch, environment, deploymentId, projectName, deploymentUrl, }: {
|
||||
config: WranglerActionConfig;
|
||||
octokit: Octokit;
|
||||
productionBranch: string;
|
||||
environment: string;
|
||||
deploymentId: string | null;
|
||||
projectName: string;
|
||||
deploymentUrl?: string;
|
||||
}): Promise<void>;
|
||||
export declare function createJobSummary({ commitHash, deploymentUrl, aliasUrl, }: {
|
||||
commitHash: string;
|
||||
deploymentUrl?: string;
|
||||
aliasUrl?: string;
|
||||
}): Promise<void>;
|
||||
/**
|
||||
* Create github deployment, if GITHUB_TOKEN is present in config
|
||||
*/
|
||||
export declare function createGitHubDeploymentAndJobSummary(config: WranglerActionConfig, pagesArtifactFields: OutputEntryPagesDeployment): Promise<void>;
|
||||
export {};
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,2 @@
|
||||
declare const _default: {};
|
||||
export default _default;
|
||||
@@ -0,0 +1,2 @@
|
||||
declare const _default: {};
|
||||
export default _default;
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
type Env = {
|
||||
SECRET1?: string;
|
||||
SECRET2?: string;
|
||||
};
|
||||
declare const _default: {
|
||||
fetch(request: Request, env: Env): Response;
|
||||
};
|
||||
export default _default;
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
export declare function mockGithubDeployments({ githubUser, githubRepoName, }: {
|
||||
githubUser: string;
|
||||
githubRepoName: string;
|
||||
}): {
|
||||
handlers: import("msw").HttpHandler[];
|
||||
};
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import { WranglerActionConfig } from "../wranglerAction";
|
||||
export declare function getTestConfig({ config, }?: {
|
||||
config?: Partial<WranglerActionConfig>;
|
||||
}): WranglerActionConfig;
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
import { WranglerActionConfig } from "./wranglerAction";
|
||||
/**
|
||||
* A helper function to compare two semver versions. If the second arg is greater than the first arg, it returns true.
|
||||
*/
|
||||
export declare function semverCompare(version1: string, version2: string): boolean;
|
||||
export declare function checkWorkingDirectory(workingDirectory?: string): string;
|
||||
export declare function info(config: WranglerActionConfig, message: string, bypass?: boolean): void;
|
||||
export declare function error(config: WranglerActionConfig, message: string, bypass?: boolean): void;
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
import { z } from "zod";
|
||||
import { PackageManager } from "./packageManagers";
|
||||
import { info } from "./utils";
|
||||
export type WranglerActionConfig = z.infer<typeof wranglerActionConfig>;
|
||||
export declare const wranglerActionConfig: z.ZodObject<{
|
||||
WRANGLER_VERSION: z.ZodString;
|
||||
didUserProvideWranglerVersion: z.ZodBoolean;
|
||||
secrets: z.ZodArray<z.ZodString, "many">;
|
||||
workingDirectory: z.ZodString;
|
||||
CLOUDFLARE_API_TOKEN: z.ZodString;
|
||||
CLOUDFLARE_ACCOUNT_ID: z.ZodString;
|
||||
ENVIRONMENT: z.ZodString;
|
||||
VARS: z.ZodArray<z.ZodString, "many">;
|
||||
COMMANDS: z.ZodArray<z.ZodString, "many">;
|
||||
QUIET_MODE: z.ZodBoolean;
|
||||
PACKAGE_MANAGER: z.ZodString;
|
||||
WRANGLER_OUTPUT_DIR: z.ZodString;
|
||||
GITHUB_TOKEN: z.ZodString;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
WRANGLER_VERSION: string;
|
||||
didUserProvideWranglerVersion: boolean;
|
||||
secrets: string[];
|
||||
workingDirectory: string;
|
||||
CLOUDFLARE_API_TOKEN: string;
|
||||
CLOUDFLARE_ACCOUNT_ID: string;
|
||||
ENVIRONMENT: string;
|
||||
VARS: string[];
|
||||
COMMANDS: string[];
|
||||
QUIET_MODE: boolean;
|
||||
PACKAGE_MANAGER: string;
|
||||
WRANGLER_OUTPUT_DIR: string;
|
||||
GITHUB_TOKEN: string;
|
||||
}, {
|
||||
WRANGLER_VERSION: string;
|
||||
didUserProvideWranglerVersion: boolean;
|
||||
secrets: string[];
|
||||
workingDirectory: string;
|
||||
CLOUDFLARE_API_TOKEN: string;
|
||||
CLOUDFLARE_ACCOUNT_ID: string;
|
||||
ENVIRONMENT: string;
|
||||
VARS: string[];
|
||||
COMMANDS: string[];
|
||||
QUIET_MODE: boolean;
|
||||
PACKAGE_MANAGER: string;
|
||||
WRANGLER_OUTPUT_DIR: string;
|
||||
GITHUB_TOKEN: string;
|
||||
}>;
|
||||
declare function main(config: WranglerActionConfig, packageManager: PackageManager): Promise<void>;
|
||||
declare function installWrangler(config: WranglerActionConfig, packageManager: PackageManager): Promise<void>;
|
||||
declare function authenticationSetup(config: WranglerActionConfig): void;
|
||||
declare function execCommands(config: WranglerActionConfig, packageManager: PackageManager, commands: string[], cmdType: string): Promise<void>;
|
||||
declare function uploadSecrets(config: WranglerActionConfig, packageManager: PackageManager): Promise<void>;
|
||||
declare function wranglerCommands(config: WranglerActionConfig, packageManager: PackageManager): Promise<void>;
|
||||
export { authenticationSetup, execCommands, info, installWrangler, main, uploadSecrets, wranglerCommands, };
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Vendored
+103
@@ -0,0 +1,103 @@
|
||||
import { z } from "zod";
|
||||
declare const OutputEntryPagesDeployment: z.ZodObject<z.objectUtil.extendShape<{
|
||||
version: z.ZodLiteral<1>;
|
||||
type: z.ZodString;
|
||||
}, {
|
||||
type: z.ZodLiteral<"pages-deploy-detailed">;
|
||||
pages_project: z.ZodNullable<z.ZodString>;
|
||||
deployment_id: z.ZodNullable<z.ZodString>;
|
||||
url: z.ZodOptional<z.ZodString>;
|
||||
alias: z.ZodOptional<z.ZodString>;
|
||||
environment: z.ZodEnum<["production", "preview"]>;
|
||||
production_branch: z.ZodOptional<z.ZodString>;
|
||||
stages: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
||||
name: z.ZodEnum<["queued", "initialize", "clone_repo", "build", "deploy"]>;
|
||||
status: z.ZodEnum<["idle", "active", "canceled", "success", "failure", "skipped"]>;
|
||||
started_on: z.ZodNullable<z.ZodString>;
|
||||
ended_on: z.ZodNullable<z.ZodString>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
status: "idle" | "active" | "canceled" | "success" | "failure" | "skipped";
|
||||
name: "deploy" | "queued" | "initialize" | "clone_repo" | "build";
|
||||
started_on: string | null;
|
||||
ended_on: string | null;
|
||||
}, {
|
||||
status: "idle" | "active" | "canceled" | "success" | "failure" | "skipped";
|
||||
name: "deploy" | "queued" | "initialize" | "clone_repo" | "build";
|
||||
started_on: string | null;
|
||||
ended_on: string | null;
|
||||
}>, "many">>;
|
||||
deployment_trigger: z.ZodOptional<z.ZodObject<{
|
||||
metadata: z.ZodObject<{
|
||||
/** Commit hash of the deployment trigger metadata for the pages project */
|
||||
commit_hash: z.ZodString;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
commit_hash: string;
|
||||
}, {
|
||||
commit_hash: string;
|
||||
}>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
metadata: {
|
||||
commit_hash: string;
|
||||
};
|
||||
}, {
|
||||
metadata: {
|
||||
commit_hash: string;
|
||||
};
|
||||
}>>;
|
||||
}>, "strip", z.ZodTypeAny, {
|
||||
type: "pages-deploy-detailed";
|
||||
environment: "production" | "preview";
|
||||
version: 1;
|
||||
pages_project: string | null;
|
||||
deployment_id: string | null;
|
||||
url?: string | undefined;
|
||||
alias?: string | undefined;
|
||||
production_branch?: string | undefined;
|
||||
stages?: {
|
||||
status: "idle" | "active" | "canceled" | "success" | "failure" | "skipped";
|
||||
name: "deploy" | "queued" | "initialize" | "clone_repo" | "build";
|
||||
started_on: string | null;
|
||||
ended_on: string | null;
|
||||
}[] | undefined;
|
||||
deployment_trigger?: {
|
||||
metadata: {
|
||||
commit_hash: string;
|
||||
};
|
||||
} | undefined;
|
||||
}, {
|
||||
type: "pages-deploy-detailed";
|
||||
environment: "production" | "preview";
|
||||
version: 1;
|
||||
pages_project: string | null;
|
||||
deployment_id: string | null;
|
||||
url?: string | undefined;
|
||||
alias?: string | undefined;
|
||||
production_branch?: string | undefined;
|
||||
stages?: {
|
||||
status: "idle" | "active" | "canceled" | "success" | "failure" | "skipped";
|
||||
name: "deploy" | "queued" | "initialize" | "clone_repo" | "build";
|
||||
started_on: string | null;
|
||||
ended_on: string | null;
|
||||
}[] | undefined;
|
||||
deployment_trigger?: {
|
||||
metadata: {
|
||||
commit_hash: string;
|
||||
};
|
||||
} | undefined;
|
||||
}>;
|
||||
export type OutputEntryPagesDeployment = z.infer<typeof OutputEntryPagesDeployment>;
|
||||
/**
|
||||
* Parses file names in a directory to find wrangler artifact files
|
||||
*
|
||||
* @param artifactDirectory
|
||||
* @returns All artifact files from the directory
|
||||
*/
|
||||
export declare function getWranglerArtifacts(artifactDirectory: string): Promise<string[]>;
|
||||
/**
|
||||
* Searches for detailed wrangler output from a pages deploy
|
||||
*
|
||||
* @param artifactDirectory
|
||||
* @returns The first pages-output-detailed found within a wrangler artifact directory
|
||||
*/
|
||||
export declare function getDetailedPagesDeployOutput(artifactDirectory: string): Promise<OutputEntryPagesDeployment | null>;
|
||||
export {};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Generated
+1460
-2512
File diff suppressed because it is too large
Load Diff
+18
-10
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wrangler-action",
|
||||
"version": "3.2.0",
|
||||
"version": "3.12.1",
|
||||
"description": "GitHub Action to use [Wrangler](https://developers.cloudflare.com/workers/cli-wrangler/).",
|
||||
"author": "wrangler@cloudflare.com",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
@@ -29,16 +29,24 @@
|
||||
"check": "prettier --check ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0"
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/github": "^6.0.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/changelog-github": "^0.4.8",
|
||||
"@changesets/cli": "^2.26.2",
|
||||
"@cloudflare/workers-types": "^4.20230814.0",
|
||||
"@types/node": "^20.5.0",
|
||||
"@vercel/ncc": "^0.36.1",
|
||||
"prettier": "^3.0.1",
|
||||
"typescript": "^5.1.6",
|
||||
"vitest": "^0.34.1"
|
||||
"@changesets/changelog-github": "^0.5.0",
|
||||
"@changesets/cli": "^2.27.9",
|
||||
"@cloudflare/workers-types": "^4.20241022.0",
|
||||
"@types/mock-fs": "^4.13.4",
|
||||
"@types/node": "^22.9.0",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@vercel/ncc": "^0.38.2",
|
||||
"mock-fs": "^5.4.1",
|
||||
"msw": "^2.6.4",
|
||||
"prettier": "^3.3.3",
|
||||
"semver": "^7.6.3",
|
||||
"typescript": "^5.6.3",
|
||||
"vitest": "^2.1.4"
|
||||
}
|
||||
}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
exec as _childProcessExec,
|
||||
type ExecException,
|
||||
} from "node:child_process";
|
||||
import { EOL } from "node:os";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
export { exec } from "@actions/exec";
|
||||
|
||||
const childProcessExec = promisify(_childProcessExec);
|
||||
|
||||
type ExecAsyncException = ExecException & {
|
||||
stderr: string;
|
||||
stdout: string;
|
||||
};
|
||||
|
||||
function isExecAsyncException(err: unknown): err is ExecAsyncException {
|
||||
return err instanceof Error && "code" in err && "stderr" in err;
|
||||
}
|
||||
|
||||
export async function execShell(
|
||||
command: string,
|
||||
{
|
||||
silent = false,
|
||||
...options
|
||||
}: Parameters<typeof childProcessExec>[1] & { silent?: boolean } = {},
|
||||
) {
|
||||
if (!silent) {
|
||||
process.stdout.write("[command]" + command + EOL);
|
||||
}
|
||||
|
||||
try {
|
||||
const promise = childProcessExec(command, {
|
||||
...options,
|
||||
});
|
||||
|
||||
const { child } = promise;
|
||||
|
||||
if (!silent) {
|
||||
child.stdout?.on("data", (data: Buffer) => process.stdout.write(data));
|
||||
child.stderr?.on("data", (data: Buffer) => process.stderr.write(data));
|
||||
}
|
||||
|
||||
await promise;
|
||||
return child.exitCode;
|
||||
} catch (err) {
|
||||
if (isExecAsyncException(err)) {
|
||||
process.stderr.write(err.stderr);
|
||||
throw new Error(`Process failed with exit code ${err.code}`);
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
+18
-303
@@ -1,51 +1,18 @@
|
||||
import {
|
||||
getBooleanInput,
|
||||
getInput,
|
||||
getMultilineInput,
|
||||
endGroup as originalEndGroup,
|
||||
error as originalError,
|
||||
info as originalInfo,
|
||||
startGroup as originalStartGroup,
|
||||
setFailed,
|
||||
} from "@actions/core";
|
||||
import { exec, execSync } from "node:child_process";
|
||||
import * as util from "node:util";
|
||||
import {
|
||||
PackageManager,
|
||||
checkWorkingDirectory,
|
||||
detectPackageManager,
|
||||
isValidPackageManager,
|
||||
semverCompare,
|
||||
} from "./utils";
|
||||
const execAsync = util.promisify(exec);
|
||||
import { getBooleanInput, getInput, getMultilineInput } from "@actions/core";
|
||||
import { tmpdir } from "os";
|
||||
import { join } from "path";
|
||||
import { getPackageManager } from "./packageManagers";
|
||||
import { checkWorkingDirectory } from "./utils";
|
||||
import { main, WranglerActionConfig } from "./wranglerAction";
|
||||
|
||||
const DEFAULT_WRANGLER_VERSION = "3.5.1";
|
||||
|
||||
interface PackageManagerCommands {
|
||||
install: string;
|
||||
exec: string;
|
||||
}
|
||||
|
||||
const PACKAGE_MANAGER_COMMANDS = {
|
||||
npm: {
|
||||
install: "npm i",
|
||||
exec: "npx",
|
||||
},
|
||||
yarn: {
|
||||
install: "yarn add",
|
||||
exec: "yarn",
|
||||
},
|
||||
pnpm: {
|
||||
install: "pnpm add",
|
||||
exec: "pnpm exec",
|
||||
},
|
||||
} as const satisfies Readonly<Record<PackageManager, PackageManagerCommands>>;
|
||||
const DEFAULT_WRANGLER_VERSION = "3.81.0";
|
||||
|
||||
/**
|
||||
* A configuration object that contains all the inputs & immutable state for the action.
|
||||
*/
|
||||
const config = {
|
||||
const config: WranglerActionConfig = {
|
||||
WRANGLER_VERSION: getInput("wranglerVersion") || DEFAULT_WRANGLER_VERSION,
|
||||
didUserProvideWranglerVersion: Boolean(getInput("wranglerVersion")),
|
||||
secrets: getMultilineInput("secrets"),
|
||||
workingDirectory: checkWorkingDirectory(getInput("workingDirectory")),
|
||||
CLOUDFLARE_API_TOKEN: getInput("apiToken"),
|
||||
@@ -55,267 +22,15 @@ const config = {
|
||||
COMMANDS: getMultilineInput("command"),
|
||||
QUIET_MODE: getBooleanInput("quiet"),
|
||||
PACKAGE_MANAGER: getInput("packageManager"),
|
||||
WRANGLER_OUTPUT_DIR: `${join(
|
||||
tmpdir(),
|
||||
`wranglerArtifacts-${crypto.randomUUID()}`,
|
||||
)}`,
|
||||
GITHUB_TOKEN: getInput("gitHubToken", { required: false }),
|
||||
} as const;
|
||||
|
||||
function realPackageManager(): PackageManager {
|
||||
if (isValidPackageManager(config.PACKAGE_MANAGER)) {
|
||||
return config.PACKAGE_MANAGER;
|
||||
}
|
||||
const packageManager = getPackageManager(config.PACKAGE_MANAGER, {
|
||||
workingDirectory: config.workingDirectory,
|
||||
});
|
||||
|
||||
const packageManager = detectPackageManager(config.workingDirectory);
|
||||
if (packageManager !== null) {
|
||||
return packageManager;
|
||||
}
|
||||
|
||||
throw new Error("Package manager is not detected");
|
||||
}
|
||||
|
||||
const pkgManagerCmd = PACKAGE_MANAGER_COMMANDS[realPackageManager()];
|
||||
|
||||
function info(message: string, bypass?: boolean): void {
|
||||
if (!config.QUIET_MODE || bypass) {
|
||||
originalInfo(message);
|
||||
}
|
||||
}
|
||||
|
||||
function error(message: string, bypass?: boolean): void {
|
||||
if (!config.QUIET_MODE || bypass) {
|
||||
originalError(message);
|
||||
}
|
||||
}
|
||||
|
||||
function startGroup(name: string): void {
|
||||
if (!config.QUIET_MODE) {
|
||||
originalStartGroup(name);
|
||||
}
|
||||
}
|
||||
|
||||
function endGroup(): void {
|
||||
if (!config.QUIET_MODE) {
|
||||
originalEndGroup();
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
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(
|
||||
command: Parameters<typeof execAsync>[0],
|
||||
options: Parameters<typeof execAsync>[1],
|
||||
) {
|
||||
try {
|
||||
const result = await execAsync(command, options);
|
||||
|
||||
result.stdout && info(result.stdout.toString());
|
||||
result.stderr && error(result.stderr.toString(), true);
|
||||
|
||||
return result;
|
||||
} catch (err: any) {
|
||||
err.stdout && info(err.stdout.toString());
|
||||
err.stderr && error(err.stderr.toString(), true);
|
||||
throw new Error(`\`${command}\` returned non-zero exit code.`);
|
||||
}
|
||||
}
|
||||
|
||||
function installWrangler() {
|
||||
if (config["WRANGLER_VERSION"].startsWith("1")) {
|
||||
throw new Error(
|
||||
`Wrangler v1 is no longer supported by this action. Please use major version 2 or greater`,
|
||||
);
|
||||
}
|
||||
startGroup("📥 Installing Wrangler");
|
||||
const command = `${pkgManagerCmd.install} wrangler@${config["WRANGLER_VERSION"]}`;
|
||||
info(`Running command: ${command}`);
|
||||
execSync(command, { cwd: config["workingDirectory"], env: process.env });
|
||||
info(`✅ Wrangler installed`, true);
|
||||
endGroup();
|
||||
}
|
||||
|
||||
function authenticationSetup() {
|
||||
process.env.CLOUDFLARE_API_TOKEN = config["CLOUDFLARE_API_TOKEN"];
|
||||
process.env.CLOUDFLARE_ACCOUNT_ID = config["CLOUDFLARE_ACCOUNT_ID"];
|
||||
}
|
||||
|
||||
async function execCommands(commands: string[], cmdType: string) {
|
||||
if (!commands.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
startGroup(`🚀 Running ${cmdType}Commands`);
|
||||
try {
|
||||
const arrPromises = commands.map(async (command) => {
|
||||
const cmd = command.startsWith("wrangler")
|
||||
? `${pkgManagerCmd.exec} ${command}`
|
||||
: command;
|
||||
|
||||
info(`🚀 Executing command: ${cmd}`);
|
||||
|
||||
return await runProcess(cmd, {
|
||||
cwd: config["workingDirectory"],
|
||||
env: process.env,
|
||||
});
|
||||
});
|
||||
|
||||
await Promise.all(arrPromises);
|
||||
} finally {
|
||||
endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function to get the secret from the environment variables.
|
||||
*/
|
||||
function getSecret(secret: string) {
|
||||
if (!secret) {
|
||||
throw new Error("Secret name cannot be blank.");
|
||||
}
|
||||
|
||||
const value = process.env[secret];
|
||||
if (!value) {
|
||||
throw new Error(`Value for secret ${secret} not found.`);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
async function legacyUploadSecrets(
|
||||
secrets: string[],
|
||||
environment?: string,
|
||||
workingDirectory?: string,
|
||||
) {
|
||||
const arrPromises = secrets
|
||||
.map((secret) => {
|
||||
const command = `echo ${getSecret(secret)} | ${
|
||||
pkgManagerCmd.exec
|
||||
} 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);
|
||||
}
|
||||
|
||||
async function uploadSecrets() {
|
||||
const secrets: string[] = config["secrets"];
|
||||
const environment = config["ENVIRONMENT"];
|
||||
const workingDirectory = config["workingDirectory"];
|
||||
|
||||
if (!secrets.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
startGroup("🔑 Uploading secrets...");
|
||||
|
||||
try {
|
||||
if (semverCompare(config["WRANGLER_VERSION"], "3.4.0"))
|
||||
return legacyUploadSecrets(secrets, environment, workingDirectory);
|
||||
|
||||
const secretObj = secrets.reduce((acc: any, secret: string) => {
|
||||
acc[secret] = getSecret(secret);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const environmentSuffix = !environment.length
|
||||
? ""
|
||||
: ` --env ${environment}`;
|
||||
|
||||
const secretCmd = `echo "${JSON.stringify(secretObj).replaceAll(
|
||||
'"',
|
||||
'\\"',
|
||||
)}" | ${pkgManagerCmd.exec} wrangler secret:bulk ${environmentSuffix}`;
|
||||
|
||||
execSync(secretCmd, {
|
||||
cwd: workingDirectory,
|
||||
env: process.env,
|
||||
stdio: "ignore",
|
||||
});
|
||||
|
||||
info(`✅ Uploaded secrets`);
|
||||
} catch (err) {
|
||||
error(`❌ Upload failed`);
|
||||
throw new Error(`Failed to upload secrets.`);
|
||||
} finally {
|
||||
endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
function getVarArgs() {
|
||||
const vars = config["VARS"];
|
||||
const envVarArray = vars.map((envVar: string) => {
|
||||
if (process.env[envVar] && process.env[envVar]?.length !== 0) {
|
||||
return `${envVar}:${process.env[envVar]!}`;
|
||||
} else {
|
||||
throw new Error(`Value for var ${envVar} not found in environment.`);
|
||||
}
|
||||
});
|
||||
|
||||
return envVarArray.length > 0 ? `--var ${envVarArray.join(" ").trim()}` : "";
|
||||
}
|
||||
|
||||
async function wranglerCommands() {
|
||||
startGroup("🚀 Running Wrangler Commands");
|
||||
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 arrPromises = commands.map(async (command) => {
|
||||
if (environment.length > 0 && !command.includes(`--env`)) {
|
||||
command = command.concat(` --env ${environment}`);
|
||||
}
|
||||
|
||||
const cmd = `${pkgManagerCmd.exec} wrangler ${command} ${
|
||||
(command.startsWith("deploy") || command.startsWith("publish")) &&
|
||||
!command.includes(`--var`)
|
||||
? getVarArgs()
|
||||
: ""
|
||||
}`.trim();
|
||||
|
||||
info(`🚀 Executing command: ${cmd}`);
|
||||
|
||||
return await runProcess(cmd, {
|
||||
cwd: config["workingDirectory"],
|
||||
env: process.env,
|
||||
});
|
||||
});
|
||||
|
||||
await Promise.all(arrPromises);
|
||||
} finally {
|
||||
endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
export {
|
||||
authenticationSetup,
|
||||
execCommands,
|
||||
installWrangler,
|
||||
uploadSecrets,
|
||||
wranglerCommands,
|
||||
};
|
||||
main(config, packageManager);
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { getPackageManager } from "./packageManagers";
|
||||
|
||||
describe("getPackageManager", () => {
|
||||
test("should use provided value instead of inferring from lockfile", () => {
|
||||
expect(
|
||||
getPackageManager("npm", { workingDirectory: "src/test/fixtures/npm" }),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "npx",
|
||||
"execNoInstall": "npx --no-install",
|
||||
"install": "npm i",
|
||||
}
|
||||
`);
|
||||
|
||||
expect(
|
||||
getPackageManager("yarn", { workingDirectory: "src/test/fixtures/npm" }),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "yarn",
|
||||
"execNoInstall": "yarn",
|
||||
"install": "yarn add",
|
||||
}
|
||||
`);
|
||||
|
||||
expect(
|
||||
getPackageManager("pnpm", { workingDirectory: "src/test/fixtures/npm" }),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "pnpm exec",
|
||||
"execNoInstall": "pnpm exec",
|
||||
"install": "pnpm add",
|
||||
}
|
||||
`);
|
||||
|
||||
expect(
|
||||
getPackageManager("bun", { workingDirectory: "src/test/fixtures/bun" }),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "bunx",
|
||||
"execNoInstall": "bun run",
|
||||
"install": "bun i",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("should use npm if no value provided and package-lock.json exists", () => {
|
||||
expect(getPackageManager("", { workingDirectory: "src/test/fixtures/npm" }))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "npx",
|
||||
"execNoInstall": "npx --no-install",
|
||||
"install": "npm i",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("should use yarn if no value provided and yarn.lock exists", () => {
|
||||
expect(
|
||||
getPackageManager("", { workingDirectory: "src/test/fixtures/yarn" }),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "yarn",
|
||||
"execNoInstall": "yarn",
|
||||
"install": "yarn add",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("should use pnpm if no value provided and pnpm-lock.yaml exists", () => {
|
||||
expect(
|
||||
getPackageManager("", { workingDirectory: "src/test/fixtures/pnpm" }),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "pnpm exec",
|
||||
"execNoInstall": "pnpm exec",
|
||||
"install": "pnpm add",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("should use bun if no value provided and bun.lockb exists", () => {
|
||||
expect(getPackageManager("", { workingDirectory: "src/test/fixtures/bun" }))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "bunx",
|
||||
"execNoInstall": "bun run",
|
||||
"install": "bun i",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("should use npm if no value provided and no lockfile is present", () => {
|
||||
expect(
|
||||
getPackageManager("", { workingDirectory: "src/test/fixtures/empty" }),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exec": "npx",
|
||||
"execNoInstall": "npx --no-install",
|
||||
"install": "npm i",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("should throw if an invalid value is provided", () => {
|
||||
expect(() =>
|
||||
getPackageManager("cargo", { workingDirectory: "src/test/fixtures/npm" }),
|
||||
).toThrowError();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,76 @@
|
||||
import { existsSync } from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
export interface PackageManager {
|
||||
install: string;
|
||||
exec: string;
|
||||
execNoInstall: string;
|
||||
}
|
||||
|
||||
const PACKAGE_MANAGERS = {
|
||||
npm: {
|
||||
install: "npm i",
|
||||
exec: "npx",
|
||||
execNoInstall: "npx --no-install",
|
||||
},
|
||||
yarn: {
|
||||
install: "yarn add",
|
||||
exec: "yarn",
|
||||
execNoInstall: "yarn",
|
||||
},
|
||||
pnpm: {
|
||||
install: "pnpm add",
|
||||
exec: "pnpm exec",
|
||||
execNoInstall: "pnpm exec",
|
||||
},
|
||||
bun: {
|
||||
install: "bun i",
|
||||
exec: "bunx",
|
||||
execNoInstall: "bun run",
|
||||
},
|
||||
} as const satisfies Readonly<Record<string, PackageManager>>;
|
||||
|
||||
type PackageManagerValue = keyof typeof PACKAGE_MANAGERS;
|
||||
|
||||
function detectPackageManager(
|
||||
workingDirectory = ".",
|
||||
): PackageManagerValue | null {
|
||||
if (existsSync(path.join(workingDirectory, "package-lock.json"))) {
|
||||
return "npm";
|
||||
}
|
||||
if (existsSync(path.join(workingDirectory, "yarn.lock"))) {
|
||||
return "yarn";
|
||||
}
|
||||
if (existsSync(path.join(workingDirectory, "pnpm-lock.yaml"))) {
|
||||
return "pnpm";
|
||||
}
|
||||
if (
|
||||
existsSync(path.join(workingDirectory, "bun.lockb")) ||
|
||||
existsSync(path.join(workingDirectory, "bun.lock"))
|
||||
) {
|
||||
return "bun";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function assertValidPackageManagerValue(
|
||||
name: string,
|
||||
): asserts name is PackageManagerValue | "" {
|
||||
if (name && !Object.keys(PACKAGE_MANAGERS).includes(name)) {
|
||||
throw new TypeError(
|
||||
`invalid value provided for "packageManager": ${name}
|
||||
Value must be one of: [${Object.keys(PACKAGE_MANAGERS).join(", ")}]`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function getPackageManager(
|
||||
name: string,
|
||||
{ workingDirectory = "." }: { workingDirectory?: string } = {},
|
||||
) {
|
||||
assertValidPackageManagerValue(name);
|
||||
|
||||
return PACKAGE_MANAGERS[
|
||||
name || detectPackageManager(workingDirectory) || "npm"
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { setupServer } from "msw/node";
|
||||
import { createGitHubDeployment, createJobSummary } from "./github";
|
||||
import { getOctokit } from "@actions/github";
|
||||
import { mockGithubDeployments } from "../test/mocks";
|
||||
import { getTestConfig } from "../test/test-utils";
|
||||
import mockfs from "mock-fs";
|
||||
import { readFile } from "fs/promises";
|
||||
|
||||
afterEach(() => {
|
||||
mockfs.restore();
|
||||
});
|
||||
|
||||
describe("github", () => {
|
||||
it("Calls createGitHubDeployment successfully", async () => {
|
||||
const githubUser = "mock-user";
|
||||
const githubRepoName = "wrangler-action";
|
||||
const server = setupServer(
|
||||
...mockGithubDeployments({ githubUser, githubRepoName }).handlers,
|
||||
);
|
||||
server.listen({ onUnhandledRequest: "error" });
|
||||
vi.stubEnv("GITHUB_REPOSITORY", `${githubUser}/${githubRepoName}`);
|
||||
|
||||
const testConfig = getTestConfig();
|
||||
const octokit = getOctokit(testConfig.GITHUB_TOKEN, { request: fetch });
|
||||
await createGitHubDeployment({
|
||||
config: testConfig,
|
||||
octokit,
|
||||
productionBranch: "production-branch",
|
||||
deploymentId: "fake-deployment-id",
|
||||
projectName: "fake-project-name",
|
||||
deploymentUrl: "https://fake-deployment-url.com",
|
||||
environment: "production",
|
||||
});
|
||||
server.close();
|
||||
});
|
||||
it("Calls createJobSummary successfully", async () => {
|
||||
vi.stubEnv("GITHUB_STEP_SUMMARY", "summary");
|
||||
mockfs({
|
||||
summary: mockfs.file(),
|
||||
});
|
||||
await createJobSummary({
|
||||
commitHash: "fake-commit-hash",
|
||||
deploymentUrl: "https://fake-deployment-url.com",
|
||||
aliasUrl: "https://fake-alias-url.com",
|
||||
});
|
||||
expect((await readFile("summary")).toString()).toMatchInlineSnapshot(`
|
||||
"
|
||||
# Deploying with Cloudflare Pages
|
||||
|
||||
| Name | Result |
|
||||
| ----------------------- | - |
|
||||
| **Last commit:** | fake-commit-hash |
|
||||
| **Preview URL**: | https://fake-deployment-url.com |
|
||||
| **Branch Preview URL**: | https://fake-alias-url.com |
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,120 @@
|
||||
import { summary } from "@actions/core";
|
||||
import { context, getOctokit } from "@actions/github";
|
||||
import { env } from "process";
|
||||
import { info } from "../utils";
|
||||
import { OutputEntryPagesDeployment } from "../wranglerArtifactManager";
|
||||
import { WranglerActionConfig } from "../wranglerAction";
|
||||
|
||||
type Octokit = ReturnType<typeof getOctokit>;
|
||||
|
||||
export async function createGitHubDeployment({
|
||||
config,
|
||||
octokit,
|
||||
productionBranch,
|
||||
environment,
|
||||
deploymentId,
|
||||
projectName,
|
||||
deploymentUrl,
|
||||
}: {
|
||||
config: WranglerActionConfig;
|
||||
octokit: Octokit;
|
||||
productionBranch: string;
|
||||
environment: string;
|
||||
deploymentId: string | null;
|
||||
projectName: string;
|
||||
deploymentUrl?: string;
|
||||
}) {
|
||||
const githubBranch = env.GITHUB_HEAD_REF || env.GITHUB_REF_NAME;
|
||||
const productionEnvironment = githubBranch === productionBranch;
|
||||
|
||||
const deployment = await octokit.rest.repos.createDeployment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: githubBranch || context.ref,
|
||||
auto_merge: false,
|
||||
description: "Cloudflare Pages",
|
||||
required_contexts: [],
|
||||
environment,
|
||||
production_environment: productionEnvironment,
|
||||
});
|
||||
|
||||
if (deployment.status !== 201) {
|
||||
info(config, "Error creating GitHub deployment");
|
||||
return;
|
||||
}
|
||||
await octokit.rest.repos.createDeploymentStatus({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
deployment_id: deployment.data.id,
|
||||
environment,
|
||||
environment_url: deploymentUrl,
|
||||
production_environment: productionEnvironment,
|
||||
// don't have project_name or deployment_id I think
|
||||
log_url: `https://dash.cloudflare.com/${config.CLOUDFLARE_ACCOUNT_ID}/pages/view/${projectName}/${deploymentId}`,
|
||||
description: "Cloudflare Pages",
|
||||
state: "success",
|
||||
auto_inactive: false,
|
||||
});
|
||||
}
|
||||
|
||||
export async function createJobSummary({
|
||||
commitHash,
|
||||
deploymentUrl,
|
||||
aliasUrl,
|
||||
}: {
|
||||
commitHash: string;
|
||||
deploymentUrl?: string;
|
||||
aliasUrl?: string;
|
||||
}) {
|
||||
await summary
|
||||
.addRaw(
|
||||
`
|
||||
# Deploying with Cloudflare Pages
|
||||
|
||||
| Name | Result |
|
||||
| ----------------------- | - |
|
||||
| **Last commit:** | ${commitHash} |
|
||||
| **Preview URL**: | ${deploymentUrl} |
|
||||
| **Branch Preview URL**: | ${aliasUrl} |
|
||||
`,
|
||||
)
|
||||
.write();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create github deployment, if GITHUB_TOKEN is present in config
|
||||
*/
|
||||
export async function createGitHubDeploymentAndJobSummary(
|
||||
config: WranglerActionConfig,
|
||||
pagesArtifactFields: OutputEntryPagesDeployment,
|
||||
) {
|
||||
if (
|
||||
config.GITHUB_TOKEN &&
|
||||
pagesArtifactFields.production_branch &&
|
||||
pagesArtifactFields.pages_project &&
|
||||
pagesArtifactFields.deployment_trigger &&
|
||||
pagesArtifactFields.stages
|
||||
) {
|
||||
const octokit = getOctokit(config.GITHUB_TOKEN);
|
||||
await Promise.all([
|
||||
createGitHubDeployment({
|
||||
config,
|
||||
octokit,
|
||||
deploymentUrl: pagesArtifactFields.url,
|
||||
productionBranch: pagesArtifactFields.production_branch,
|
||||
environment: pagesArtifactFields.environment,
|
||||
deploymentId: pagesArtifactFields.deployment_id,
|
||||
projectName: pagesArtifactFields.pages_project,
|
||||
}),
|
||||
createJobSummary({
|
||||
commitHash:
|
||||
pagesArtifactFields.deployment_trigger.metadata.commit_hash.substring(
|
||||
0,
|
||||
8,
|
||||
),
|
||||
deploymentUrl: pagesArtifactFields.url,
|
||||
aliasUrl: pagesArtifactFields.alias,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ export default {
|
||||
return new Response("OK");
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
return Response.json({
|
||||
...request,
|
||||
headers: Object.fromEntries(request.headers),
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
name = "wrangler-action-test-build-quiet"
|
||||
main = "./index.ts"
|
||||
compatibility_date = "2023-07-07"
|
||||
workers_dev = true
|
||||
@@ -17,7 +17,6 @@ export default {
|
||||
return new Response("OK");
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
return Response.json({
|
||||
...request,
|
||||
headers: Object.fromEntries(request.headers),
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-bun-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -12,7 +12,6 @@ export default {
|
||||
return new Response(`${SECRET1} ${SECRET2}`);
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
return Response.json({
|
||||
...request,
|
||||
headers: Object.fromEntries(request.headers),
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-environment-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -17,7 +17,6 @@ export default {
|
||||
return new Response("OK");
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
return Response.json({
|
||||
...request,
|
||||
headers: Object.fromEntries(request.headers),
|
||||
@@ -17,7 +17,6 @@ export default {
|
||||
return new Response("OK");
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
return Response.json({
|
||||
...request,
|
||||
headers: Object.fromEntries(request.headers),
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "wrangler-action-test",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wrangler-action-test"
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -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
|
||||
Vendored
+25
@@ -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),
|
||||
});
|
||||
},
|
||||
};
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-pnpm-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "wrangler",
|
||||
"version": "1.1.1",
|
||||
"main": "index.js",
|
||||
"bin": "index.js"
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "wrangler-action-pre-installed-wrangler-test",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wrangler-action-pre-installed-wrangler-test",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"wrangler": "file:mock_packages/wrangler"
|
||||
}
|
||||
},
|
||||
"mock_packages/wrangler": {
|
||||
"version": "1.1.1",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"wrangler": "index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/wrangler": {
|
||||
"resolved": "mock_packages/wrangler",
|
||||
"link": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"wrangler": {
|
||||
"version": "file:mock_packages/wrangler"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "wrangler-action-pre-installed-wrangler-test",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"wrangler": "file:mock_packages/wrangler"
|
||||
}
|
||||
}
|
||||
+25
@@ -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
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "wrangler-action-test",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wrangler-action-test"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
name = "wrangler-action-test-secrets-default"
|
||||
main = "./index.ts"
|
||||
compatibility_date = "2023-07-07"
|
||||
workers_dev = true
|
||||
+25
@@ -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
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "wrangler-action-test",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wrangler-action-test"
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
name = "wrangler-action-test-secrets-v2"
|
||||
main = "./index.ts"
|
||||
compatibility_date = "2023-07-07"
|
||||
workers_dev = true
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-detect-package-manager-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
name = "wrangler-action-test-specify-package-manager"
|
||||
main = "./index.ts"
|
||||
compatibility_date = "2023-07-07"
|
||||
workers_dev = true
|
||||
@@ -0,0 +1 @@
|
||||
export default {};
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-detect-package-manager-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
name = "wrangler-action-test-unspecified-package-manager"
|
||||
main = "./index.ts"
|
||||
compatibility_date = "2023-07-07"
|
||||
workers_dev = true
|
||||
Vendored
+25
@@ -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),
|
||||
});
|
||||
},
|
||||
};
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "wrangler-action-yarn-test",
|
||||
"license": "MIT",
|
||||
"private": true
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { http, HttpResponse } from "msw";
|
||||
import { z } from "zod";
|
||||
|
||||
export function mockGithubDeployments({
|
||||
githubUser,
|
||||
githubRepoName,
|
||||
}: {
|
||||
githubUser: string;
|
||||
githubRepoName: string;
|
||||
}) {
|
||||
return {
|
||||
handlers: [
|
||||
http.post(
|
||||
`https://api.github.com/repos/${githubUser}/${githubRepoName}/deployments`,
|
||||
async ({ request }) => {
|
||||
if (request.headers.get("Authorization") === null) {
|
||||
return HttpResponse.text("error: no auth token", { status: 400 });
|
||||
}
|
||||
const GithubDeploymentsRequest = z.object({
|
||||
auto_merge: z.literal(false),
|
||||
description: z.literal("Cloudflare Pages"),
|
||||
required_contexts: z.array(z.string()).length(0),
|
||||
environment: z.literal("production"),
|
||||
production_environment: z.literal(false),
|
||||
});
|
||||
// validate request body
|
||||
GithubDeploymentsRequest.parse(await request.json());
|
||||
|
||||
return HttpResponse.json(null);
|
||||
},
|
||||
),
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { WranglerActionConfig } from "../wranglerAction";
|
||||
|
||||
export function getTestConfig({
|
||||
config = {},
|
||||
}: {
|
||||
config?: Partial<WranglerActionConfig>;
|
||||
} = {}): WranglerActionConfig {
|
||||
return Object.assign(
|
||||
{
|
||||
WRANGLER_VERSION: "3.81.0",
|
||||
didUserProvideWranglerVersion: false,
|
||||
secrets: [],
|
||||
workingDirectory: "/src/test/fixtures",
|
||||
CLOUDFLARE_API_TOKEN: "foo",
|
||||
CLOUDFLARE_ACCOUNT_ID: "bar",
|
||||
ENVIRONMENT: "dev",
|
||||
VARS: [],
|
||||
COMMANDS: [],
|
||||
QUIET_MODE: false,
|
||||
PACKAGE_MANAGER: "npm",
|
||||
WRANGLER_OUTPUT_DIR: "/tmp/wranglerArtifacts",
|
||||
GITHUB_TOKEN: "xxxxyy23213123132131",
|
||||
} as const satisfies WranglerActionConfig,
|
||||
config,
|
||||
);
|
||||
}
|
||||
+22
-35
@@ -1,11 +1,6 @@
|
||||
import path from "node:path";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import {
|
||||
checkWorkingDirectory,
|
||||
detectPackageManager,
|
||||
isValidPackageManager,
|
||||
semverCompare,
|
||||
} from "./utils";
|
||||
import { checkWorkingDirectory, semverCompare } from "./utils";
|
||||
|
||||
describe("semverCompare", () => {
|
||||
test("should return false if the second argument is equal to the first argument", () => {
|
||||
@@ -31,38 +26,30 @@ describe("checkWorkingDirectory", () => {
|
||||
expect(() =>
|
||||
checkWorkingDirectory("/does/not/exist"),
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
'"Directory /does/not/exist does not exist."',
|
||||
`[Error: Directory /does/not/exist does not exist.]`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("detectPackageManager", () => {
|
||||
test("should return name of package manager for current workspace", () => {
|
||||
expect(detectPackageManager()).toBe("npm");
|
||||
});
|
||||
describe("semverCompare", () => {
|
||||
test.each([
|
||||
["1.2.3", "1.2.3", false],
|
||||
["1.2.2", "1.2.3", true],
|
||||
["2.0.0", "3.0.0", true],
|
||||
["3.1.0", "3.1.1", true],
|
||||
["3.1.0", "3.5.0", true],
|
||||
["3.1.0", "3.10.0", true],
|
||||
["3.1.0", "3.15.0", true],
|
||||
["3.10.0", "3.1.0", false],
|
||||
["3.20.0", "3.2.0", false],
|
||||
["3.1.0", "latest", true],
|
||||
["4.0.0", "latest", true],
|
||||
])(
|
||||
"should semver compare %s vs %s correctly, expecting %s",
|
||||
(version1, version2, expected) => {
|
||||
const isVersion1LessThanVersion2 = semverCompare(version1, version2);
|
||||
|
||||
test("should return npm if package-lock.json exists", () => {
|
||||
expect(detectPackageManager("test/npm")).toBe("npm");
|
||||
});
|
||||
|
||||
test("should return yarn if yarn.lock exists", () => {
|
||||
expect(detectPackageManager("test/yarn")).toBe("yarn");
|
||||
});
|
||||
|
||||
test("should return pnpm if pnpm-lock.yaml exists", () => {
|
||||
expect(detectPackageManager("test/pnpm")).toBe("pnpm");
|
||||
});
|
||||
|
||||
test("should return null if no package manager is detected", () => {
|
||||
expect(detectPackageManager("test/empty")).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
test("isValidPackageManager", () => {
|
||||
expect(isValidPackageManager("npm")).toBe(true);
|
||||
expect(isValidPackageManager("pnpm")).toBe(true);
|
||||
expect(isValidPackageManager("yarn")).toBe(true);
|
||||
|
||||
expect(isValidPackageManager("")).toBe(false);
|
||||
expect(isValidPackageManager("ppnpm")).toBe(false);
|
||||
expect(isVersion1LessThanVersion2).toBe(expected);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
+19
-28
@@ -1,5 +1,8 @@
|
||||
import { existsSync } from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import semverGt from "semver/functions/gt";
|
||||
import { info as originalInfo, error as originalError } from "@actions/core";
|
||||
import { WranglerActionConfig } from "./wranglerAction";
|
||||
|
||||
/**
|
||||
* A helper function to compare two semver versions. If the second arg is greater than the first arg, it returns true.
|
||||
@@ -7,18 +10,7 @@ import * as path from "node:path";
|
||||
export 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;
|
||||
return semverGt(version2, version1);
|
||||
}
|
||||
|
||||
export function checkWorkingDirectory(workingDirectory = ".") {
|
||||
@@ -30,23 +22,22 @@ export function checkWorkingDirectory(workingDirectory = ".") {
|
||||
}
|
||||
}
|
||||
|
||||
export type PackageManager = "npm" | "yarn" | "pnpm";
|
||||
|
||||
export function detectPackageManager(
|
||||
workingDirectory = ".",
|
||||
): PackageManager | null {
|
||||
if (existsSync(path.join(workingDirectory, "package-lock.json"))) {
|
||||
return "npm";
|
||||
export function info(
|
||||
config: WranglerActionConfig,
|
||||
message: string,
|
||||
bypass?: boolean,
|
||||
): void {
|
||||
if (!config.QUIET_MODE || bypass) {
|
||||
originalInfo(message);
|
||||
}
|
||||
if (existsSync(path.join(workingDirectory, "yarn.lock"))) {
|
||||
return "yarn";
|
||||
}
|
||||
if (existsSync(path.join(workingDirectory, "pnpm-lock.yaml"))) {
|
||||
return "pnpm";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function isValidPackageManager(name: string): name is PackageManager {
|
||||
return name === "npm" || name === "yarn" || name === "pnpm";
|
||||
export function error(
|
||||
config: WranglerActionConfig,
|
||||
message: string,
|
||||
bypass?: boolean,
|
||||
): void {
|
||||
if (!config.QUIET_MODE || bypass) {
|
||||
originalError(message);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user