Compare commits

...

60 Commits

Author SHA1 Message Date
Jacob M-G Evans 9641d961b5 Changing publish trigger for build & tagging to released or edit 2023-08-10 17:09:55 -05:00
Jacob M-G Evans 5b3d60c156 Testing Changeset behavior 2023-08-10 16:51:52 -05:00
Jacob M-G Evans 3252711404 hotfix 2023-08-10 16:46:29 -05:00
Jacob M-G Evans 2faabf36a2 Merge pull request #150 from cloudflare/jacobmgevans/changesets-tag-cli
Changesets needs a tag created for release
2023-08-10 16:45:05 -05:00
Jacob M-G Evans b734d85d74 Changesets needs a tag created for release 2023-08-10 16:40:12 -05:00
Jacob M-G Evans 8ca2ff1612 Merge pull request #148 from cloudflare/changeset-release/main
Version Packages
2023-08-10 16:19:21 -05:00
Jacob M-G Evans 7d08a8657e Merge pull request #149 from cloudflare/jacobmgevans/changesets-needs-publish
Spoofing publish for Changeset Action
2023-08-10 16:18:55 -05:00
Jacob M-G Evans e193627f19 Spoofing publish for Changeset Action 2023-08-10 16:17:56 -05:00
github-actions[bot] 55b80c5f62 Version Packages 2023-08-10 21:11:56 +00:00
Jacob M-G Evans f61dc4d5a9 Merge pull request #147 from cloudflare/revert-146-changeset-release/main
Revert "Version Packages"
2023-08-10 16:11:27 -05:00
Jacob M-G Evans 58f274b9f7 Revert "Version Packages" 2023-08-10 16:11:02 -05:00
Jacob M-G Evans ef7686b259 Merge pull request #146 from cloudflare/changeset-release/main
Version Packages
2023-08-10 16:06:17 -05:00
github-actions[bot] d63b9dc486 Version Packages 2023-08-10 21:06:00 +00:00
Jacob M-G Evans 88ccce72e0 Merge pull request #145 from cloudflare/revert-140-changeset-release/main
Revert "Version Packages"
2023-08-10 16:05:37 -05:00
Jacob M-G Evans 554eea134a Revert "Version Packages" 2023-08-10 16:05:14 -05:00
Jacob M-G Evans a584cc5606 Merge pull request #140 from cloudflare/changeset-release/main
Version Packages
2023-08-10 16:00:53 -05:00
github-actions[bot] 0f5076c3e7 Version Packages 2023-08-10 20:55:38 +00:00
Jacob M-G Evans c7d1bd35bf Merge pull request #143 from cloudflare/jacobmgevans/version-syntax-support
Update documentation to include new versioning syntax support
2023-08-10 15:55:12 -05:00
Jacob M-G Evans 3c728e1d5d Update README.md
Co-authored-by: lrapoport-cf <107272160+lrapoport-cf@users.noreply.github.com>
2023-08-10 15:45:08 -05:00
Jacob M-G Evans a333df3c9e Update documentation to include new versioning syntax support 2023-08-10 15:30:29 -05:00
Jacob M-G Evans bb0133dcfc Merge pull request #141 from cloudflare/jacobmgevans/add-more-error-handling
Additional Error Handling
2023-08-10 14:54:16 -05:00
Jacob M-G Evans 88466ea5ae Update .changeset/itchy-buses-grow.md
Co-authored-by: Cina Saffary <itscina@gmail.com>
2023-08-10 14:51:00 -05:00
Jacob M-G Evans 74433eb31e Additional Error Handling
Previously, we prevented any error logs from propagating too far to prevent leaking of any potentially sensitive information. However, this made it difficult for developers to debug their code.

In this release, we have updated our error handling to allow for more error messaging from pre/post and custom commands. We still discourage the use of these commands for secrets or other sensitive information, but we believe this change will make it easier for developers to debug their code.

Relates to #137
2023-08-10 10:11:35 -05:00
Jacob M-G Evans 559dd40fe6 Merge pull request #139 from cloudflare/jacobmgevans/gh-permissions
Another GH permission for GH Token for Changesets
2023-08-09 16:45:52 -05:00
Jacob M-G Evans 9930080b73 Another GH permission for GH Token for Changesets 2023-08-09 16:39:06 -05:00
Jacob M-G Evans 43bbbb16ab Merge pull request #138 from cloudflare/jacobmgevans/changeset-gh-dep
Add missing GH github dep
2023-08-09 15:42:57 -05:00
Jacob M-G Evans 598c6b4043 Add missing GH github dep 2023-08-09 15:38:59 -05:00
Jacob M-G Evans 0c094f5307 Merge pull request #132 from cloudflare/jacobmgevans/changesets
Add Changesets
2023-08-09 15:28:38 -05:00
Jacob M-G Evans 6ea2e616f2 Update .github/workflows/changesets.yml
Co-authored-by: Cina Saffary <itscina@gmail.com>
2023-08-09 15:17:25 -05:00
Jacob M-G Evans 1b4a61cee9 Remove unnecessary context from fetch depth and node_env 2023-08-09 14:50:06 -05:00
Jacob M-G Evans 8e3876a0c9 Update .github/workflows/changesets.yml
Co-authored-by: Cina Saffary <itscina@gmail.com>
2023-08-09 14:43:50 -05:00
Jacob M-G Evans 8fab856f8d Update .github/workflows/changesets.yml
Co-authored-by: Cina Saffary <itscina@gmail.com>
2023-08-09 14:43:40 -05:00
Jacob M-G Evans ce1ea4e7c3 Merge pull request #136 from cloudflare/jacobmgevans/esm-support
Updating build script to convert to .mjs for ESM support
2023-08-09 11:28:16 -05:00
Jacob M-G Evans e420d29d0a Updating build script to convert to .mjs for ESM support 2023-08-09 11:19:52 -05:00
Jacob M-G Evans 311d514d9d Add Changesets 2023-08-08 17:14:09 -05:00
Jacob M-G Evans d05a65f82b Merge pull request #129 from cloudflare/jacobmgevans/README-action-update
Update README with newer version of checkout action
2023-08-08 15:13:50 -05:00
Jacob M-G Evans c9da75b82e Update README with newer version of checkout action 2023-08-08 15:13:05 -05:00
Jacob M-G Evans 29cef5effc Merge pull request #131 from cloudflare/jacobmgevans/action-permissions
Add permissions to Action
2023-08-08 14:51:16 -05:00
Jacob M-G Evans ee60b7bd5e Add permissions to Action 2023-08-08 14:50:15 -05:00
Jacob M-G Evans 0ab3500d54 Merge pull request #128 from cloudflare/jacobmgevans/automate-action-publish
Automate Action Release
2023-08-08 14:14:19 -05:00
Jacob M-G Evans dfa59a861f start script not needed, using Act locally 2023-08-08 13:28:05 -05:00
Jacob M-G Evans 342e6243b7 remove dist & node_modules from repo 2023-08-08 13:21:44 -05:00
Jacob M-G Evans d6590f86f4 Automate Action Release
Utilizing build & tag action to automate the deps and build steps for releasing the Action. Additionally using NCC for the build process to easy compile the deps into a small executable with the JS file.
2023-08-08 13:03:11 -05:00
Jacob M-G Evans 97e54f3396 Merge pull request #127 from cloudflare/lrapoport/add-issues-to-gh-project
Automatically add issues to workers-sdk GH project
2023-08-08 08:35:11 -05:00
lrapoport-cf f85e1acfa7 Add workflow to add issues to GH project 2023-08-07 22:10:59 -04:00
lrapoport-cf e18e1dfc82 Merge pull request #124 from cloudflare/lrapoport/publish-to-deploy
Update publish to deploy
2023-08-07 16:31:50 -04:00
Jacob M-G Evans 20ea506049 Temp fix for deps issue 2023-08-07 15:11:15 -05:00
lrapoport-cf 45c57ae013 Update publish to deploy 2023-08-07 15:57:12 -04:00
Jacob M-G Evans a5fd4fdd34 Merge pull request #121 from cloudflare/jacobmgevans/codeowners
Owners: Wrangler Team
2023-08-07 14:42:13 -05:00
Jacob M-G Evans 002bb083fa Update README.md
Co-authored-by: lrapoport-cf <107272160+lrapoport-cf@users.noreply.github.com>
2023-08-07 14:42:06 -05:00
Jacob M-G Evans 42c609b2d6 included README update 2023-08-07 14:29:10 -05:00
Jacob M-G Evans c8f756bccf Fix Prettier check with /dist 2023-08-07 14:23:56 -05:00
Jacob M-G Evans 81fb6a9681 Owners: Wrangler Team 2023-08-07 14:11:03 -05:00
Jacob M-G Evans 6231e31709 hotfix missing dist 2023-08-07 14:06:55 -05:00
Jacob M-G Evans 0c419bee6c Merge pull request #119 from cloudflare/jacobmgevans/remove-v1-examples
Update README to remove v1 suggestions/examples
2023-08-07 13:30:09 -05:00
Jacob M-G Evans 74a9b9885f Update README to remove v1 suggestions/examples 2023-08-07 13:18:56 -05:00
Jacob M-G Evans 3dd57ff2bb Merge pull request #112 from cloudflare/jacobmgevans/typescript-overhaul
v4 w/ TypeScript Overhaul
2023-08-07 13:08:09 -05:00
Jacob M-G Evans edb2a58814 feat: rewrite Wrangler Action in TypeScript
* Removes dependencies such as Docker, decreasing spin-up time
* Adds community-requested features, including bulk secrets API utilization from Wrangler
* Fixes CI/CD
* Adds testing
* Improves command implementation
* Begins using Node for the Action engine/runner
* Openly discusses all changes with the community
  GitHub Discussions opened and Issues monitored

BREAKING CHANGES:
* Docker is no longer a dependency
* Wrangler v1 is no longer supported

Additional related Internal tickets:
Major Version Default: https://jira.cfdata.org/browse/DEVX-632
Rewrite Project: DEVX-804,802,800,632
2023-08-07 13:05:09 -05:00
Sunil Pai 4c10c1822a Merge pull request #72 from WalshyDev/walshy/pages-996-support-wrangler2
Support wrangler2 - v2
2022-05-09 12:02:45 +01:00
Daniel Walsh 3d1979ca8e Support wrangler2 - v2.0.0 2022-05-09 11:49:03 +01:00
33 changed files with 5433 additions and 434 deletions
+8
View File
@@ -0,0 +1,8 @@
# 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
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
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
+13
View File
@@ -0,0 +1,13 @@
{
"$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
"changelog": [
"@changesets/changelog-github",
{ "repo": "cloudflare/wrangler-action" }
],
"commit": false,
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
+40
View File
@@ -0,0 +1,40 @@
name: Release
on:
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
if: ${{ github.repository_owner == 'cloudflare' }}
name: Release
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
pull-requests: write
issues: read
steps:
- name: Checkout Repo
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "latest"
cache: "npm"
- name: Install modules
run: npm ci
- name: Create Version PR
id: changesets
uses: changesets/action@v1
with:
createGithubReleases: true
publish: npx changeset tag
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+83 -70
View File
@@ -1,91 +1,104 @@
on: push
name: Wrangler Action Self Testing
on:
pull_request:
branches:
- main
jobs:
lint:
wrangler_action_self_testing:
runs-on: ubuntu-latest
name: Lint
steps:
- uses: actions/checkout@v2
- name: Lint shell script
uses: azohra/shell-linter@v0.3.0
with:
path: "entrypoint.sh"
build-only:
runs-on: ubuntu-latest
name: Only build the app
steps:
- uses: actions/checkout@v2
- name: Build app
- name: Checkout Repo
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "latest"
cache: "npm"
- name: Install modules and build
run: npm ci && npm run build
- name: Unit Tests
run: npm run test
- name: Check Formatting
run: npm run check
- name: Only build app
uses: ./
with:
workingDirectory: "./test/base"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
workingDirectory: "test"
publish: false
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"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
environment: dev
secrets: |
SECRET1
SECRET2
preCommands: echo "*** pre commands ***"
postCommands: |
echo "*** post commands ***"
wrangler build
echo "******"
env:
SECRET1: ${{ secrets.SECRET1 }}
SECRET2: ${{ secrets.SECRET2 }}
publish:
runs-on: ubuntu-latest
name: Publish app
steps:
- uses: actions/checkout@v2
- name: Publish app
uses: ./
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
environment: "production"
workingDirectory: 'test'
publish_legacy_credentials:
runs-on: ubuntu-latest
name: Publish app with legacy credentials
steps:
- uses: actions/checkout@v2
- name: Publish app
uses: ./
with:
apiKey: ${{ secrets.CLOUDFLARE_API_KEY }}
email: ${{ secrets.CLOUDFLARE_EMAIL }}
environment: "production"
workingDirectory: 'test'
publish_hardcoded_wrangler_version:
runs-on: ubuntu-latest
name: Publish app with hardcoded Wrangler version
steps:
- uses: actions/checkout@v2
- name: Publish app
uses: ./
with:
apiKey: ${{ secrets.CLOUDFLARE_API_KEY }}
email: ${{ secrets.CLOUDFLARE_EMAIL }}
environment: "production"
wranglerVersion: '1.5.0'
workingDirectory: 'test'
publish_secrets:
runs-on: ubuntu-latest
name: Publish app with secrets
steps:
- uses: actions/checkout@v2
- name: Publish app
- name: Clean up Deployed Environment Worker
uses: ./
with:
workingDirectory: "./test/base"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
environment: "production"
workingDirectory: "test"
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"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
secrets: |
SECRET1
SECRET2
preCommands: echo "*** pre command ***"
postCommands: |
echo "*** post commands ***"
echo "******"
env:
SECRET1: ${{ secrets.SECRET1 }}
SECRET2: ${{ secrets.SECRET2 }}
SECRET2: ${{ secrets.SECRET2 }}
- name: Health Check Deployed Worker
run: node .github/workflows/workerHealthCheck.cjs
shell: bash
- name: Deploy app secrets w/ default version
uses: ./
with:
workingDirectory: "./test/base"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
secrets: |
SECRET1
SECRET2
env:
SECRET1: ${{ secrets.SECRET1 }}
SECRET2: ${{ secrets.SECRET2 }}
- name: Health Check Deployed Worker
run: node .github/workflows/workerHealthCheck.cjs
shell: bash
- name: Clean Up Deployed Workers
uses: ./
with:
workingDirectory: "./test/base"
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: delete --name wrangler-action-test --force
# END Setup and teardown of Workers w/ Secrets Tests
+16
View File
@@ -0,0 +1,16 @@
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 }}
+30
View File
@@ -0,0 +1,30 @@
name: Publish
permissions:
contents: write
on:
release:
types: [released, edited]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.release.tag_name }}
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "latest"
cache: "npm"
- name: Install modules and build
run: npm ci && npm run build
- uses: JasonEtco/build-and-tag-action@v2
env:
GITHUB_TOKEN: ${{ github.token }}
+18
View File
@@ -0,0 +1,18 @@
const { execSync } = require("child_process");
function workerHealthCheck() {
const url =
"https://wrangler-action-test.devprod-testing7928.workers.dev/secret-health-check";
const buffer = execSync(`curl ${url}`);
const response = buffer.toString();
response.includes("OK")
? console.log(`Status: Worker is up! Secrets: ${response}`)
: console.log(`Worker is down!`);
return response;
}
workerHealthCheck();
+95
View File
@@ -0,0 +1,95 @@
dist
.idea
.vscode
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Node ###
node_modules
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Moved from ./templates for ignoring all locks in templates
templates/**/*-lock.*
templates/**/*.lock
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
+6
View File
@@ -0,0 +1,6 @@
{
"printWidth": 80,
"singleQuote": false,
"semi": true,
"useTabs": true
}
+74
View File
@@ -0,0 +1,74 @@
# Changelog
## 3.0.2
### Patch Changes
- [#147](https://github.com/cloudflare/wrangler-action/pull/147) [`58f274b`](https://github.com/cloudflare/wrangler-action/commit/58f274b9f70867447519c6fa983c813e2b167b85) Thanks [@JacobMGEvans](https://github.com/JacobMGEvans)! - Added more error logging when a command fails to execute
Previously, we prevented any error logs from propagating too far to prevent leaking of any potentially sensitive information. However, this made it difficult for developers to debug their code.
In this release, we have updated our error handling to allow for more error messaging from pre/post and custom commands. We still discourage the use of these commands for secrets or other sensitive information, but we believe this change will make it easier for developers to debug their code.
Relates to #137
- [#147](https://github.com/cloudflare/wrangler-action/pull/147) [`58f274b`](https://github.com/cloudflare/wrangler-action/commit/58f274b9f70867447519c6fa983c813e2b167b85) Thanks [@JacobMGEvans](https://github.com/JacobMGEvans)! - Adding Changesets
- [Version 3.0.0](#version-300)
- [Version 2.0.0](#version-200)
## Version 3.0.0 (Breaking update)
### Additions
- **Rewritten Wrangler Action in TypeScript.**
- Bulk secrets API utilization from Wrangler.
- Added testing for improved reliability.
- Implemented multiline support for the `command` input to allow running multiple Wrangler commands.
- Now using Node for the Action engine/runner.
- Open discussions with the community on all changes through GitHub Discussions and monitored Issues.
### Removals
- Removed Docker as a dependency.
- Dropped support for Wrangler v1.
### Changes
- Fixed CI/CD issues.
### Breaking changes
- Wrangler v1 is no longer supported.
- Please update to the latest version of Wrangler.
- Updated default version of Wrangler to v3.4.0
### Additional Notes
- Major Version Default: [DEVX-632](https://jira.cfdata.org/browse/DEVX-632)
- Rewrite Project Tickets: [DEVX-804](https://jira.cfdata.org/browse/DEVX-804), [DEVX-802](https://jira.cfdata.org/browse/DEVX-802), [DEVX-800](https://jira.cfdata.org/browse/DEVX-800), [DEVX-632](https://jira.cfdata.org/browse/DEVX-632)
---
## Version 2.0.0 (Breaking update)
### Additions
- New `command` input
- This allows you to specify the Wrangler command you would like to run.
For example, if you want to publish the production version of your Worker you may run `publish --env=production`.
- This opens up other possibilities too like publishing a Pages project: `pages publish <directory> --project-name=<name>`.
- New `accountId` input
- This allows you to specify your account ID.
### Removals
- Removed `publish` input (refer to [Breaking changes](#breaking-changes)).
### Changes
-- no changes --
### Breaking changes
- `publish` has been removed.
- You should instead do `command:
+1
View File
@@ -0,0 +1 @@
* @cloudflare/wrangler
-5
View File
@@ -1,5 +0,0 @@
FROM node:16
ENV XDG_CONFIG_HOME /github/workspace
ENV WRANGLER_HOME /github/workspace
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
+83 -83
View File
@@ -1,10 +1,18 @@
# Wrangler GitHub Action
✨ Zero-config [Cloudflare Workers](https://workers.cloudflare.com) deployment using [Wrangler](https://github.com/cloudflare/wrangler) and [GitHub Actions](https://github.com/actions)
Easy-to-use GitHub Action to use [Wrangler](https://developers.cloudflare.com/workers/cli-wrangler/). Makes deploying Workers a breeze.
## Big Changes in v3
- Wrangler v1 is no longer supported.
- Global API key & Email Auth no longer supported
- Action version syntax is newly supported. This means e.g. `uses: cloudflare/wrangler-action@v3` and `uses: cloudflare/wrangler-action@v3.x` are both now valid syntax. Previously supported syntax e.g. `uses: cloudflare/wrangler-action@3.x.x` continues to be supported.
[Refer to Changelog for more information](CHANGELOG.md).
## Usage
Add `wrangler-action` to the workflow for your Workers application. The below example will publish your application on pushes to the `master` branch:
Add `wrangler-action` to the workflow for your Workers/Pages application. The below example will deploy a Worker on a `git push` to the `main` branch:
```yaml
name: Deploy
@@ -12,16 +20,16 @@ name: Deploy
on:
push:
branches:
- master
- main
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@v2
- name: Publish
uses: cloudflare/wrangler-action@1.3.0
- uses: actions/checkout@v3
- name: Deploy
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
```
@@ -37,48 +45,23 @@ jobs:
deploy:
name: Deploy
steps:
uses: cloudflare/wrangler-action@1.3.0
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
```
`wrangler-action` also supports using your [global API key and email](https://developers.cloudflare.com/workers/quickstart/#global-api-key) as an authentication method, although API tokens are preferred. Pass in `apiKey` and `email` to the GitHub Action to use this method:
```yaml
jobs:
deploy:
name: Deploy
steps:
uses: cloudflare/wrangler-action@1.3.0
with:
apiKey: ${{ secrets.CF_API_KEY }}
email: ${{ secrets.CF_EMAIL }}
```
## Configuration
If you're using Wrangler's [environments](https://developers.cloudflare.com/workers/tooling/wrangler/configuration/environments/) feature, you can customize _where_ the action deploys to by passing an `environment` in the `with` block of your workflow:
If you need to install a specific version of Wrangler to use for deployment, you can also pass the input `wranglerVersion` to install a specific version of Wrangler from NPM. This should be a [SemVer](https://semver.org/)-style version number, such as `2.20.0`:
```yaml
jobs:
deploy:
steps:
uses: cloudflare/wrangler-action@1.3.0
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
environment: 'production'
```
If you need to install a specific version of Wrangler to use for deployment, you can also pass the input `wranglerVersion` to install a specific version of Wrangler from NPM. This should be a [SemVer](https://semver.org/)-style version number, such as `1.6.0`:
```yaml
jobs:
deploy:
steps:
uses: cloudflare/wrangler-action@1.3.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
wranglerVersion: '1.6.0'
wranglerVersion: "2.20.0"
```
Optionally, you can also pass a `workingDirectory` key to the action. This will allow you to specify a subdirectory of the repo to run the Wrangler command from.
@@ -87,36 +70,36 @@ Optionally, you can also pass a `workingDirectory` key to the action. This will
jobs:
deploy:
steps:
uses: cloudflare/wrangler-action@1.3.0
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
workingDirectory: 'subfoldername'
workingDirectory: "subfoldername"
```
[Worker secrets](https://developers.cloudflare.com/workers/tooling/wrangler/secrets/) can be optionally passed as a new line deliminated string of names in `secrets`. Each secret name must match an environment variable name specified in the `env` attribute. 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.
```yaml
jobs:
deploy:
steps:
uses: cloudflare/wrangler-action@1.3.0
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
secrets: |
SECRET1
SECRET2
SECRET1
SECRET2
env:
SECRET1: ${{ secrets.SECRET1 }}
SECRET2: ${{ secrets.SECRET2 }}
```
If you need to run additional shell commands before or after `wrangler publish`, you can specify them as input to `preCommands` (before publish) or `postCommands` (after publish). These can include additional `wrangler` commands (i.e. `build`, `kv:key put`) or any other commands available inside the `wrangler-action` context.
If you need to run additional shell commands before or after your command, you can specify them as input to `preCommands` (before `deploy`) or `postCommands` (after `deploy`). These can include additional `wrangler` commands (that is, `whoami`, `kv:key put`) or any other commands available inside the `wrangler-action` context.
```yaml
jobs:
deploy:
steps:
uses: cloudflare/wrangler-action@1.3.0
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
preCommands: echo "*** pre command ***"
@@ -126,120 +109,137 @@ jobs:
echo "******"
```
Set the optional `publish` input to false to skip publishing your Worker project and secrets. Useful in conjunction with pre and post commands. For example, if you only wanted to run `wrangler build` against your project:
You can use the `command` option to do specific actions such as running `wrangler whoami` against your project:
```yaml
jobs:
deploy:
steps:
uses: cloudflare/wrangler-action@1.3.0
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
publish: false
preCommands: wrangler build
command: whoami
```
## Use cases
### Deploying when commits are merged to master
### Deploy when commits are merged to main
The above workflow examples have already shown how to run `wrangler-action` when new commits are merged to the master branch. For most developers, this workflow will easily replace manual deploys and be a great first integration step with `wrangler-action`:
The above workflow examples have already shown how to run `wrangler-action` when new commits are merged to the main branch. For most developers, this workflow will easily replace manual deploys and be a great first integration step with `wrangler-action`:
```yaml
on:
push:
branches:
- master
- main
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@master
- name: Publish
uses: cloudflare/wrangler-action@1.3.0
- uses: actions/checkout@v3
- name: Deploy
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_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, check out the [GitHub Actions documentation](https://help.github.com/en/articles/workflow-syntax-for-github-actions#on).
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).
### Deploying on a schedule
### Deploy your Pages site (production & preview)
If you'd like to deploy your Workers application on a recurring basis for instance, every hour, or daily the `schedule` trigger allows you to use cron syntax to define a workflow schedule. The below example will deploy at the beginning of every hour:
If you want to deploy your Pages project with GitHub Actions rather than the built-in continous integration (CI), then this is a great way to do it. Wrangler 2 will populate the commit message and branch for you. You only need to pass the project name. If a push to a non-production branch is done, it will deploy as a preview deployment:
```yaml
on:
schedule:
- cron: '0 * * * *'
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@master
- name: Publish app
uses: cloudflare/wrangler-action@1.3.0
- uses: actions/checkout@v3
- name: Deploy
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}
command: pages deploy --project-name=example
```
### Deploying on a schedule
If you would like to deploy your Workers application on a recurring basis for example, every hour, or daily the `schedule` trigger allows you to use cron syntax to define a workflow schedule. The below example will deploy at the beginning of every hour:
```yaml
on:
schedule:
- cron: "0 * * * *"
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@v3
- name: Deploy app
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_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.
### Deploying on a "dispatched" event
### Manually triggering a deployment
If you need to trigger a workflow at-will, you can use GitHub's `workflow_dispatch` [event](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) in your workflow file. By setting your workflow to trigger on that event, you'll be able to deploy your application via the GitHub UI. The UI also accepts inputs that can be used to configure the action :
If you need to trigger a workflow at-will, you can use GitHub's `workflow_dispatch` [event](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) in your workflow file. By setting your workflow to trigger on that event, you will be able to deploy your application via the GitHub UI. The UI also accepts inputs that can be used to configure the action:
```yaml
on:
workflow_dispatch:
inputs:
environment:
description: 'Choose an environment to deploy to: <dev|staging|prod>'
description: "Choose an environment to deploy to: <dev|staging|prod>"
required: true
default: 'dev'
default: "dev"
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@master
- name: Publish app
uses: cloudflare/wrangler-action@1.3.0
- uses: actions/checkout@v3
- name: Deploy app
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
environment: ${{ github.event.inputs.environment }}
command: deploy --env ${{ github.event.inputs.environment }}
```
For more advanced usage or to programmatically trigger the workflow from scripts, check out [the docs](https://docs.github.com/en/rest/reference/actions#create-a-workflow-dispatch-event) for making API calls
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.
## Troubleshooting
This action is in beta, and I'm looking for folks to use it! If something goes wrong, please file an issue! That being said, there's a couple things you should know:
### "I just started using Workers/Wrangler and I don't know what this is!"
No problem! Check out the [Quick Start guide](https://developers.cloudflare.com/workers/quickstart) in our docs to get started. Once you have a Workers application, you may want to set it up to automatically deploy from GitHub whenever you change your project. That's where this action comes in - nice!
Refer to the [Quick Start guide](https://developers.cloudflare.com/workers/quickstart) to get started. Once you have a Workers application, you may want to set it up to automatically deploy from GitHub whenever you change your project.
### "I'm trying to deploy my static site but it isn't working!"
### "[ERROR] No account id found, quitting.."
To deploy static sites and frontend applications to Workers, check out the documentation for [Workers Sites](https://developers.cloudflare.com/workers/sites).
Note that this action makes no assumptions about _how_ your project is built! **If you need to run a pre-publish step, like building your application, you need to specify a build step in your Workflow.** For instance, if I have an NPM command called `build`, my workflow YAML might resemble the following:
You will need to add `account_id = ""` in your `wrangler.toml` file or set `accountId` in this GitHub Action.
```yaml
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@master
- name: Build site
run: 'npm run build'
- name: Publish
uses: cloudflare/wrangler-action@1.3.0
- uses: actions/checkout@v3
- name: Deploy app
uses: cloudflare/wrangler-action@3.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}
```
+21 -15
View File
@@ -2,32 +2,38 @@ name: "Deploy to Cloudflare Workers with Wrangler"
branding:
icon: "upload-cloud"
color: "orange"
description: "Deploy your Cloudflare Workers applications and sites directly from GitHub, using Wrangler"
description: "Deploy your Cloudflare projects from GitHub using Wrangler"
runs:
using: "docker"
image: "Dockerfile"
using: "node16"
main: "dist/index.mjs"
inputs:
apiKey:
description: "(Legacy) Your Cloudflare API Key"
apiToken:
description: "Your Cloudflare API Token"
email:
description: "(Legacy) Your Cloudflare Email"
required: false
accountId:
description: "Your Cloudflare Account ID"
required: false
environment:
description: "The environment you'd like to publish your Workers project to - must be defined in wrangler.toml"
description: "The environment you'd like to deploy your Workers project to - must be defined in wrangler.toml"
workingDirectory:
description: "The relative path which Wrangler commands should be run from"
required: false
wranglerVersion:
description: "The version of Wrangler you'd like to use to publish your Workers project"
description: "The version of Wrangler you'd like to use to deploy your Workers project"
required: false
secrets:
description: "A new line deliminated string of environment variable names that should be configured as Worker secrets"
description: "A string of environment variable names, separated by newlines. These will be bound to your Worker as Secrets and must match the names of environment variables declared in `env` of this workflow."
required: false
preCommands:
description: "Commands to execute before publishing the Workers project"
description: "Commands to execute before deploying the Workers project"
required: false
postCommands:
description: "Commands to execute after publishing the Workers project"
description: "Commands to execute after deploying the Workers project"
required: false
command:
description: 'The Wrangler command (along with any arguments) you wish to run. Multiple Wrangler commands can be run by separating each command with a newline. Defaults to `"deploy"`.'
required: false
vars:
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
publish:
description: "Set to false to skip publishing your Worker project and secrets. Defaults to true."
required: false
-122
View File
@@ -1,122 +0,0 @@
#!/bin/bash
set -e
export HOME="/github/workspace"
export WRANGLER_HOME="/github/workspace"
mkdir -p "$HOME/.wrangler"
chmod -R 770 "$HOME/.wrangler"
export API_CREDENTIALS=""
# Used to execute any specified pre and post commands
execute_commands() {
COMMANDS=$1
while IFS= read -r COMMAND; do
CHUNKS=()
for CHUNK in $COMMAND; do
CHUNKS+=("$CHUNK")
done
eval "${CHUNKS[@]}"
CHUNKS=()
done <<< "$COMMANDS"
}
secret_not_found() {
echo "::error::Specified secret \"$1\" not found in environment variables."
exit 1
}
# If an API token is detected as input
if [ -n "$INPUT_APITOKEN" ]
then
export CF_API_TOKEN="$INPUT_APITOKEN"
export API_CREDENTIALS="API Token"
fi
# If an API key and email are detected as input
if [ -n "$INPUT_APIKEY" ] && [ -n "$INPUT_EMAIL" ]
then
export CF_EMAIL="$INPUT_EMAIL"
export CF_API_KEY="$INPUT_APIKEY"
export API_CREDENTIALS="Email and API Key"
fi
if [ -n "$INPUT_APIKEY" ] && [ -z "$INPUT_EMAIL" ]
then
echo "Provided an API key without an email for authentication. Please pass in 'apiKey' and 'email' to the action."
fi
if [ -z "$INPUT_APIKEY" ] && [ -n "$INPUT_EMAIL" ]
then
echo "Provided an email without an API key for authentication. Please pass in 'apiKey' and 'email' to the action."
exit 1
fi
if [ -z "$API_CREDENTIALS" ]
then
>&2 echo "Unable to find authentication details. Please pass in an 'apiToken' as an input to the action, or a legacy 'apiKey' and 'email'."
exit 1
else
echo "Using $API_CREDENTIALS authentication"
fi
# If a Wrangler version is detected as input
if [ -z "$INPUT_WRANGLERVERSION" ]
then
npm i @cloudflare/wrangler -g
else
npm i "@cloudflare/wrangler@$INPUT_WRANGLERVERSION" -g
fi
# If a working directory is detected as input
if [ -n "$INPUT_WORKINGDIRECTORY" ]
then
cd "$INPUT_WORKINGDIRECTORY"
fi
# If precommands is detected as input
if [ -n "$INPUT_PRECOMMANDS" ]
then
execute_commands "$INPUT_PRECOMMANDS"
fi
# If an environment is detected as input, for each secret specified get the value of
# the matching named environment variable then configure using wrangler secret put.
# Skip if publish is set to false.
if [ "$INPUT_PUBLISH" != "false" ]
then
if [ -z "$INPUT_ENVIRONMENT" ]
then
wrangler publish
for SECRET in $INPUT_SECRETS; do
VALUE=$(printenv "$SECRET") || secret_not_found "$SECRET"
echo "$VALUE" | wrangler secret put "$SECRET"
done
else
wrangler publish -e "$INPUT_ENVIRONMENT"
for SECRET in $INPUT_SECRETS; do
VALUE=$(printenv "$SECRET") || secret_not_found "$SECRET"
echo "$VALUE" | wrangler secret put "$SECRET" --env "$INPUT_ENVIRONMENT"
done
fi
fi
# If postcommands is detected as input
if [ -n "$INPUT_POSTCOMMANDS" ]
then
execute_commands "$INPUT_POSTCOMMANDS"
fi
# If a working directory is detected as input, revert to the
# original directory before continuing with the workflow
if [ -n "$INPUT_WORKINGDIRECTORY" ]
then
cd $HOME
fi
+4457
View File
File diff suppressed because it is too large Load Diff
+44
View File
@@ -0,0 +1,44 @@
{
"name": "wrangler-action",
"version": "3.0.2",
"description": "GitHub Action to use [Wrangler](https://developers.cloudflare.com/workers/cli-wrangler/).",
"author": "wrangler@cloudflare.com",
"license": "MIT OR Apache-2.0",
"bugs": {
"url": "https://github.com/cloudflare/wrangler-action/issues"
},
"homepage": "https://github.com/cloudflare/wrangler-action#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/cloudflare/wrangler-action.git"
},
"keywords": [
"script",
"cli",
"serverless",
"cloudflare",
"cloudflare-workers",
"typescript"
],
"type": "module",
"main": "dist/index.mjs",
"scripts": {
"build": "npx ncc build ./src/index.ts && mv ./dist/index.js ./dist/index.mjs",
"test": "vitest",
"format": "prettier --write . --ignore-path ./dist/**",
"check": "prettier --check . --ignore-path ./dist/**"
},
"dependencies": {
"@actions/core": "^1.10.0"
},
"devDependencies": {
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.2",
"@cloudflare/workers-types": "^4.20230710.1",
"@types/node": "^20.4.2",
"@vercel/ncc": "^0.36.1",
"prettier": "^3.0.0",
"typescript": "^5.1.6",
"vitest": "^0.33.0"
}
}
+64
View File
@@ -0,0 +1,64 @@
import { expect, test, describe } from "vitest";
import { checkWorkingDirectory, getNpxCmd, semverCompare } from "./index";
import path from "node:path";
const config = {
WRANGLER_VERSION: "mockVersion",
secrets: ["mockSercret", "mockSecretAgain"],
workingDirectory: "./mockWorkingDirectory",
CLOUDFLARE_API_TOKEN: "mockAPIToken",
CLOUDFLARE_ACCOUNT_ID: "mockAccountID",
ENVIRONMENT: undefined,
VARS: ["mockVar", "mockVarAgain"],
COMMANDS: ["mockCommand", "mockCommandAgain"],
};
test("getNpxCmd ", async () => {
process.env.RUNNER_OS = "Windows";
expect(getNpxCmd()).toBe("npx.cmd");
process.env.RUNNER_OS = "Mac";
expect(getNpxCmd()).toBe("npx");
process.env.RUNNER_OS = "Linux";
expect(getNpxCmd()).toBe("npx");
delete process.env.RUNNER_OS;
});
describe("semverCompare", () => {
test("should return false if the second argument is equal to the first argument", () => {
const isVersion1LessThanVersion2 = semverCompare("1.2.3", "1.2.3");
expect(isVersion1LessThanVersion2).toBe(false);
});
test("should return true if the first argument is less than the second argument", () => {
const isVersion1LessThanVersion2 = semverCompare("1.2.2", "1.2.3");
expect(isVersion1LessThanVersion2).toBe(true);
});
});
describe("checkWorkingDirectory", () => {
test("should return the normalized path if the directory exists", () => {
const normalizedPath = checkWorkingDirectory(".");
expect(normalizedPath).toBe(path.normalize("."));
});
test("should fail if the directory does not exist", () => {
try {
checkWorkingDirectory("/does/not/exist");
} catch (error) {
expect(error.message).toMatchInlineSnapshot();
}
});
test("should fail if an error occurs while checking/creating the directory", () => {
try {
checkWorkingDirectory("/does/not/exist");
} catch (error) {
expect(error.message).toMatchInlineSnapshot();
}
});
});
Executable
+294
View File
@@ -0,0 +1,294 @@
import {
getInput,
getMultilineInput,
info,
setFailed,
endGroup,
startGroup,
error,
} from "@actions/core";
import { execSync, exec } from "node:child_process";
import { existsSync } from "node:fs";
import * as path from "node:path";
import * as util from "node:util";
const execAsync = util.promisify(exec);
const DEFAULT_WRANGLER_VERSION = "3.4.0";
/**
* A configuration object that contains all the inputs & immutable state for the action.
*/
const config = {
WRANGLER_VERSION: getInput("wranglerVersion") || DEFAULT_WRANGLER_VERSION,
secrets: getMultilineInput("secrets"),
workingDirectory: checkWorkingDirectory(getInput("workingDirectory")),
CLOUDFLARE_API_TOKEN: getInput("apiToken"),
CLOUDFLARE_ACCOUNT_ID: getInput("accountId"),
ENVIRONMENT: getInput("environment"),
VARS: getMultilineInput("vars"),
COMMANDS: getMultilineInput("command"),
} as const;
function getNpxCmd() {
return process.env.RUNNER_OS === "Windows" ? "npx.cmd" : "npx";
}
/**
* A helper function to compare two semver versions. If the second arg is greater than the first arg, it returns true.
*/
function semverCompare(version1: string, version2: string) {
if (version2 === "latest") return true;
const version1Parts = version1.split(".");
const version2Parts = version2.split(".");
for (const version1Part of version1Parts) {
const version2Part = version2Parts.shift();
if (version1Part !== version2Part && version2Part) {
return version1Part < version2Part ? true : false;
}
}
return false;
}
async function main() {
installWrangler();
authenticationSetup();
await execCommands(getMultilineInput("preCommands"), "pre");
await uploadSecrets();
await wranglerCommands();
await execCommands(getMultilineInput("postCommands"), "post");
}
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());
return result;
} catch (err: any) {
err.stdout && info(err.stdout.toString());
err.stderr && error(err.stderr.toString());
throw err;
}
}
function checkWorkingDirectory(workingDirectory = ".") {
try {
const normalizedPath = path.normalize(workingDirectory);
if (existsSync(normalizedPath)) {
return normalizedPath;
} else {
setFailed(`🚨 Directory ${workingDirectory} does not exist.`);
}
} catch (error) {
setFailed(
`🚨 While checking/creating directory ${workingDirectory} received ${error}`,
);
}
}
function installWrangler() {
if (config["WRANGLER_VERSION"].startsWith("1")) {
setFailed(
`🚨 Wrangler v1 is no longer supported by this action. Please use major version 2 or greater`,
);
}
startGroup("📥 Installing Wrangler");
const command = `npm install wrangler@${config["WRANGLER_VERSION"]}`;
info(`Running command: ${command}`);
execSync(command, { cwd: config["workingDirectory"], env: process.env });
info(`✅ Wrangler installed`);
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`);
const arrPromises = commands.map(async (command) => {
const cmd = command.startsWith("wrangler")
? `${getNpxCmd()} ${command}`
: command;
info(`🚀 Executing command: ${cmd}`);
return await runProcess(cmd, {
cwd: config["workingDirectory"],
env: process.env,
});
});
await Promise.all(arrPromises).catch((result) => {
result.stdout && info(result.stdout.toString());
result.stderr && error(result.stderr.toString());
setFailed(`🚨 ${cmdType}Commands failed`);
});
endGroup();
}
/**
* A helper function to get the secret from the environment variables.
*/
function getSecret(secret: string) {
if (!secret) {
setFailed("No secret provided");
}
const value = process.env[secret];
if (!value) {
setFailed(`Secret ${secret} not found`);
}
return value;
}
async function legacyUploadSecrets(
secrets: string[],
environment?: string,
workingDirectory?: string,
) {
try {
const arrPromises = secrets
.map((secret) => {
const command = `echo ${getSecret(
secret,
)} | ${getNpxCmd()} wrangler secret put ${secret}`;
return environment ? command.concat(` --env ${environment}`) : command;
})
.map(
async (command) =>
await execAsync(command, {
cwd: workingDirectory,
env: process.env,
}),
);
await Promise.all(arrPromises);
} catch {
setFailed(`🚨 Error uploading secrets`);
}
}
async function uploadSecrets() {
const secrets: string[] = config["secrets"];
const environment = config["ENVIRONMENT"];
const workingDirectory = config["workingDirectory"];
if (!secrets.length) {
return;
}
try {
startGroup("🔑 Uploading Secrets");
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(
'"',
'\\"',
)}" | ${getNpxCmd()} wrangler secret:bulk ${environmentSuffix}`;
execSync(secretCmd, {
cwd: workingDirectory,
env: process.env,
stdio: "ignore",
});
info(`✅ Uploaded secrets`);
} catch {
setFailed(`🚨 Error uploading 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 {
setFailed(`🚨 ${envVar} not found in variables.`);
}
});
return envVarArray.length > 0 ? `--var ${envVarArray.join(" ").trim()}` : "";
}
async function wranglerCommands() {
startGroup("🚀 Running Wrangler Commands");
const commands = config["COMMANDS"];
const environment = config["ENVIRONMENT"];
if (!commands.length) {
const wranglerVersion = config["WRANGLER_VERSION"];
const deployCommand = semverCompare("2.20.0", wranglerVersion)
? "deploy"
: "publish";
commands.push(deployCommand);
}
const arrPromises = commands.map(async (command) => {
if (environment.length > 0 && !command.includes(`--env`)) {
command = command.concat(` --env ${environment}`);
}
const cmd = `${getNpxCmd()} 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).catch((result) => {
result.stdout && info(result.stdout.toString());
result.stderr && error(result.stderr.toString());
setFailed(`🚨 Command failed`);
});
endGroup();
}
main().catch(() => setFailed("🚨 Action failed"));
export {
wranglerCommands,
execCommands,
uploadSecrets,
authenticationSetup,
installWrangler,
checkWorkingDirectory,
getNpxCmd,
semverCompare,
};
-1
View File
@@ -1 +0,0 @@
dist
+26
View File
@@ -0,0 +1,26 @@
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");
}
// @ts-expect-error
return Response.json({
...request,
headers: Object.fromEntries(request.headers),
});
},
};
+3
View File
@@ -0,0 +1,3 @@
{
"name": "wrangler-action-test"
}
+4
View File
@@ -0,0 +1,4 @@
name = "wrangler-action-test"
main = "./index.ts"
compatibility_date = "2023-07-07"
workers_dev = true
+21
View File
@@ -0,0 +1,21 @@
type Env = {
SECRET1?: string;
SECRET2?: string;
};
export default {
fetch(request: Request, env: Env) {
const url = new URL(request.url);
if (url.pathname === "/secret") {
const { SECRET1 = "", SECRET2 = "" } = env;
return new Response(`${SECRET1} ${SECRET2}`);
}
// @ts-expect-error
return Response.json({
...request,
headers: Object.fromEntries(request.headers),
});
},
};
+3
View File
@@ -0,0 +1,3 @@
{
"name": "wrangler-action-environment-test"
}
+9
View File
@@ -0,0 +1,9 @@
name = "wrangler-action-environment-test"
main = "./index.ts"
compatibility_date = "2023-07-07"
workers_dev = true
[env.dev]
name = "wrangler-action-dev-environment-test"
[env.dev.vars]
DEV_VAR = "example_production_token"
-6
View File
@@ -1,6 +0,0 @@
<h1>My Static Site Test</h1>
<p>This is the content of my site</p>
<footer>
And this is my footer
</footer>
View File
-88
View File
@@ -1,88 +0,0 @@
import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler'
/**
* The DEBUG flag will do two things that help during development:
* 1. we will skip caching on the edge, which makes it easier to
* debug.
* 2. we will return an error message on exception in your response rather
* than the default 404.html page.
*/
const DEBUG = false
addEventListener('fetch', event => {
try {
event.respondWith(handleEvent(event))
} catch (e) {
if (DEBUG) {
return event.respondWith(
new Response(e.message || e.toString(), {
status: 500,
}),
)
}
event.respondWith(new Response('Internal Error', { status: 500 }))
}
})
async function handleEvent(event) {
const url = new URL(event.request.url)
let options = {}
/**
* You can add custom logic to how we fetch your assets
* by configuring the function `mapRequestToAsset`
*/
// options.mapRequestToAsset = handlePrefix(/^\/docs/)
// Path to test secrets passed through Wrangler Action. Create SECRET1 and SECRET2 secrets
// in the Action repo to something innocuous like "Hello" and "World!".
if (url.pathname === "/secret") {
let sec1 = (typeof SECRET1 !== 'undefined') ? SECRET1 : ""
let sec2 = (typeof SECRET2 !== 'undefined') ? SECRET2 : ""
return new Response(`${sec1} ${sec2}`)
}
try {
if (DEBUG) {
// customize caching
options.cacheControl = {
bypassCache: true,
}
}
return await getAssetFromKV(event, options)
} catch (e) {
// if an error is thrown try to serve the asset at 404.html
if (!DEBUG) {
try {
let notFoundResponse = await getAssetFromKV(event, {
mapRequestToAsset: req => new Request(`${new URL(req.url).origin}/404.html`, req),
})
return new Response(notFoundResponse.body, { ...notFoundResponse, status: 404 })
} catch (e) {}
}
return new Response(e.message || e.toString(), { status: 500 })
}
}
/**
* Here's one example of how to modify a request to
* remove a specific prefix, in this case `/docs` from
* the url. This can be useful if you are deploying to a
* route on a zone, or if you only want your static content
* to exist at a specific path.
*/
function handlePrefix(prefix) {
return request => {
// compute the default (e.g. / -> index.html)
let defaultAssetKey = mapRequestToAsset(request)
let url = new URL(defaultAssetKey.url)
// strip the prefix from the path for lookup
url.pathname = url.pathname.replace(prefix, '/')
// inherit all other props from the default request
return new Request(url.toString(), defaultAssetKey)
}
}
-21
View File
@@ -1,21 +0,0 @@
{
"name": "worker",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@cloudflare/kv-asset-handler": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.0.5.tgz",
"integrity": "sha512-7yLMAUZD1XQNKzmktYCcUUPB+wXmQENv1MMi8QEMs0rzL01e0XEyCUUDauRXHzxi7dBbSUGA5RS23h890ncKog==",
"requires": {
"mime": "^2.4.4"
}
},
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
}
}
}
-12
View File
@@ -1,12 +0,0 @@
{
"private": true,
"name": "worker",
"version": "1.0.0",
"description": "A template for kick starting a Cloudflare Workers project",
"main": "index.js",
"author": "Ashley Lewis <ashleymichal@gmail.com>",
"license": "MIT",
"dependencies": {
"@cloudflare/kv-asset-handler": "^0.0.5"
}
}
-11
View File
@@ -1,11 +0,0 @@
name = "static-test"
type = "webpack"
workers_dev = true
account_id = "dc56444c4c955a1653106ccf997c1067"
[env.production]
name = "static-test-prod"
[site]
bucket = "./public"
entry-point = "workers-site"
+20
View File
@@ -0,0 +1,20 @@
{
"files": ["./src/index.ts"],
"compilerOptions": {
"strict": true,
"composite": true,
"incremental": true,
"esModuleInterop": true,
"skipLibCheck": true,
"isolatedModules": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "NodeNext",
"rootDir": "./src",
"outDir": "./dist",
"lib": ["ESNext"],
"types": ["node", "@cloudflare/workers-types"]
},
"exclude": ["node_modules", "**/*.test.ts"],
"include": ["src/index.ts"]
}