Skip to content

eddiegroves/cloudflare-pages-deploy-action

Repository files navigation

Cloudflare Pages deploy action

Deploys files to a Cloudflare Pages project using direct upload and sets GitHub deployment status.

Advantages of direct upload compared with linking GitHub to Cloudflare:

  • No need to link Cloudflare Pages as a GitHub App to your entire GitHub account.
  • Full control over build process. Using CI/CD such as GitHub Actions is much more flexible than Cloudflare for doing the build and adding other jobs.

Inputs

Action inputRequiredDescription
cloudflare-account-idYesCloudflare account ID that contains the Pages project
cloudflare-api-tokenYesCloudflare API token with Cloudflare Pages read/write permission.
cloudflare-environmentYesThe name of the environment (Cloudflare calls it a branch) you want for the Cloudflare Pages deployment. Does not have to match git branch.
cloudflare-pages-project-nameYesThe name of the Cloudflare Pages project you want to deploy to.
cloudflare-publish-directoryYesThe directory of static files to upload to Cloudflare Pages.

Outputs

Action outputsDescription
github-deployment-idThe created GitHub deployment identifier
cloudflare-pages-deployment-idThe created Cloudflare Pages deployment identifier.
cloudflare-pages-urlThe URL where Cloudflare Pages was deployed to.

Example usage

name: Deploy to Cloudflare Pages production
on:
  push:
    branches:
      - main
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Build
        run: make build
      - id: Deploy
        uses: eddiegroves/cloudflare-pages-deploy-action@7eb85e27aa014332055f718f151a7071ce50eae4
        with:
          cloudflare-publish-directory: dist/
          cloudflare-environment: production
          cloudflare-pages-project-name: eddie-cf-pages-example
          cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}

Steps

The action is developed as a composite action using bash or python steps. All steps are placed inline into the run sections to avoid issues with PATHs and external files.

The process is three steps:

  1. Create GitHub deployment
  2. Create Cloudflare Pages deployment
  3. Poll deployment status

Sequence diagram

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                              β”Œβ”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚GitHub β”‚          β”‚create-github-β”‚          β”‚create-cloudflare-β”‚          β”‚poll-deployment-β”‚                              β”‚GitHubβ”‚          β”‚Cloudflareβ”‚
                    β”‚Actionsβ”‚          β”‚deployment    β”‚          β”‚pages-deployment  β”‚          β”‚status          β”‚                              β”‚API   β”‚          β”‚API       β”‚
                    β””β”€β”€β”€β”¬β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β””β”€β”€β”¬β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                        β”‚     Start step      β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        │────────────────────>β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚          Create GitHub deployment                                     β”‚                   β”‚
                        β”‚                     β”‚ ──────────────────────────────────────────────────────────────────────────────────────────────────>                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                    β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚   Deployment ID     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                   Start step                    β”‚                            β”‚                                          β”‚                   β”‚
                        │────────────────────────────────────────────────>β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚     Create Pages deployment              β”‚                   β”‚
                        β”‚                     β”‚                           β”‚ ──────────────────────────────────────────────────────────────────────────────────────────>
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚           Start step      β”‚                            β”‚                                          β”‚                   β”‚
                        │─────────────────────────────────────────────────────────────────────────────>β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
╔═══════╀═══════════════β•ͺ═════════════════════β•ͺ═══════════════════════════β•ͺ════════════════════════════β•ͺ══════════════════════════════════════════β•ͺ═══════════════════β•ͺ═══════════════╗
β•‘ LOOP  β”‚  up to 5 minutes                    β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•Ÿβ”€β”€β”€β”€β”€β”€β”€β”˜               β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                   Find matching deployment                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚ ─────────────────────────────────────────────────────────────>               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                       id, stage, status  β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘         ╔══════╀══════β•ͺ═════════════════════β•ͺ═══════════════════════════β•ͺ════════════════════════════β•ͺ══════════════════════════════════════════β•ͺ═════════════╗     β”‚               β•‘
β•‘         β•‘ ALT  β”‚  status == failure         β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•Ÿβ”€β”€β”€β”€β”€β”€β”˜      β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚ Create GitHub deployment status (failed) β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚ ─────────────────────────────────────────>             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•ͺ═════════════════════β•ͺ═══════════════════════════β•ͺ════════════════════════════β•ͺ══════════════════════════════════════════β•ͺ═════════════╝     β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘         ╔══════╀══════β•ͺ═════════════════════β•ͺ═══════════════════════════β•ͺ════════════════════════════β•ͺ══════════════════════════════════════════β•ͺ═════════════╗     β”‚               β•‘
β•‘         β•‘ ALT  β”‚  stage == deploy and status == success                 β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•Ÿβ”€β”€β”€β”€β”€β”€β”˜      β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚ Create GitHub deployment status (success)β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚ ─────────────────────────────────────────>             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚                           β”‚                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚                     β”‚    id, Cloudflare Pages url                            β”‚                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•‘             β”‚<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│                                          β”‚             β•‘     β”‚               β•‘
β•‘         β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•ͺ═════════════════════β•ͺ═══════════════════════════β•ͺ════════════════════════════β•ͺ══════════════════════════════════════════β•ͺ═════════════╝     β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚ Create GitHub deployment status (pending)β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚ ─────────────────────────────────────────>                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚               β•‘
β•‘                       β”‚                     β”‚                           β”‚                            β”‚ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                   β”‚               β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•ͺ═════════════════════β•ͺ═══════════════════════════β•ͺ════════════════════════════β•ͺ══════════════════════════════════════════β•ͺ═══════════════════β•ͺ═══════════════╝
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚  Create GitHub deployment status (error) β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚ ─────────────────────────────────────────>                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚                     β”‚                           β”‚                            β”‚                                          β”‚                   β”‚
                        β”‚<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│                                          β”‚                   β”‚
                    β”Œβ”€β”€β”€β”΄β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”                              β”Œβ”€β”€β”΄β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”
                    β”‚GitHub β”‚          β”‚create-github-β”‚          β”‚create-cloudflare-β”‚          β”‚poll-deployment-β”‚                              β”‚GitHubβ”‚          β”‚Cloudflareβ”‚
                    β”‚Actionsβ”‚          β”‚deployment    β”‚          β”‚pages-deployment  β”‚          β”‚status          β”‚                              β”‚API   β”‚          β”‚API       β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β””β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Create GitHub deployment

Create Github deployment is responsible for calling the create deployments GitHub API and outputting the newly created deployment identifier.

It is implemented in bash and a standalone example can be tested and viewed: create-gh-deployment.sh

GitHub deployments are used purely for convenience purposes by populating GitHub deployment history and filling the environment section on the repository page.

create-gh-deployment.sh

Inputs
Environment variableRequiredDescriptionValueResources
INPUT_ENVIRONMENTYesThe deployment target environment, e.g test, dev, qa, production.inputs.cloudflare-environmentGitHub create deployment API
INPUT_GITHUB_REFYesThe ref for the deploy. This can be a branch, tag, or SHA.github.refRequired by GitHub Create a deployment API
INPUT_GITHUB_REPOSITORYYesThe owner and repository name. For example, eddiegroves/hello-world.github.repositoryGitHub Actions contexts
GITHUB_TOKENYesA token to authenticate on behalf of the GitHub Action.github.tokenGitHub Actions contexts
Outputs
GitHub outputsDescription
github-deployment-idThe created GitHub deployment identifier
Source
# * Inputs
#
# |-------------------------+----------------------------------------------------------------------|
# | Environment variable    | Description                                                          |
# |-------------------------+----------------------------------------------------------------------|
# | INPUT_ENVIRONMENT       | The deployment target environment, e.g test, dev, qa, staging.       |
# | INPUT_GITHUB_REF        | The ref for the deploy. This can be a branch, tag, or SHA.           |
# | INPUT_GITHUB_REPOSITORY | The owner and repository name. For example, eddiegroves/hello-world. |
# | GITHUB_TOKEN            | A token to authenticate on behalf of the GitHub Action.              |
# |-------------------------+----------------------------------------------------------------------|
#
# * Outputs
#
# |----------------------+------------------------------------------|
# | GitHub outputs       | Description                              |
# |----------------------+------------------------------------------|
# | github-deployment-id | The created GitHub deployment identifier |
# |----------------------+------------------------------------------|

errors=""
declare -a inputs=(<<create-gh-deployment-inputs-list()>>)

for input_name in "${inputs[@]}"
do
    if [ -z ${!input_name+x} ]; then
       errors="${errors}environment variable $input_name is required\n"
    fi
done

if [ ! -z "${errors}" ]; then
    printf "$errors"
    exit 1
fi

json_string=$( jq -n \
                 --arg environment "$INPUT_ENVIRONMENT" \
                 --arg github_ref "$INPUT_GITHUB_REF" \
                 '<<create-gh-deployment-json-jq-single-line>>')

curl --silent \
  -X POST \
  https://api.github.com/repos/$INPUT_GITHUB_REPOSITORY/deployments \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -d "$json_string" | jq '.id' | xargs -I {} echo "::set-output name=github-deployment-id::{}"

Create Cloudflare Pages deployment

Create Cloudflare Pages deployment deploys a directory of static assets as a Pages deployment.

It is implemented in bash and a standalone example can be tested and viewed:

The implementation uses Cloudflare Wrangler CLI tool which is an npm package.

NameHomepageDescription
wranglerhttps://github.com/cloudflare/wrangler2#readmeCommand-line interface for all things Cloudflare Workers

create-cf-deployment-status.sh

Inputs
Environment variableRequiredDescriptionValueResources
CLOUDFLARE_ACCOUNT_IDYesUsed by Wranlger to identify the Cloudflare Pages account.inputs.cloudflare-account-idWrangler source
CLOUDFLARE_API_TOKENYesUsed by Wranlger to authenticate to Cloudflare API.inputs.cloudflare-api-tokenWrangler source
INPUT_CLOUDFLARE_PROJECT_NAMEYesThe name of the Cloudflare Pages project you want to deploy to.inputs.cloudflare-pages-project-nameWrangler pages publish command
INPUT_ENVIRONMENTYesThe deployment target environment, e.g test, dev, qa, staging. Cloudflare refers to this as a branch.inputs.cloudflare-environmentWrangler pages publish command
INPUT_PUBLISH_DIRECTORYYesThe directory of static files to upload.inputs.cloudflare-publish-directoryWrangler pages publish command
INPUT_COMMIT_HASHYesThe SHA to attach to this deployment.github.shaWrangler pages publish command
INPUT_MESSAGEYesThe commit message to attach to this deployment.github.event.head_commit.messageWrangler pages publish command https://stackoverflow.com/a/63619526/19596450 github.event.head_commit object available for push event
Outputs

No outputs are created.

Source
# * Input
#
# |-------------------------------+-----------------------------------------------------------------|
# | Environment variable          | Description                                                     |
# |-------------------------------+-----------------------------------------------------------------|
# | CLOUDFLARE_ACCOUNT_ID         | Used by Wranlger to identify the Cloudflare Pages account.      |
# | CLOUDFLARE_API_TOKEN          | Used by Wranlger to authenticate to Cloudflare API.             |
# | INPUT_CLOUDFLARE_PROJECT_NAME | The name of the Cloudflare Pages project you want to deploy to. |
# | INPUT_ENVIRONMENT             | The deployment target environment, e.g test, dev, qa, staging.  |
# | INPUT_PUBLISH_DIRECTORY       | The directory of static files to upload.                        |
# | INPUT_COMMIT_HASH             | The SHA to attach to this deployment.                           |
# | INPUT_MESSAGE                 | The commit message to attach to this deployment.                |
# |-------------------------------+-----------------------------------------------------------------|
#
# * Output
#
# No outputs are created.

errors=""
declare -a inputs=(<<create-cf-deployment-status-inputs-list()>>)

for input_name in "${inputs[@]}"
do
    if [ -z ${!input_name+x} ]; then
       errors="${errors}environment variable $input_name is required\n"
    fi
done

if [ ! -z "${errors}" ]; then
    printf "$errors"
    exit 1
fi

npx wrangler@2.0.29 pages publish $INPUT_PUBLISH_DIRECTORY \
--project-name=$INPUT_CLOUDFLARE_PROJECT_NAME \
--branch=$INPUT_ENVIRONMENT \
--commit-hash=$INPUT_COMMIT_HASH \
--commit-message="$INPUT_MESSAGE"

Poll deployment status

poll-deployment-status.sh

Inputs
Environment variableRequiredDescriptionValueResources
INPUT_COMMIT_HASHYesThe SHA to attach to this deployment.github.sha
INPUT_GITHUB_DEPLOYMENT_IDYesThe GitHub deployment identifier for this deployment.steps.create-gh-deployment.outputs.github-deployment-id
INPUT_GITHUB_REPOSITORYYesThe owner and repository name. For example, eddiegroves/hello-world.github.repositoryGitHub Actions contexts
INPUT_CLOUDFLARE_PROJECT_NAMEYesThe name of the Cloudflare Pages project you want to deploy to.inputs.cloudflare-pages-project-nameWrangler pages publish command
GITHUB_TOKENYesA token to authenticate on behalf of the GitHub Action.github.tokenGitHub Actions contexts
CLOUDFLARE_ACCOUNT_IDYesUsed by Wrangler to identify the Cloudflare Pages account.inputs.cloudflare-account-idWrangler source
CLOUDFLARE_API_TOKENYesUsed by Wrangler to authenticate to Cloudflare API.inputs.cloudflare-api-tokenWrangler source
Outputs
GitHub outputsDescription
cloudflare-pages-deployment-idThe created Cloudflare Pages deployment identifier.
cloudflare-pages-urlThe URL where Cloudflare Pages was deployed to.
Source
# * Inputs
#
# |-------------------------------+----------+----------------------------------------------------------------------|
# | Environment variable          | Required | Description                                                          |
# |-------------------------------+----------+----------------------------------------------------------------------|
# | INPUT_COMMIT_HASH             | Yes      | The SHA to attach to this deployment.                                |
# | INPUT_GITHUB_DEPLOYMENT_ID    | Yes      | The GitHub deployment identifier for this deployment.                |
# | INPUT_GITHUB_REPOSITORY       | Yes      | The owner and repository name. For example, eddiegroves/hello-world. |
# | INPUT_CLOUDFLARE_PROJECT_NAME | Yes      | The name of the Cloudflare Pages project you want to deploy to.      |
# | GITHUB_TOKEN                  | Yes      | A token to authenticate on behalf of the GitHub Action.              |
# | CLOUDFLARE_ACCOUNT_ID         | Yes      | Used by Wrangler to identify the Cloudflare Pages account.           |
# | CLOUDFLARE_API_TOKEN          | Yes      | Used by Wrangler to authenticate to Cloudflare API.                  |
# |-------------------------------+----------+----------------------------------------------------------------------|
#
# * Outputs
# |--------------------------------+-----------------------------------------------------|
# | GitHub outputs                 | Description                                         |
# |--------------------------------+-----------------------------------------------------|
# | cloudflare-pages-deployment-id | The created Cloudflare Pages deployment identifier. |
# | cloudflare-pages-url           | The URL where Cloudflare Pages was deployed to.     |
# |--------------------------------+-----------------------------------------------------|

import http.client
import json
import subprocess
import os
from time import sleep
from typing import Literal

commit_hash = os.environ["INPUT_COMMIT_HASH"]
github_deployment_id = os.environ["INPUT_GITHUB_DEPLOYMENT_ID"]
github_repository = os.environ["INPUT_GITHUB_REPOSITORY"]
cloudflare_project_name = os.environ["INPUT_CLOUDFLARE_PROJECT_NAME"]
github_token = os.environ["GITHUB_TOKEN"]
cloudflare_api_token = os.environ["CLOUDFLARE_API_TOKEN"]
cloudflare_account_id = os.environ["CLOUDFLARE_ACCOUNT_ID"]


def create_github_deployment_status(
    description: str,
    environment: str,
    state: Literal[
        "error", "failure", "inactive", "in_progress", "queued", "pending", "success"
    ],
    log_url: str = None,
    environment_url: str = None,
):
    payload = {"description": description, "environment": environment, "state": state}

    if log_url:
        payload["log_url"] = log_url

    if environment_url:
        payload["environment_url"] = environment_url

    headers = {
        "User-Agent": "eddiegroves/action/cloudflare-deploy",
        "Content-Type": "application/json",
        "Accept": "application/vnd.github+json",
        "Authorization": f"Bearer {github_token}",
    }

    githubApi = http.client.HTTPSConnection("api.github.com")
    githubApi.request(
        "POST",
        f"/repos/{github_repository}/deployments/{github_deployment_id}/statuses",
        json.dumps(payload),
        headers,
    )


def list_cloudflare_deployments():
    headers = {
        "User-Agent": "eddiegroves/action/cloudflare-deploy",
        "Accept": "application/json",
        "Authorization": f"Bearer {cloudflare_api_token}",
    }

    cloudflareApi = http.client.HTTPSConnection("api.cloudflare.com")
    cloudflareApi.request(
        "GET",
        f"/client/v4/accounts/{cloudflare_account_id}/pages/projects/{cloudflare_project_name}/deployments",
        "",
        headers,
    )

    res = cloudflareApi.getresponse()
    data = res.read().decode("utf-8")

    p = subprocess.run(
        [
            "jq",
            "-r",
            "--arg",
            "commit",
            commit_hash,
            ".result[] | select(.deployment_trigger.metadata.commit_hash == $commit) | { id, project_name, environment,  url: (.aliases[0] // .url), stage: .latest_stage.name, status: .latest_stage.status }",
        ],
        input=data,
        capture_output=True,
        text=True,
        check=False,
    )

    return json.loads(p.stdout)


count = 0
while count < 60:
    deployment = list_cloudflare_deployments()

    if deployment["status"] == "failed":
        print("😒 sad face")
        create_github_deployment_status(
            description="Cloudflare Pages deployment failed.",
            environment="production",
            state="failure",
            log_url=f"https://dash.cloudflare.com?to=/:account/pages/view/{cloudflare_project_name}/{deployment['id']}",
        )
        exit(1)

    if deployment["stage"] == "deploy" and deployment["status"] == "success":
        print("πŸ€— happy face")
        create_github_deployment_status(
            description="Cloudflare Pages deployment success.",
            environment="production",
            state="success",
            log_url=f"https://dash.cloudflare.com?to=/:account/pages/view/{cloudflare_project_name}/{deployment['id']}",
            environment_url=deployment["url"],
        )

        print(f"::set-output name=cloudflare-pages-deployment-id::{deployment['id']}")
        print(f"::set-output name=cloudflare-pages-url::{deployment['url']}")
        exit(0)

    print(f"🧐 {deployment['stage']} {deployment['status']}")
    create_github_deployment_status(
        description="Cloudflare Pages deployment in progress.",
        environment="production",
        state="in_progress",
        log_url=f"https://dash.cloudflare.com?to=/:account/pages/view/{cloudflare_project_name}/{deployment['id']}",
    )
    sleep(5)
    count = count + 1

print("😭 super sad")
create_github_deployment_status(
    description="Cloudflare Pages deployment status unknown.",
    environment="production",
    state="error",
)
exit(1)

About

GitHub composite action for deploying to Cloudflare Pages

Resources

License

Stars

Watchers

Forks

Packages

No packages published