name: Deploy on: push: branches: - main repository_dispatch: jobs: deploy: runs-on: ubuntu-latest timeout-minutes: 60 steps: - name: Ensure CF_DEPLOY_DOMAIN and CF_ZONE_ID are defined run: | if [ -z "$CF_ZONE_ID" ] then echo "CF_ZONE_ID not defined" exit 1 fi if [ -z "$CF_DEPLOY_DOMAIN" ] then echo "CF_DEPLOY_DOMAIN not defined" exit 1 fi env: CF_ZONE_ID: ${{ vars.CF_ZONE_ID }} CF_DEPLOY_DOMAIN: ${{ vars.CF_DEPLOY_DOMAIN }} # this is needed to get the lowercase version of the repository_owner name # TODO: switch to some lowercase function in the future when Actions supports it - name: Set lowercase repository_owner name run: | echo $GH_OWNER | awk '{ print "OWNER_LOWER=" tolower($0) }' >> ${GITHUB_ENV} env: GH_OWNER: ${{ github.repository_owner }} - uses: actions/checkout@v2 - uses: hashicorp/setup-terraform@v2 - name: Install package run: | sudo apt-get -y install jq - name: Setup node.js uses: actions/setup-node@v3 with: node-version: 18 - name: Configure Cloudflare Images variants run: | curl -XPOST https://api.cloudflare.com/client/v4/accounts/${{ secrets.CF_ACCOUNT_ID }}/images/v1/variants \ -d '{ "id": "avatar", "options": { "metadata": "copyright", "width": 400, "height": 400 } }' \ -H 'Authorization: Bearer ${{ secrets.CF_API_TOKEN }}' curl -XPOST https://api.cloudflare.com/client/v4/accounts/${{ secrets.CF_ACCOUNT_ID }}/images/v1/variants \ -d '{ "id": "header", "options": { "metadata": "copyright", "width": 1500, "height": 500 } }' \ -H 'Authorization: Bearer ${{ secrets.CF_API_TOKEN }}' curl -XPOST https://api.cloudflare.com/client/v4/accounts/${{ secrets.CF_ACCOUNT_ID }}/images/v1/variants \ -d '{ "id": "usercontent", "options": { "metadata": "copyright" } }' \ -H 'Authorization: Bearer ${{ secrets.CF_API_TOKEN }}' - name: Create D1 database uses: cloudflare/wrangler-action@2.0.0 with: command: d1 create wildebeest-${{ env.OWNER_LOWER }} apiToken: ${{ secrets.CF_API_TOKEN }} continue-on-error: true env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: retrieve D1 database uses: cloudflare/wrangler-action@2.0.0 with: command: d1 list | grep wildebeest-${{ env.OWNER_LOWER }} | awk '{print "d1_id="$2}' >> $GITHUB_ENV apiToken: ${{ secrets.CF_API_TOKEN }} env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: migrate D1 database uses: cloudflare/wrangler-action@2.0.0 with: command: d1 migrations apply wildebeest-${{ env.OWNER_LOWER }} apiToken: ${{ secrets.CF_API_TOKEN }} preCommands: | echo "*** pre commands ***" echo -e "[[d1_databases]]\nbinding=\"DATABASE\"\ndatabase_name=\"wildebeest-${{ env.OWNER_LOWER }}\"\ndatabase_id=\"${{ env.d1_id }}\"" >> wrangler.toml echo "******" env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: retrieve Zero Trust organization run: | auth_domain=$(curl https://api.cloudflare.com/client/v4/accounts/${{ secrets.CF_ACCOUNT_ID }}/access/organizations \ -H 'Authorization: Bearer ${{ secrets.CF_API_TOKEN }}' | jq -r '.result.auth_domain') printf "auth_domain=$auth_domain" >> $GITHUB_ENV - name: retrieve Terraform state KV namespace uses: cloudflare/wrangler-action@2.0.0 with: command: kv:namespace list | jq -r '.[] | select( .title == "wildebeest-terraform-${{ env.OWNER_LOWER }}-state" ) | .id' | awk '{print "tfstate_kv="$1}' >> $GITHUB_ENV apiToken: ${{ secrets.CF_API_TOKEN }} preCommands: | echo "*** pre commands ***" apt-get update && apt-get -y install jq echo "******" env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: Init run: terraform init working-directory: ./tf - name: download Terraform state uses: cloudflare/wrangler-action@2.0.0 with: command: kv:key get --namespace-id=${{ env.tfstate_kv }} terraform.tfstate > ./tf/terraform.tfstate postCommands: | echo "*** post commands ***" chmod 777 ./tf/terraform.tfstate echo "******" apiToken: ${{ secrets.CF_API_TOKEN }} env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} if: ${{ env.tfstate_kv != '' }} - name: download VAPID keys uses: cloudflare/wrangler-action@2.0.0 with: command: kv:key get --namespace-id=${{ env.tfstate_kv }} vapid_jwk | jq . > ./tf/vapid_jwk apiToken: ${{ secrets.CF_API_TOKEN }} preCommands: | echo "*** pre commands ***" apt-get update && apt-get -y install jq echo "******" env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} continue-on-error: true if: ${{ env.tfstate_kv != '' }} - name: generate VAPID keys if needed run: | sudo chmod 777 ./tf/vapid_jwk || true if [ ! -s ./tf/vapid_jwk ] then node ./scripts/generate-vapid-keys.mjs > ./tf/vapid_jwk echo "VAPID keys generated" fi - name: Publish DO uses: cloudflare/wrangler-action@2.0.0 with: apiToken: ${{ secrets.CF_API_TOKEN }} command: publish --config do/wrangler.toml env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: Retrieve DO namespace run: | curl https://api.cloudflare.com/client/v4/accounts/${{ secrets.CF_ACCOUNT_ID }}/workers/durable_objects/namespaces \ -H 'Authorization: Bearer ${{ secrets.CF_API_TOKEN }}' \ | jq -r '.result[] | select( .script == "wildebeest-do" ) | .id' | awk '{print "do_cache_id="$1}' >> $GITHUB_ENV - name: Configure run: terraform plan && terraform apply -auto-approve continue-on-error: true working-directory: ./tf env: TF_VAR_cloudflare_account_id: ${{ secrets.CF_ACCOUNT_ID }} TF_VAR_cloudflare_api_token: ${{ secrets.CF_API_TOKEN }} TF_VAR_cloudflare_zone_id: ${{ vars.CF_ZONE_ID }} TF_VAR_cloudflare_deploy_domain: ${{ vars.CF_DEPLOY_DOMAIN }} TF_VAR_gh_username: ${{ env.OWNER_LOWER }} TF_VAR_d1_id: ${{ env.d1_id }} TF_VAR_do_cache_id: ${{ env.do_cache_id }} TF_VAR_access_auth_domain: ${{ env.auth_domain }} TF_VAR_wd_instance_title: ${{ vars.INSTANCE_TITLE }} TF_VAR_wd_admin_email: ${{ vars.ADMIN_EMAIL }} TF_VAR_wd_instance_description: ${{ vars.INSTANCE_DESCR }} TF_VAR_sentry_dsn: ${{ secrets.SENTRY_DSN }} TF_VAR_sentry_access_client_id: ${{ secrets.SENTRY_ACCESS_CLIENT_ID }} TF_VAR_sentry_access_client_secret: ${{ secrets.SENTRY_ACCESS_CLIENT_SECRET }} - name: retrieve Terraform state KV namespace uses: cloudflare/wrangler-action@2.0.0 with: command: kv:namespace list | jq -r '.[] | select( .title == "wildebeest-terraform-${{ env.OWNER_LOWER }}-state" ) | .id' | awk '{print "tfstate_kv="$1}' >> $GITHUB_ENV apiToken: ${{ secrets.CF_API_TOKEN }} preCommands: | echo "*** pre commands ***" apt-get update && apt-get -y install jq echo "******" env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} if: ${{ env.tfstate_kv == '' }} - name: store VAPID keys state uses: cloudflare/wrangler-action@2.0.0 with: command: kv:key put --namespace-id=${{ env.tfstate_kv }} vapid_jwk --path=./tf/vapid_jwk apiToken: ${{ secrets.CF_API_TOKEN }} env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: store Terraform state uses: cloudflare/wrangler-action@2.0.0 with: command: kv:key put --namespace-id=${{ env.tfstate_kv }} terraform.tfstate --path=./tf/terraform.tfstate apiToken: ${{ secrets.CF_API_TOKEN }} env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: Create Queue uses: cloudflare/wrangler-action@2.0.0 with: command: queues create wildebeest apiToken: ${{ secrets.CF_API_TOKEN }} continue-on-error: true env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: Publish consumer uses: cloudflare/wrangler-action@2.0.0 with: apiToken: ${{ secrets.CF_API_TOKEN }} preCommands: | echo "*** pre commands ***" echo -e "[[d1_databases]]\nbinding=\"DATABASE\"\ndatabase_name=\"wildebeest-${{ env.OWNER_LOWER }}\"\ndatabase_id=\"${{ env.d1_id }}\"\n" >> consumer/wrangler.toml echo -e "[durable_objects]\n" >> consumer/wrangler.toml echo -e "bindings=[" >> consumer/wrangler.toml echo -e "{name=\"DO_CACHE\",class_name=\"WildebeestCache\",script_name=\"wildebeest-do\"}," >> consumer/wrangler.toml echo -e "]" >> consumer/wrangler.toml echo -e "[vars]\n" >> consumer/wrangler.toml echo -e "DOMAIN=\"${{ vars.CF_DEPLOY_DOMAIN }}\"\n" >> consumer/wrangler.toml echo -e "ADMIN_EMAIL=\"${{ vars.ADMIN_EMAIL }}\"\n" >> consumer/wrangler.toml echo "******" command: publish --config consumer/wrangler.toml env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} - name: add Queue producer to Pages run: | curl https://api.cloudflare.com/client/v4/accounts/${{ secrets.CF_ACCOUNT_ID }}/pages/projects/wildebeest-${{ env.OWNER_LOWER }} \ -XPATCH \ -H 'Authorization: Bearer ${{ secrets.CF_API_TOKEN }}' \ -d '{ "deployment_configs": { "production": { "queue_producers": { "QUEUE": { "name": "wildebeest" } } } } }' > /dev/null - name: Publish uses: cloudflare/wrangler-action@2.0.0 with: apiToken: ${{ secrets.CF_API_TOKEN }} preCommands: | echo "*** pre commands ***" yarn yarn build cp -rv ./frontend/dist/* . # remove folder that aren't needed in Pages before we upload rm -rf ./tf ./scripts ./.github ./.npm ./consumer ./*.md echo "******" command: pages publish --project-name=wildebeest-${{ env.OWNER_LOWER }} . env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} COMMIT_HASH: ${{ github.sha }}