Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/adriangonz97/refined-cf-pages-action
https://github.com/adriangonz97/refined-cf-pages-action
Last synced: 4 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/adriangonz97/refined-cf-pages-action
- Owner: AdrianGonz97
- License: mit
- Created: 2024-01-06T17:15:09.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-09-23T16:32:00.000Z (about 1 month ago)
- Last Synced: 2024-10-30T02:25:18.506Z (7 days ago)
- Language: TypeScript
- Size: 644 KB
- Stars: 21
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Refined Cloudflare Pages Action
> An opinionated fork of the official [Cloudflare Pages Action](https://github.com/cloudflare/pages-action).
A GitHub Action for creating Cloudflare Pages deployments, using [Direct Upload](https://developers.cloudflare.com/pages/platform/direct-upload/) with [Wrangler](https://developers.cloudflare.com/pages/platform/direct-upload/#wrangler-cli).
## Advantages over official solutions
- ✅ Generated build summaries
- ✅ Deploy multiple sites from a single monorepo
- ✅ Builds site previews of PRs from forked repositories, [a known issue](https://developers.cloudflare.com/pages/platform/known-issues/#builds-and-deployment) with official solutions
- ✅ GitHub Deployments on PRs from forks## Usage
> [!IMPORTANT]
> This action entirely replaces the Cloudflare Pages GitHub integration. Before continuing, you should [disable the automatic builds](#disabling-the-cloudflare-pages-github-integration) made by Cloudflare for the repository you are applying this action to.1. [Locate your Cloudflare account ID](#get-account-id).
2. [Generate an API token](#generate-an-api-token).
3. Add the Cloudflare account ID and API token [as secrets to your GitHub repository](#add-cloudflare-credentials-to-github-secrets).
4. Create a `.github/workflows/publish.yml` file in your repository:```yml
on:
push:
branches:
- mainjobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
name: Publish to Cloudflare Pages
steps:
- name: Checkout
uses: actions/checkout@v3# Run a build step here if your project requires one
# ...- name: Publish to Cloudflare Pages
uses: AdrianGonz97/refined-cf-pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
projectName: YOUR_PROJECT_NAME
directory: YOUR_BUILD_OUTPUT_DIRECTORY
# Optional: Supply a deployment name if you want to have GitHub Deployments triggered
deploymentName: Production
# Optional: Switch what branch you are publishing to.
# By default, this will be the branch which triggered this workflow
branch: main
# Optional: Change the working directory
workingDirectory: my-site
# Optional: Change the Wrangler version, allows you to point to a specific version or a tag such as `beta`
# Specifying an empty string ('') will omit the version specifier.
wranglerVersion: '3'
```5. Replace `YOUR_PROJECT_NAME` and `YOUR_BUILD_OUTPUT_DIRECTORY` with the appropriate values to your Pages project.
And you're ready to go!
> [!TIP]
> Be sure to check out the [_Enabling PR Previews from Forks_](#enabling-pr-previews-from-forks) section if you're interested in enabling this particular feature.### Get account ID
To find your account ID, log in to the Cloudflare dashboard > 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**.
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).
1. Select **My Profile** from the dropdown menu of your user icon on the top right of your dashboard.
1. Select **API Tokens** > **Create Token**.
1. Under **Custom Token**, select **Get started**.
1. Name your API Token in the **Token name** field.
1. Under **Permissions**, select **Account**, **Cloudflare Pages** and **Edit**:
1. Select **Continue to summary** > **Create Token**.### Add Cloudflare credentials to GitHub secrets
1. Go to your project’s repository in GitHub.
1. Under your repository’s name, select **Settings**.
1. Select **Secrets and variables** > **Actions** > **New repository secret**.
1. Create a secret and put `CLOUDFLARE_ACCOUNT_ID` as the name with the value being your Cloudflare account ID.
1. Create another secret and put `CLOUDFLARE_API_TOKEN` as the name with the value being your Cloudflare API token.### Disabling the Cloudflare Pages GitHub integration
If you have already connected your repository to the [Cloudflare Pages GitHub integration](https://developers.cloudflare.com/pages/configuration/git-integration/), you'll need to disable it.
1. Go to your project’s repository in GitHub.
1. Under your repository’s name, select **Settings**.
1. Select **GitHub Apps**, and next to Cloudflare Pages, select **Configure**
1. Under **Repository access**, select **Only select repositories**, and remove your repository.### Enabling PR Previews from Forks
If your site _does not_ use/have any runtime secrets in your **preview environment on Cloudflare**, then it should be fine to use as-is. We use this method in [shadcn-svelte](https://github.com/huntabyte/shadcn-svelte) and its implementation can be found [here](https://github.com/huntabyte/shadcn-svelte/blob/main/.github/workflows).
Example: Preview Deployment with NO RUNTIME/BUILD-TIME SECRETS
First we'll build the project in an unprivileged environment where secrets are not exposed. This allows use to safely run untrusted code:
```yaml
# build-preview.yml
name: Build Preview Deploymenton:
pull_request:
types: [opened, synchronize]jobs:
build-preview:
runs-on: ubuntu-latest
name: Build Preview Site and Upload Build Artifact
steps:
- name: Checkout
uses: actions/checkout@v4# Run your install/build steps here
# ...# Build example
- name: Build site
run: pnpm build
env:
# if you need environment variables that are _NOT secrets_, apply them here during build
# using GH Action variables
SOME_ENV_VAR: ${{ vars.SOME_ENV_VAR }}# Uploads the build directory as a workflow artifact
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: preview-build
path: YOUR_BUILD_OUTPUT_DIRECTORY
```Then we'll deploy the project to Cloudflare in a privileged environment where we can safely use secrets (i.e. your cloudflare credentials):
```yaml
# deploy-preview.yml
name: Upload Preview Deployment
on:
workflow_run:
workflows: ['Build Preview Deployment']
types:
- completedpermissions:
actions: read
deployments: write
contents: read
pull-requests: writejobs:
deploy-preview:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
name: Deploy Preview to Cloudflare Pages
steps:
# Downloads the build directory from the previous workflow
- name: Download build artifact
uses: actions/download-artifact@v4
id: preview-build-artifact
with:
name: preview-build
path: build
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}- name: Deploy to Cloudflare Pages
uses: AdrianGonz97/refined-cf-pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
projectName: YOUR_PROJECT_NAME
deploymentName: Preview
directory: ${{ steps.preview-build-artifact.outputs.download-path }}
```---
If your project **does use runtime secrets**, then the deployment job can be fitted with an `environment` field that requires manual approval before each deployment.
Manual approval using [environments](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) needs to be setup at the repo level, as described in this [Melt UI PR](https://github.com/melt-ui/melt-ui/pull/899) under the _"Make the `Preview` environment protected"_ step.
Example: Preview Deployment WITH RUNTIME SECRETS
```yaml
# build-preview.yml
name: Build Preview Deploymenton:
pull_request:
types: [opened, synchronize]jobs:
build-preview:
environment: Preview # The name of the environment that requires manual approval before each deployment
runs-on: ubuntu-latest
name: Build Preview Site and Upload Build Artifact
steps:
- name: Checkout
uses: actions/checkout@v4# Run your install/build steps here
# ...# Build example
- name: Build site
run: pnpm build
env:
# If you need environment variables that are **NOT secrets**,
# apply them here during build using GH Action Variables
SOME_ENV_VAR: ${{ vars.SOME_ENV_VAR }}# Uploads the build directory as a workflow artifact
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: preview-build
path: YOUR_BUILD_OUTPUT_DIRECTORY
``````yaml
# deploy-preview.yml
name: Upload Preview Deployment
on:
workflow_run:
workflows: ['Build Preview Deployment']
types:
- completedpermissions:
actions: read
deployments: write
contents: read
pull-requests: writejobs:
deploy-preview:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
name: Deploy Preview to Cloudflare Pages
steps:
# Downloads the build directory from the previous workflow
- name: Download build artifact
uses: actions/download-artifact@v4
id: preview-build-artifact
with:
name: preview-build
path: build
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}- name: Deploy to Cloudflare Pages
uses: AdrianGonz97/refined-cf-pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
projectName: YOUR_PROJECT_NAME
deploymentName: Preview
directory: ${{ steps.preview-build-artifact.outputs.download-path }}
```---
In the off chance that you need **build-time secrets** (which you should try to avoid for previews), then you'll need to use the `pull_request_target` event _with_ manual approvals before each deployment.
> [!IMPORTANT]
> With this method, each PR needs to be reviewed thoroughly before deployment approval to ensure that secrets are not being exposed via malicious code. Use with discretion.Example: Preview Deployment WITH BUILD-TIME SECRETS
```yaml
name: Preview Deployment
on:
pull_request_target:jobs:
deploy-preview:
environment: Preview # The name of the environment that requires manual approval before each deployment
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
deployments: write
name: Deploy Preview to Cloudflare Pages
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}# Run your install/build steps here
# ...# Build example
- name: Build site
run: pnpm build
env:
SOME_SECRET: ${{ secrets.SOME_SECRET }} # Uses some secret during build- name: Deploy to Cloudflare Pages
uses: AdrianGonz97/refined-cf-pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
projectName: YOUR_PROJECT_NAME
directory: YOUR_BUILD_OUTPUT_DIRECTORY
deploymentName: Preview
```### Specifying a 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: YOUR_BRANCH_NAME`.### Specifying a 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: YOUR_PACKAGE_DIRECTORY`.
## 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 |