Skip to content

Commit

Permalink
feat: add cloudflare pages action
Browse files Browse the repository at this point in the history
  • Loading branch information
adeherysh committed Jul 30, 2024
1 parent 0b35a61 commit 3995627
Show file tree
Hide file tree
Showing 6 changed files with 311 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @adeherysh
20 changes: 20 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## What does this PR do?
_Place what this pull request changes and anything affected. If your PR block or require another PR, also need to mention here_

## Why are we doing this? Any context or related work?
_You may put your link or another here_

## Where should a reviewer start?
_optional -- if your changes affected so much files, it is encouraged to give helper for reviewer_

## Screenshots
_optional -- You may put the database, sequence or any diagram needed_

## Manual testing steps?
_Steps to do tests. including all possible that can hape_

## Config changes
_optional -- If there's config changes, put it here_

## Deployment instructions
_optional -- Better to put it if there's some 'special case' for deployment_
16 changes: 16 additions & 0 deletions .github/workflows/release-please.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Release Please

on:
push:
branches:
- main

jobs:
release-please:
runs-on: ubuntu-latest
steps:
- name: Release please
uses: googleapis/release-please-action@v4
with:
release-type: simple
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ bin-release/

# Other files and folders
.settings/
.DS_Store

# Executables
*.swf
Expand Down
96 changes: 95 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,95 @@
# cloudflare-pages-action
# Cloudflare Pages Action

Deploy your project to Cloudflare Pages with automatic project creation and custom domain

## Usage

### Deploy preview

```yaml
on:
pull_request:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Build
run: pnpm build

- name: Deploy
uses: kitabisa/cloudflare-pages-action@v1
with:
api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
branch: ${{ github.ref }}
production-branch: main
package-manager: pnpm
build-directory: ./out
project-name: your-cloudflare-project
zone-name: example.com
custom-domain: dev-${{ github.event.pull_request.number }}.example.com
working-directory: ./
```
### Deploy production
```yaml
on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Build
run: pnpm build

- name: Deploy
uses: kitabisa/cloudflare-pages-action@v1
with:
api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
branch: main
production-branch: main
package-manager: pnpm
build-directory: ./out
project-name: your-cloudflare-project
zone-name: example.com
custom-domain: prod.example.com
working-directory: ./
```
## Inputs
| Name | Description | Default | Examples |
| --------------------- | --------------------------------- | ------------- | ------------------------------------- |
| `api-token` | Define Cloudflare api token. | `undefined` | `sjcbjxbBJKBJKBbkjbjkbkBkbjkBjkbk` |
| `account-id` | Define Cloudflare account id. | `undefined` | `023e105f4ecef8ad9ca31a8372d0c353` |
| `branch` | Branch for current deployment. | `undefined` | `${{ github.ref }}` |
| `production-branch` | Branch for production deployment. | `undefined` | `main` |
| `package-manager` | Setup package manager. | `undefined` | `npm`, `yarn`, `pnpm`, `bun` |
| `build-directory` | Define output build directory. | `undefined` | `./out` |
| `project-name` | Setup project name. | `undefined` | `kitabisa-accounts` |
| `zone-name` | Define Cloudflare zone name. | `""` | `kitabisa.com` |
| `custom-domain` | Setup custom domain. | `""` | `accounts.kitabisa.com` |
| `working-directory` | Setup working directory. | `"."` | `./apps/accounts` |

## Outputs

| Name | Description | Example |
| ----------------- | --------------------------------------------------------- | ----------------------------- |
| `deployment-url` | The output deployment url from custom domain (if set). | `accounts.kitabisa.com` |
| `pages-url` | The output deployment url from cloudflare pages. | `kitabisa-accounts.pages.dev` |
178 changes: 178 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
name: Cloudflare Pages Action
description: Deploy your project to Cloudflare Pages with automatic project creation and custom domain
author: Ade Hery Shopyan

branding:
icon: 'upload-cloud'
color: 'blue'

inputs:
api-token:
required: true
description: "Set api token"
type: string

account-id:
required: true
description: "Set account id"
type: string

branch:
required: true
description: "Set branch"
type: string

production-branch:
required: true
description: "Set production branch"
type: string

build-directory:
required: true
description: "Set build directory"
type: string

package-manager:
required: true
description: "Set package manager"
type: string

project-name:
required: true
description: "Set project name"
type: string

zone-name:
required: false
description: "Set zone name"
default: ""
type: string

custom-domain:
required: false
description: "Set custom domain"
default: ""
type: string

working-directory:
required: false
description: "Set working directory"
default: "."
type: string

outputs:
deployment-url:
description: "Define deployment url"
value: ${{ steps.url.outputs.deployment-url }}

pages-url:
description: "Define pages url"
value: ${{ steps.url.outputs.pages-url }}

runs:
using: composite
steps:
- name: Deploy
id: deploy
uses: cloudflare/wrangler-action@v3
with:
workingDirectory: ${{ inputs.working-directory }}
apiToken: ${{ inputs.api-token }}
accountId: ${{ inputs.account-id }}
preCommands: wrangler pages project create ${{ inputs.project-name }} --production-branch=${{ inputs.production-branch }} || true
command: pages deploy ${{ inputs.build-directory }} --project-name=${{ inputs.project-name }} --branch=${{ inputs.branch }} --commit-dirty=true
packageManager: ${{ inputs.package-manager }}

- name: Get Cloudflare Zone ID
id: get-zone-id
if: "${{ inputs.zone-name != '' }}"
shell: bash
env:
CLOUDFLARE_API_TOKEN: ${{ inputs.api-token }}
ZONE_DOMAIN: ${{ inputs.zone-name }}
run: |
response=$(curl -X GET "https://api.cloudflare.com/client/v4/zones?name=$ZONE_DOMAIN" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json")
zone_id=$(echo $response | jq -r '.result[0].id')
echo "id=$zone_id" >> $GITHUB_OUTPUT
- name: Set Cloudflare DNS Record & Custom Domain
id: dnsrecord
if: "${{ steps.get-zone-id.outputs.id != 'null' && inputs.zone-name != '' && inputs.custom-domain != '' }}"
shell: bash
env:
CLOUDFLARE_API_TOKEN: ${{ inputs.api-token }}
CLOUDFLARE_ACCOUNT_ID: ${{ inputs.account-id }}
CLOUDFLARE_ZONE_ID: ${{ steps.get-zone-id.outputs.id }}
PROJECT_NAME: ${{ inputs.project-name }}
CUSTOM_DOMAIN: ${{ inputs.custom-domain }}
run: |
echo "Check DNS record exist or not for the domain: ${CUSTOM_DOMAIN}"
res_record=$(curl -X GET "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records?type=CNAME&name=$CUSTOM_DOMAIN" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json")
dns_record_id=$(echo $res_record | jq -r '.result[0].id')
if [ "$dns_record_id" == "null" ] || [ -z "$dns_record_id" ]; then
echo "DNS record not found for the domain: ${CUSTOM_DOMAIN}"
response=$(curl -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"type": "CNAME",
"name": "'"$CUSTOM_DOMAIN"'",
"content": "'"$PROJECT_NAME"'.pages.dev",
"ttl": 1,
"proxied": true
}')
id=$(echo $response | jq -r '.result.id')
echo "id=$id" >> $GITHUB_OUTPUT
echo "Set Cloudflare Pages Custom Domain for: ${CUSTOM_DOMAIN}"
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/pages/projects/$PROJECT_NAME/domains" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"name": "'$CUSTOM_DOMAIN'"}'
else
echo "DNS record found for the domain: ${CUSTOM_DOMAIN}"
echo "id=$dns_record_id" >> $GITHUB_OUTPUT
fi
- name: Update Cloudflare DNS Record
if: "${{ steps.get-zone-id.outputs.id != 'null' && inputs.zone-name != '' && inputs.custom-domain != '' && inputs.branch != inputs.production-branch }}"
shell: bash
env:
CLOUDFLARE_API_TOKEN: ${{ inputs.api-token }}
CLOUDFLARE_ZONE_ID: ${{ steps.get-zone-id.outputs.id }}
CUSTOM_DOMAIN: ${{ inputs.custom-domain }}
DNS_RECORD_ID: ${{ steps.dnsrecord.outputs.id }}
PAGES_URL: ${{ steps.deploy.outputs.deployment-url }}
run: |
DNS_RECORD_CONTENT=$(echo "$PAGES_URL" | sed 's/^https:\/\///')
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records/$DNS_RECORD_ID" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"type": "CNAME",
"name": "'"$CUSTOM_DOMAIN"'",
"content": "'"$DNS_RECORD_CONTENT"'",
"id": "'"$DNS_RECORD_ID"'",
"ttl": 1,
"proxied": true
}'
- name: Get deployment url
id: url
shell: bash
env:
DEPLOYMENT_URL: ${{ inputs.custom-domain }}
PAGES_URL: ${{ steps.deploy.outputs.deployment-url }}
run: |
if [ "$DEPLOYMENT_URL" != "" ]; then
echo "deployment-url=https://$DEPLOYMENT_URL" >> $GITHUB_OUTPUT
echo "pages-url=$PAGES_URL" >> $GITHUB_OUTPUT
else
echo "deployment-url=$PAGES_URL" >> $GITHUB_OUTPUT
echo "pages-url=$PAGES_URL" >> $GITHUB_OUTPUT
fi

0 comments on commit 3995627

Please sign in to comment.