From ace9cb0fdd55e5913ad3a1115712d2186cbabd07 Mon Sep 17 00:00:00 2001 From: Edoardo Pirovano Date: Wed, 3 Jul 2024 14:36:53 +0100 Subject: [PATCH 1/4] Create new Action to create GitHub deployments from Cloudflare --- cloudflare-pages/action.yml | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 cloudflare-pages/action.yml diff --git a/cloudflare-pages/action.yml b/cloudflare-pages/action.yml new file mode 100644 index 00000000..bd71b8a0 --- /dev/null +++ b/cloudflare-pages/action.yml @@ -0,0 +1,54 @@ +name: 'Meticulous - Trigger tests for Cloudflare Pages' +description: 'Trigger Meticulous tests for a Cloudflare Pages deployment' +inputs: + github-token: + description: 'A GitHub Actions token (should have write permission on deployments)' + required: true + cloudflare-api-token: + description: 'API token for Cloudflare (should have Read permission for Cloudflare Pages)' + required: true + cloudflare-account-id: + description: 'Account ID for Cloudflare Pages (from the Workers & Pages section of the dashboard)' + required: true + cloudflare-project-name: + description: 'Name of your Cloudflare Pages project (from the Workers & Pages section of the dashboard)' + required: true + sleep-seconds: + description: 'Time to sleep before starting to poll deployment status (in seconds)' + required: false + default: "300" +runs: + using: "composite" + steps: + - name: Sleep a bit to wait for the deployment to exist + if: ${{ inputs.sleep-time != '0' }} + shell: bash + run: sleep ${{ inputs.sleep-time }} + - name: Wait for deployment to be ready and get URL + shell: bash + id: get-url + run: | + STATUS="unknown" + SLEPT=0 + while [[ "$STATUS" != "success" ]]; do + echo "Checking deployment status..." + STATUS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${{ inputs.cloudflare-account-id }}/pages/projects/${{ inputs.cloudflare-project-name }}/deployments" -H "Authorization: Bearer ${{ inputs.cloudflare-api-token }}" -H "Content-Type:application/json" | jq -c 'first(.result[] | select(.deployment_trigger.metadata.commit_hash == "${{ github.sha }}") | .latest_stage.status)' --raw-output | tr -d '\n') + if [[ "$STATUS" != "success" ]]; then + if [[ $SLEPT -gt 3600 ]]; then + echo "Deployment is still not ready after waiting an hour, failing..." + exit 1 + fi + echo "Deployment is not ready yet, sleeping for a minute..." + sleep 60 + SLEPT=$((SLEPT+30)) + fi + done + echo "Deployment is ready!" + echo "url=`curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${{ inputs.cloudflare-account-id }}/pages/projects/${{ inputs.cloudflare-project-name }}/deployments" -H "Authorization: Bearer ${{ inputs.cloudflare-api-token }}" -H "Content-Type:application/json" | jq -c 'first(.result[] | select(.deployment_trigger.metadata.commit_hash == "${{ github.sha }}") | .url)' --raw-output | tr -d '\n'`" >> $GITHUB_OUTPUT + - name: Create GitHub deployment from Cloudflare Pages deployment + uses: altinukshini/deployment-action@releases/v1 + with: + token: "${{ inputs.github-token }}" + target_url: "${{ steps.get-url.outputs.url }}" + initial_status: "success" + environment: "Meticulous" From efb4ef92646590a0819f513e5dfeb7f206deccfe Mon Sep 17 00:00:00 2001 From: Edoardo Pirovano Date: Wed, 3 Jul 2024 14:55:45 +0100 Subject: [PATCH 2/4] Add documentation --- cloudflare-pages/README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 cloudflare-pages/README.md diff --git a/cloudflare-pages/README.md b/cloudflare-pages/README.md new file mode 100644 index 00000000..9da98a40 --- /dev/null +++ b/cloudflare-pages/README.md @@ -0,0 +1,29 @@ +# Cloudflare Pages Action + +To use this Action please create a GitHub Actions workflow `.github/workflows/trigger-meticulous.yaml` with the contents: + +```yaml +name: Trigger Meticulous +on: [push] +permissions: + deployments: write +jobs: + trigger-meticulous: + name: Trigger Meticulous + runs-on: ubuntu-latest + steps: + - name: Trigger Meticulous + uses: alwaysmeticulous/report-diffs-action/cloudflare-pages@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare-account-id: << FILL THIS IN >> + cloudflare-project-name: << FILL THIS IN >> +``` + +You should pass in: + +- `github-token`: This is automatically created for your workflow by GitHub but still needs to be passed in to our step as shown above. +- `cloudflare-api-token`: This should be created as documented [here](https://developers.cloudflare.com/pages/configuration/api/) with the `Read` permission for `Cloudflare Pages` and stored in a [GitHub Actions secret](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository) named `CLOUDFLARE_API_TOKEN`. Then it can be passed into our step as shown above. +- `cloudflare-account-id`: You can find this by following the instructions [here](https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/#find-account-id-workers-and-pages), then paste it into the workflow file (it is not confidential). +- `cloudflare-project-name`: You can find this on the same dashboard your account ID is on, then paste it into the workflow file (it is not confidential). From 0cc7b23898692d7bb185e39c91e3f570d900f010 Mon Sep 17 00:00:00 2001 From: Edoardo Pirovano Date: Wed, 3 Jul 2024 16:12:19 +0100 Subject: [PATCH 3/4] Add more options --- cloudflare-pages/action.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cloudflare-pages/action.yml b/cloudflare-pages/action.yml index bd71b8a0..69914772 100644 --- a/cloudflare-pages/action.yml +++ b/cloudflare-pages/action.yml @@ -17,6 +17,14 @@ inputs: description: 'Time to sleep before starting to poll deployment status (in seconds)' required: false default: "300" + deployment-poll-seconds: + description: 'Time to wait between API calls to poll for the deployment to be ready (in seconds)' + required: false + default: "60" + wait-till-ready-seconds: + description: 'Maximum time to wait for the deployment to be ready (in seconds)' + required: false + default: "3600" runs: using: "composite" steps: @@ -34,13 +42,13 @@ runs: echo "Checking deployment status..." STATUS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${{ inputs.cloudflare-account-id }}/pages/projects/${{ inputs.cloudflare-project-name }}/deployments" -H "Authorization: Bearer ${{ inputs.cloudflare-api-token }}" -H "Content-Type:application/json" | jq -c 'first(.result[] | select(.deployment_trigger.metadata.commit_hash == "${{ github.sha }}") | .latest_stage.status)' --raw-output | tr -d '\n') if [[ "$STATUS" != "success" ]]; then - if [[ $SLEPT -gt 3600 ]]; then - echo "Deployment is still not ready after waiting an hour, failing..." + if [[ $SLEPT -gt ${{ inputs.wait-till-ready-seconds }} ]]; then + echo "Deployment is still not ready, failing..." exit 1 fi - echo "Deployment is not ready yet, sleeping for a minute..." - sleep 60 - SLEPT=$((SLEPT+30)) + echo "Deployment is not ready yet, sleeping..." + sleep ${{ inputs.deployment-poll-seconds }} + SLEPT=$((SLEPT+${{ inputs.deployment-poll-seconds }})) fi done echo "Deployment is ready!" From 036865a7c9b752cfbac2ff48b044639e1695fce0 Mon Sep 17 00:00:00 2001 From: Edoardo Pirovano Date: Wed, 3 Jul 2024 17:53:01 +0100 Subject: [PATCH 4/4] Address review comments from Alex --- cloudflare-pages/README.md | 4 +++- cloudflare-pages/action.yml | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cloudflare-pages/README.md b/cloudflare-pages/README.md index 9da98a40..9aea3007 100644 --- a/cloudflare-pages/README.md +++ b/cloudflare-pages/README.md @@ -1,6 +1,8 @@ # Cloudflare Pages Action -To use this Action please create a GitHub Actions workflow `.github/workflows/trigger-meticulous.yaml` with the contents: +This GitHub Action will create a GitHub deployment from your Cloudflare Pages one, thus triggering Meticulous to run tests. + +To use this Action please create a GitHub Actions workflow `.github/workflows/cloudflare-pages.yaml` with the contents: ```yaml name: Trigger Meticulous diff --git a/cloudflare-pages/action.yml b/cloudflare-pages/action.yml index 69914772..16d4dc1e 100644 --- a/cloudflare-pages/action.yml +++ b/cloudflare-pages/action.yml @@ -1,5 +1,5 @@ -name: 'Meticulous - Trigger tests for Cloudflare Pages' -description: 'Trigger Meticulous tests for a Cloudflare Pages deployment' +name: 'Meticulous - Create a GitHub deployment from a Cloudflare Pages deployment' +description: 'Create a GitHub deployment from a Cloudflare Pages deployment thus triggering Meticulous tests' inputs: github-token: description: 'A GitHub Actions token (should have write permission on deployments)' @@ -20,7 +20,7 @@ inputs: deployment-poll-seconds: description: 'Time to wait between API calls to poll for the deployment to be ready (in seconds)' required: false - default: "60" + default: "30" wait-till-ready-seconds: description: 'Maximum time to wait for the deployment to be ready (in seconds)' required: false @@ -34,13 +34,15 @@ runs: run: sleep ${{ inputs.sleep-time }} - name: Wait for deployment to be ready and get URL shell: bash - id: get-url + id: get-deployment run: | STATUS="unknown" + LAST_RESULT="" SLEPT=0 while [[ "$STATUS" != "success" ]]; do echo "Checking deployment status..." - STATUS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${{ inputs.cloudflare-account-id }}/pages/projects/${{ inputs.cloudflare-project-name }}/deployments" -H "Authorization: Bearer ${{ inputs.cloudflare-api-token }}" -H "Content-Type:application/json" | jq -c 'first(.result[] | select(.deployment_trigger.metadata.commit_hash == "${{ github.sha }}") | .latest_stage.status)' --raw-output | tr -d '\n') + LAST_RESULT=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${{ inputs.cloudflare-account-id }}/pages/projects/${{ inputs.cloudflare-project-name }}/deployments" -H "Authorization: Bearer ${{ inputs.cloudflare-api-token }}" -H "Content-Type:application/json") + STATUS=$(echo "$LAST_RESULT" | jq -c 'first(.result[] | select(.deployment_trigger.metadata.commit_hash == "${{ github.sha }}") | .latest_stage.status)' --raw-output | tr -d '\n') if [[ "$STATUS" != "success" ]]; then if [[ $SLEPT -gt ${{ inputs.wait-till-ready-seconds }} ]]; then echo "Deployment is still not ready, failing..." @@ -52,11 +54,12 @@ runs: fi done echo "Deployment is ready!" - echo "url=`curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/${{ inputs.cloudflare-account-id }}/pages/projects/${{ inputs.cloudflare-project-name }}/deployments" -H "Authorization: Bearer ${{ inputs.cloudflare-api-token }}" -H "Content-Type:application/json" | jq -c 'first(.result[] | select(.deployment_trigger.metadata.commit_hash == "${{ github.sha }}") | .url)' --raw-output | tr -d '\n'`" >> $GITHUB_OUTPUT + echo "url=`echo "$LAST_RESULT" | jq -c 'first(.result[] | select(.deployment_trigger.metadata.commit_hash == "${{ github.sha }}") | .url)' --raw-output | tr -d '\n'`" >> $GITHUB_OUTPUT + echo "environment=`echo "$LAST_RESULT" | jq -c 'first(.result[] | select(.deployment_trigger.metadata.commit_hash == "${{ github.sha }}") | .environment)' --raw-output | tr -d '\n'`" >> $GITHUB_OUTPUT - name: Create GitHub deployment from Cloudflare Pages deployment uses: altinukshini/deployment-action@releases/v1 with: token: "${{ inputs.github-token }}" - target_url: "${{ steps.get-url.outputs.url }}" + target_url: "${{ steps.get-deployment.outputs.url }}" initial_status: "success" - environment: "Meticulous" + environment: "Cloudflare Pages: ${{ inputs.cloudflare-project-name }} (${{ steps.get-deployment.outputs.environment }})"