Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Aetherinox/cloudflare-publish-action

Github action for publishing to Cloudflare pages.
https://github.com/Aetherinox/cloudflare-publish-action

actions cloudflare cloudflare-pages

Last synced: 3 months ago
JSON representation

Github action for publishing to Cloudflare pages.

Awesome Lists containing this project

README

        


Cloudflare Pages ☁️ Github Action




A forked copy of the Github action [Cloudflare Pages](https://github.com/cloudflare/pages-action) which is updated to utilize NodeJS 20+ and continues updates.


[![Test Status][badge-tests]][link-tests]
[![Last Commit][badge-commit]][badge-commit]
[![Size][badge-size-gh]][badge-size-gh]
[![All Contributors][badge-all-contributors]](#contributors-)

---


- [About](#about)
- [Usage](#usage)
- [Get Account ID](#get-account-id)
- [Generate an API Token](#generate-an-api-token)
- [Define Branch](#define-branch)
- [Define Working Directory](#define-working-directory)
- [Wrangler v3](#wrangler-v3)
- [Outputs](#outputs)
- [Examples](#examples)
- [Contributors ✨](#contributors-)

---


## About
GitHub Action for creating Cloudflare Pages deployments, using the [Direct Upload](https://developers.cloudflare.com/pages/platform/direct-upload/) feature and [Wrangler](https://developers.cloudflare.com/pages/platform/direct-upload/#wrangler-cli) integration.


This action was originally found on the official Cloudflare Github page, but the action has lacked updates to more recent libraries.


Specifying `wranglerVersion: '3'` will utilize the newer `wrangler deploy` command over v2's deprecated `publish` command.


---


## Usage

1. Create an API token within the [Cloudflare Dashboard](https://dash.cloudflare.com/profile/api-tokens) with the "Cloudflare Pages — Edit" permission.
2. Within the example below, replace `CLOUDFLARE_API_TOKEN` with your given API token.
3. Create a new Github action file `.github/workflows/cfpage-publish.yml` in your repository with the following:


```yml
run-name: "☁️ CF › Deploy"
name: "☁️ CF › Deploy"

on: [push]

jobs:
job-publish:
name: >-
📦 Publish to Cloudflare
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:

- name: "☑️ Checkout"
id: task_publish_checkout
uses: actions/checkout@v4

- name: "☁️ Publish to Cloudflare Pages"
id: task_publish_push
uses: aetherinox/cloudflare-publish-action@latest
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} # Cloudflare API Token at https://dash.cloudflare.com/profile/api-tokens
accountId: ACCOUNT_ID # Cloudflare account ID available on right side of CF website
projectName: PROJECT_NAME # Project name assigned at creation. view on workers-and-pages section of CF website
directory: BUILD_OUTPUT_FOLDER # Output directory for built website
gitHubToken: ${{ secrets.GITHUB_TOKEN }} # Optional: Enable this if you want to have GitHub Deployments triggered
branch: main # Branch website published to; by default this will be the branch which triggered this workflow
workingDirectory: my-site # Working directory
wranglerVersion: '3' # Optional: Change the Wrangler version, allows you to point to a specific version or a tag such as `beta`
commitMsg: 'Your commit message' # Optional: Commit message to attach
commitDirty: false # Optional: Whether or not the workspace should be considered dirty for this deployment
skipCaching: false # Optional: Skip asset caching which speeds up builds
```


Replace with following variables with your own:
- `ACCOUNT_ID`
- `PROJECT_NAME`
- `BUILD_OUTPUT_FOLDER`


### Get Account ID

To find your account ID, log in to the [Cloudflare Dashboard](https://dash.cloudflare.com/) > select your zone in Account Home > find your account ID in Overview under **API** on the right-side menu. If you have not added a zone, add one by selecting **Add site** . You can purchase a domain from [Cloudflare’s registrar](https://developers.cloudflare.com/registrar/).

If you do not have a zone registered to your account, you can also get your account ID from the `pages.dev` URL. E.g: `https://dash.cloudflare.com//pages`


### Generate an API Token

To generate an API token:

1. Log in to the [Cloudflare Dashboard](https://dash.cloudflare.com/)
2. Select [My Profile](https://dash.cloudflare.com/profile) from the dropdown menu of your user icon on the top right of your dashboard.
3. Select [API Tokens](https://dash.cloudflare.com/profile/api-tokens) > `Create Token`
4. Under `Custom Token`, select `Get Started`
5. Name your API Token in the Token name field
6. Under `Permissions`, select `Account`, `Cloudflare Pages` and `Edit`
7. Select Continue to `Summary` > `Create Token`



More information can be found on [our guide for making Direct Upload deployments with continous integration](https://developers.cloudflare.com/pages/how-to/use-direct-upload-with-continuous-integration/#use-github-actions).


### Define Branch

The branch name is used by Cloudflare Pages to determine if the deployment is production or preview. Read more about
[git branch build controls](https://developers.cloudflare.com/pages/platform/branch-build-controls/#branch-build-controls).

If you are in a Git workspace, Wrangler will automatically pull the branch information for you. You can override this
manually by adding the argument `branch: BRANCH_NAME`.


### Define Working Directory

By default Wrangler will run in the root package directory. If your app lives in a monorepo and you want to run Wrangler from its directory, add `workingDirectory: PACKAGE_DIRECTORY`.


Some people may store their website in the root directory of a branch; if so, specify `./` as your working directory.


### Wrangler v3

You can use the newly released [Wrangler v3](https://blog.cloudflare.com/wrangler3/) with the `wranglerVersion` property.

```yaml
- name: "☁️ Publish to Cloudflare Pages"
uses: aetherinox/cloudflare-publish-action@latest
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ACCOUNT_ID
projectName: PROJECT_NAME
directory: BUILD_OUTPUT_FOLDER
wranglerVersion: '3'
```


---


## Outputs
This action will return the following outputs:


| Name | Description |
| ------------- | --------------------------------------------------- |
| `id` | The ID of the pages deployment |
| `url` | The URL of the pages deployment |
| `alias` | The alias if it exists otherwise the deployment URL |
| `environment` | The environment that was deployed to |


---


## Examples
A few examples of this Github action are provided below:

Deploy cloudflare pages on push with deploy outputs


This example allows you to run the action either manually, or on push for the branches `master` or `main`. It includes input declarations when using `workflow_dispatch`.


```yml
run-name: "☁️ CF › Deploy"
name: "☁️ CF › Deploy"

on:
push:
branches:
- main
- master

jobs:
job-publish:
name: >-
📦 Publish to Cloudflare
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:

- name: "☑️ Checkout"
id: task_publish_checkout
uses: actions/checkout@v4

- name: "☁️ Publish to Cloudflare Pages"
id: task_publish_push
uses: aetherinox/cloudflare-publish-action@latest
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ACCOUNT_ID
projectName: PROJECT_NAME
directory: BUILD_OUTPUT_FOLDER
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
branch: main
workingDirectory: my-site
wranglerVersion: '3'

- name: "📝 Outputs"
run: |
echo "ID ........... ${{ steps.task_publish_push.outputs.id }}"
echo "URL .......... ${{ steps.task_publish_push.outputs.url }}"
echo "Environment .. ${{ steps.task_publish_push.outputs.environment }}"
echo "Alias ........ ${{ steps.task_publish_push.outputs.alias }}"

- name: "📝 Outputs to Summary"
run: |
echo "Deployed to ${{ steps.task_publish_push.outputs.url }}" >> $GITHUB_STEP_SUMMARY
```


Ensure you change the values above to your own.

Run npm, @cloudflare/next-on-pages (Next.js), and deploy to cloudflare pages


[@cloudflare/next-on-pages](https://github.com/cloudflare/next-on-pages) is a CLI tool that you can use to build and develop Next.js applications so that they can run on the Cloudflare Pages platform.


```yml
run-name: "☁️ CF › Deploy"
name: "☁️ CF › Deploy"

on:
push:
branches:
- main
- master

jobs:
job-publish:
name: >-
📦 Publish to Cloudflare
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
statuses: write
steps:

- name: "☑️ Checkout"
id: task_publish_checkout
uses: actions/checkout@v4

- name: "📦 Install Packages"
id: task_publish_install_packages
run: npm install

- name: "🔨 Build"
id: task_publish_build_nextonpages
run: npx @cloudflare/next-on-pages@1

- name: "☁️ Publish to Cloudflare Pages"
id: task_publish_push
uses: aetherinox/cloudflare-publish-action@latest
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ACCOUNT_ID
projectName: PROJECT_NAME
directory: BUILD_OUTPUT_FOLDER
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
branch: main
workingDirectory: my-site
wranglerVersion: '3'

- name: "📝 Outputs"
run: |
echo "ID ........... ${{ steps.task_publish_push.outputs.id }}"
echo "URL .......... ${{ steps.task_publish_push.outputs.url }}"
echo "Environment .. ${{ steps.task_publish_push.outputs.environment }}"
echo "Alias ........ ${{ steps.task_publish_push.outputs.alias }}"

- name: "📝 Outputs to Summary"
run: |
echo "Deployed to ${{ steps.task_publish_push.outputs.url }}" >> $GITHUB_STEP_SUMMARY
```


Ensure you change the values above to your own.

Run on push + workflow dispatch (with inputs)


This example allows you to run the action either manually, or on push for the branches `master` or `main`. It includes input declarations when using `workflow_dispatch`.


```yml
run-name: "☁️ CF › Deploy"
name: "☁️ CF › Deploy"

on:
push:
branches:
- main
- master

workflow_dispatch:
inputs:
PROJECT_NAME:
description: "Project Name"
required: true
default: 'my-site'
type: string

CLOUDFLARE_ACCOUNT_ID:
description: "Cloudflare Account ID"
required: true
default: 'XXXXXXXXXXXXXXXX'
type: string

DIRECTORY_BUILD_OUTPUT:
description: "Build Output Dir"
required: true
default: './'
type: string

DIRECTORY_WORKING:
description: "Working Dir"
required: true
default: './'
type: string

WRANGLER_VERSION:
description: "Wrangler Version"
required: true
default: '3'
type: string

BRANCH:
description: 'Website Branch'
required: true
default: 'main'
type: choice
options:
- main
- master

jobs:
job-publish:
name: >-
📦 Publish to Cloudflare
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:

- name: "☑️ Checkout"
id: task_publish_checkout
uses: actions/checkout@v4

- name: "☁️ Publish to Cloudflare Pages"
id: task_publish_push
uses: aetherinox/cloudflare-publish-action@latest
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || inputs.CLOUDFLARE_ACCOUNT_ID }}
projectName: ${{ inputs.PROJECT_NAME || 'my-site' }}
directory: ${{ inputs.DIRECTORY_BUILD_OUTPUT || './' }}
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ inputs.BRANCH || 'main' }}
workingDirectory: ${{ inputs.DIRECTORY_WORKING || './' }}
wranglerVersion: ${{ inputs.WRANGLER_VERSION || '3' }}
```


Ensure you change the values above to your own.

Verify & create project using Cloudflare APU, then push to cloudflare (with inputs)


This example adds the usage of the Cloudflare api to first check if your project name actually exists on Cloudflare, creates the project if not, and then pushes to Cloudflare pages.


```yml
run-name: "☁️ CF › Deploy"
name: "☁️ CF › Deploy"

on:
push:
branches:
- main
- master

workflow_dispatch:
inputs:
PROJECT_NAME:
description: "Project Name"
required: true
default: 'my-site'
type: string

CLOUDFLARE_ACCOUNT_ID:
description: "Cloudflare Account ID"
required: true
default: 'XXXXXXXXXXXXXXXX'
type: string

DIRECTORY_BUILD_OUTPUT:
description: "Build Output Dir"
required: true
default: './'
type: string

DIRECTORY_WORKING:
description: "Working Dir"
required: true
default: './'
type: string

WRANGLER_VERSION:
description: "Wrangler Version"
required: true
default: '3'
type: string

BRANCH:
description: 'Website Branch'
required: true
default: 'main'
type: choice
options:
- main
- master

jobs:
job-publish:
name: >-
📦 Publish to Cloudflare
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:

- name: "☑️ Checkout"
id: task_publish_checkout
uses: actions/checkout@v4

- name: "☁️ CF › Check Project"
id: task_publish_project_verify
shell: bash
run: |
check=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${{ secrets.CLOUDFLARE_ACCOUNT_ID || inputs.CLOUDFLARE_ACCOUNT_ID }}/pages/projects/${{ inputs.PROJECT_NAME || 'my-site' }}" \
-H "Authorization: Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type:application/json" | jq -r '.success')
echo "result=$check" >> $GITHUB_OUTPUT

- name: "☁️ CF › Create Project (if nonexistent)"
id: task_publish_project_create
shell: bash
if: steps.task_publish_project_verify.outputs.result != 'true'
run: |
curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/${{ secrets.CLOUDFLARE_ACCOUNT_ID || inputs.CLOUDFLARE_ACCOUNT_ID }}/pages/projects" \
-H "Authorization: Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type:application/json" \
--data '{"name":"${{ inputs.PROJECT_NAME || 'my-site' }}", "production_branch":"${{ inputs.BRANCH || 'main' }}"}'

- name: "☁️ Publish to Cloudflare Pages"
id: task_publish_push
uses: aetherinox/cloudflare-publish-action@latest
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || inputs.CLOUDFLARE_ACCOUNT_ID }}
projectName: ${{ inputs.PROJECT_NAME || 'my-site' }}
directory: ${{ inputs.DIRECTORY_BUILD_OUTPUT || './' }}
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ inputs.BRANCH || 'main' }}
workingDirectory: ${{ inputs.DIRECTORY_WORKING || './' }}
wranglerVersion: ${{ inputs.WRANGLER_VERSION || '3' }}
```


Configure node + pre-install wrangler, and push to cloudflare (with inputs)


This example adds the usage of the Cloudflare api to first check if your project name actually exists on Cloudflare, creates the project if not, and then pushes to Cloudflare pages.


```yml
run-name: "☁️ CF › Deploy"
name: "☁️ CF › Deploy"

on:
push:
branches:
- main
- master

workflow_dispatch:
inputs:
PROJECT_NAME:
description: "Project Name"
required: true
default: 'my-site'
type: string

CLOUDFLARE_ACCOUNT_ID:
description: "Cloudflare Account ID"
required: true
default: 'XXXXXXXXXXXXXXXX'
type: string

DIRECTORY_BUILD_OUTPUT:
description: "Build Output Dir"
required: true
default: './'
type: string

DIRECTORY_WORKING:
description: "Working Dir"
required: true
default: './'
type: string

WRANGLER_VERSION:
description: "Wrangler Version"
required: true
default: '3'
type: string

BRANCH:
description: 'Website Branch'
required: true
default: 'main'
type: choice
options:
- main
- master

jobs:
job-publish:
name: >-
📦 Publish to Cloudflare
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:

- name: "☑️ Checkout"
id: task_publish_checkout
uses: actions/checkout@v4

- name: "⚙️ Setup › Node"
id: task_publish_node_setup
uses: actions/setup-node@v4
with:
node-version: '20.x'

- name: "📦 NPM › Install Wrangler"
id: task_publish_npm_install
run: |
npm install -g npm@latest
npm install --global wrangler
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: "☁️ CF › Check Project"
id: task_publish_project_verify
shell: bash
run: |
check=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${{ secrets.CLOUDFLARE_ACCOUNT_ID || inputs.CLOUDFLARE_ACCOUNT_ID }}/pages/projects/${{ inputs.PROJECT_NAME || 'my-site' }}" \
-H "Authorization: Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type:application/json" | jq -r '.success')
echo "result=$check" >> $GITHUB_OUTPUT

- name: "☁️ CF › Create Project (if nonexistent)"
id: task_publish_project_create
shell: bash
if: steps.task_publish_project_verify.outputs.result != 'true'
run: |
curl -s -X POST "https://api.cloudflare.com/client/v4/accounts/${{ secrets.CLOUDFLARE_ACCOUNT_ID || inputs.CLOUDFLARE_ACCOUNT_ID }}/pages/projects" \
-H "Authorization: Bearer ${{ secrets.CLOUDFLARE_API_TOKEN }}" \
-H "Content-Type:application/json" \
--data '{"name":"${{ inputs.PROJECT_NAME || 'my-site' }}", "production_branch":"${{ inputs.BRANCH || 'main' }}"}'

- name: "☁️ Publish to Cloudflare Pages"
id: task_publish_push
uses: aetherinox/cloudflare-publish-action@latest
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID || inputs.CLOUDFLARE_ACCOUNT_ID }}
projectName: ${{ inputs.PROJECT_NAME || 'my-site' }}
directory: ${{ inputs.DIRECTORY_BUILD_OUTPUT || './' }}
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ inputs.BRANCH || 'main' }}
workingDirectory: ${{ inputs.DIRECTORY_WORKING || './' }}
wranglerVersion: ${{ inputs.WRANGLER_VERSION || '3' }}
```



---


## Contributors ✨
We are always looking for contributors. If you feel that you can provide something useful to this package, then we'd love to review your suggestion. Before submitting your contribution, please review the following resources:


The following people have helped get this project going:

[![Contributors][badge-all-contributors]](#contributors-)



Aetherinox
Aetherinox

💻 📆 🔍


---


[link-general-npm]: https://npmjs.com
[link-general-nodejs]: https://nodejs.org
[link-npmtrends]: http://npmtrends.com/@aetherinox/cloudflare-publish-action

[badge-version-gh]: https://img.shields.io/github/v/tag/aetherinox/cloudflare-publish-action?logo=GitHub&label=Version&color=ba5225
[link-version-gh]: https://github.com/aetherinox/cloudflare-publish-action/releases

[badge-version-npm]: https://img.shields.io/npm/v/@aetherinox/cloudflare-publish-action?logo=npm&label=Version&color=ba5225
[link-version-npm]: https://npmjs.com/package/@aetherinox/cloudflare-publish-action

[badge-license-mit]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
[link-license-mit]: https://github.com/aetherinox/cloudflare-publish-action/blob/main/LICENSE

[badge-build]: https://img.shields.io/github/actions/workflow/status/aetherinox/cloudflare-publish-action/release-npm.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
[link-build]: https://github.com/aetherinox/cloudflare-publish-action/actions/workflows/release-npm.yml

[badge-downloads-gh]: https://img.shields.io/github/downloads/aetherinox/cloudflare-publish-action/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
[link-downloads-gh]: https://github.com/aetherinox/cloudflare-publish-action/releases
[badge-downloads-npm]: https://img.shields.io/npm/dw/%40aetherinox%2Fcloudflare-publish-action?logo=npm&&label=Downloads&color=376892
[link-downloads-npm]: https://npmjs.com/package/@aetherinox/cloudflare-publish-action

[badge-size-gh]: https://img.shields.io/github/repo-size/aetherinox/cloudflare-publish-action?logo=github&label=Size&color=59702a
[link-size-gh]: https://github.com/aetherinox/cloudflare-publish-action/releases
[badge-size-npm]: https://img.shields.io/npm/unpacked-size/@aetherinox/cloudflare-publish-action/latest?logo=npm&label=Size&color=59702a
[link-size-npm]: https://npmjs.com/package/@aetherinox/cloudflare-publish-action

[badge-coverage]: https://img.shields.io/codecov/c/github/aetherinox/cloudflare-publish-action?token=MPAVASGIOG&logo=codecov&logoColor=FFFFFF&label=Coverage&color=354b9e
[link-coverage]: https://codecov.io/github/aetherinox/cloudflare-publish-action

[badge-all-contributors]: https://img.shields.io/github/all-contributors/aetherinox/cloudflare-publish-action?logo=contributorcovenant&color=de1f6f&label=contributors
[link-all-contributors]: https://github.com/all-contributors/all-contributors
[badge-tests]: https://img.shields.io/github/actions/workflow/status/aetherinox/cloudflare-publish-action/tests.yml?logo=github&label=Tests&color=2c6488
[link-tests]: https://github.com/aetherinox/cloudflare-publish-action/actions/workflows/tests.yml
[badge-commit]: https://img.shields.io/github/last-commit/aetherinox/cloudflare-publish-action?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
[link-commit]: https://github.com/aetherinox/cloudflare-publish-action/commits/main/