-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Consolidate CI web builds into the build workflow and restore deployments to GitHub environments #3916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consolidate CI web builds into the build workflow and restore deployments to GitHub environments #3916
Changes from 4 commits
e5a4d8f
e3d25b6
8a69a8d
565f637
5dec45f
2bd4c44
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,8 @@ on: | |
| push: | ||
| branches: | ||
| - master | ||
| tags: | ||
| - latest-stable | ||
| workflow_dispatch: | ||
| inputs: | ||
| web: | ||
|
|
@@ -59,8 +61,6 @@ jobs: | |
| RUSTC_WRAPPER: /usr/bin/sccache | ||
| CARGO_INCREMENTAL: 0 | ||
| SCCACHE_DIR: /var/lib/github-actions/.cache | ||
| INDEX_HTML_HEAD_REPLACEMENT: <script defer data-domain="dev.graphite.art" data-api="https://graphite.art/visit/event" src="https://graphite.art/visit/script.hash.js"></script> | ||
|
|
||
| steps: | ||
| - name: 📥 Clone repository | ||
| uses: actions/checkout@v6 | ||
|
|
@@ -90,9 +90,20 @@ jobs: | |
| rustflags: "" | ||
| target: wasm32-unknown-unknown | ||
|
|
||
| - name: ✂ Replace template in <head> of index.html | ||
| - name: 🔀 Choose production deployment environment and insert template | ||
| id: production-env | ||
| if: github.event_name == 'push' | ||
| run: sed -i "s|<!-- INDEX_HTML_HEAD_REPLACEMENT -->|$INDEX_HTML_HEAD_REPLACEMENT|" frontend/index.html | ||
| run: | | ||
| if [[ "${{ github.ref }}" == "refs/tags/latest-stable" ]]; then | ||
| echo "cf_project=graphite-editor" >> $GITHUB_OUTPUT | ||
| DOMAIN="editor.graphite.art" | ||
| else | ||
| echo "cf_project=graphite-dev" >> $GITHUB_OUTPUT | ||
| DOMAIN="dev.graphite.art" | ||
| fi | ||
| TEMPLATE="<script defer data-domain=\"$DOMAIN\" data-api=\"https://graphite.art/visit/event\" src=\"https://graphite.art/visit/script.hash.js\"></script>" | ||
| echo "template=$TEMPLATE" >> $GITHUB_OUTPUT | ||
| sed -i "s|<!-- INDEX_HTML_HEAD_REPLACEMENT -->|$TEMPLATE|" frontend/index.html | ||
|
|
||
| - name: 🌐 Build Graphite web code | ||
| env: | ||
|
|
@@ -105,28 +116,70 @@ jobs: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | ||
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | ||
| run: | | ||
| MAX_ATTEMPTS=5 | ||
| DELAY=30 | ||
| if [ -z "$CLOUDFLARE_API_TOKEN" ]; then | ||
| echo "No Cloudflare API token available (fork PR), skipping deploy." | ||
| exit 0 | ||
| fi | ||
| MAX_ATTEMPTS=8 | ||
| DELAY=15 | ||
| for ATTEMPT in $(seq 1 $MAX_ATTEMPTS); do | ||
| echo "Attempt $ATTEMPT of $MAX_ATTEMPTS..." | ||
| if OUTPUT=$(npx wrangler@3 pages deploy "frontend/dist" --project-name="graphite-dev" --commit-dirty=true 2>&1); then | ||
| URL=$(echo "$OUTPUT" | grep -oP 'https://[^\s]+\.pages\.dev' | head -1) | ||
| npx wrangler@3 pages deploy "frontend/dist" --project-name="${{ steps.production-env.outputs.cf_project || 'graphite-dev' }}" --commit-dirty=true 2>&1 | tee /tmp/wrangler_output | ||
| if [ ${PIPESTATUS[0]} -eq 0 ]; then | ||
| URL=$(grep -oP 'https://[^\s]+\.pages\.dev' /tmp/wrangler_output | head -1) | ||
| echo "url=$URL" >> "$GITHUB_OUTPUT" | ||
| echo "Published successfully: $URL" | ||
| exit 0 | ||
| fi | ||
| echo "Attempt $ATTEMPT failed:" | ||
| echo "$OUTPUT" | ||
| echo "Attempt $ATTEMPT failed." | ||
| if [ "$ATTEMPT" -lt "$MAX_ATTEMPTS" ]; then | ||
| echo "Retrying in ${DELAY}s..." | ||
| sleep $DELAY | ||
| DELAY=$((DELAY * 3)) | ||
| DELAY=$((DELAY * 2)) | ||
| fi | ||
| done | ||
| echo "All $MAX_ATTEMPTS Cloudflare Pages publish attempts failed." | ||
| exit 1 | ||
|
|
||
| - name: 🚀 Create a GitHub environment deployment | ||
| if: inputs.checkout_repo == '' || inputs.checkout_repo == github.repository | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| CF_URL: ${{ steps.cloudflare.outputs.url }} | ||
| run: | | ||
| if [ -z "$CF_URL" ]; then | ||
| echo "No Cloudflare URL available, skipping deployment." | ||
| exit 0 | ||
| fi | ||
| if [ "${{ github.ref }}" = "refs/tags/latest-stable" ]; then | ||
| REF="latest-stable" | ||
| ENVIRONMENT="graphite-editor (Production)" | ||
| elif [ "${{ github.event_name }}" = "push" ]; then | ||
| REF="master" | ||
| ENVIRONMENT="graphite-dev (Production)" | ||
| else | ||
| REF="${{ inputs.checkout_ref || github.head_ref || github.ref_name }}" | ||
| ENVIRONMENT="graphite-dev (Preview)" | ||
| fi | ||
| DEPLOY_ID=$(gh api \ | ||
| -X POST \ | ||
| -H "Accept: application/vnd.github+json" \ | ||
| repos/${{ github.repository }}/deployments \ | ||
| --input - \ | ||
| --jq '.id' <<EOF | ||
| {"ref":"$REF","environment":"$ENVIRONMENT","auto_merge":false,"required_contexts":[]} | ||
| EOF | ||
| ) | ||
| gh api \ | ||
| -X POST \ | ||
| -H "Accept: application/vnd.github+json" \ | ||
| repos/${{ github.repository }}/deployments/$DEPLOY_ID/statuses \ | ||
| -f state=success \ | ||
| -f environment_url="$CF_URL" \ | ||
| -f log_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | ||
|
|
||
| - name: 💬 Comment with the build link | ||
| if: github.event_name != 'pull_request' && github.event_name != 'merge_group' | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| CF_URL: ${{ steps.cloudflare.outputs.url }} | ||
|
|
@@ -140,15 +193,18 @@ jobs: | |
| |-| | ||
| | $CF_URL |" | ||
|
|
||
| if [ "${{ github.event_name }}" = "push" ]; then | ||
| # Comment on the commit hash page | ||
| if [ "${{ github.ref }}" = "refs/tags/latest-stable" ]; then | ||
| # Push tag: skip commenting (commit was already commented on master merge) | ||
| echo "Tag push, skipping comment." | ||
| elif [ "${{ github.event_name }}" = "push" ]; then | ||
| # Push master: comment on the commit hash page | ||
| gh api \ | ||
| -X POST \ | ||
| -H "Accept: application/vnd.github+json" \ | ||
| repos/${{ github.repository }}/commits/$(git rev-parse HEAD)/comments \ | ||
| -f body="$COMMENT_BODY" | ||
| else | ||
| # Comment on the PR (use provided PR number from !build, or look it up by branch name) | ||
| elif [ "${{ github.event_name }}" != "pull_request" ] && [ "${{ github.event_name }}" != "merge_group" ]; then | ||
| # Manual trigger (workflow_dispatch, !build): comment on the PR | ||
| PR_NUMBER="${{ inputs.pr_number }}" | ||
| if [ -z "$PR_NUMBER" ]; then | ||
| BRANCH=$(git rev-parse --abbrev-ref HEAD) | ||
|
|
@@ -162,18 +218,26 @@ jobs: | |
| fi | ||
| fi | ||
|
|
||
| - name: ✂ Strip analytics script from built output for clean artifact | ||
| - name: ✂ Strip template from completed build for a clean artifact | ||
| if: github.event_name == 'push' | ||
| run: sed -i "s|$INDEX_HTML_HEAD_REPLACEMENT||" frontend/dist/index.html | ||
| run: sed -i "s|${{ steps.production-env.outputs.template }}||" frontend/dist/index.html | ||
|
|
||
| - name: 📦 Upload web bundle artifact | ||
| if: github.event_name != 'pull_request' | ||
| uses: actions/upload-artifact@v6 | ||
| with: | ||
| name: graphite-web-bundle | ||
| path: frontend/dist | ||
|
|
||
| - name: 👕 Lint Graphite web formatting | ||
| env: | ||
| NODE_ENV: production | ||
| run: | | ||
| cd frontend | ||
| npm run check | ||
|
|
||
| - name: 📃 Trigger website rebuild if auto-generated code docs are stale | ||
| if: github.event_name == 'push' | ||
| if: github.event_name == 'push' && github.ref != 'refs/tags/latest-stable' | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
|
|
@@ -184,7 +248,7 @@ jobs: | |
| || gh workflow run website.yml --ref master | ||
|
|
||
| windows: | ||
| if: github.event_name == 'push' || inputs.windows | ||
| if: (github.event_name == 'push' && github.ref != 'refs/tags/latest-stable') || inputs.windows | ||
| runs-on: windows-latest | ||
| permissions: | ||
| contents: read | ||
|
|
@@ -214,8 +278,8 @@ jobs: | |
| uses: actions/cache@v5 | ||
| with: | ||
| path: | | ||
| ${{ env.USERPROFILE }}\.cargo\registry | ||
| ${{ env.USERPROFILE }}\.cargo\git | ||
| ~/.cargo/registry | ||
| ~/.cargo/git | ||
| target | ||
| key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} | ||
|
|
||
|
|
@@ -376,7 +440,7 @@ jobs: | |
| path: target/artifacts | ||
|
|
||
| mac: | ||
| if: github.event_name == 'push' || inputs.mac | ||
| if: (github.event_name == 'push' && github.ref != 'refs/tags/latest-stable') || inputs.mac | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why, I would expect it to also build on pushing the tag.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That build already occurs when we originally push the commit. We haven't yet set up GitHub Releases deployments, but this clause will be removed when we do that. |
||
| runs-on: macos-latest | ||
| permissions: | ||
| contents: read | ||
|
|
@@ -554,7 +618,7 @@ jobs: | |
| path: target/artifacts | ||
|
|
||
| linux: | ||
| if: github.event_name == 'push' || inputs.linux | ||
| if: (github.event_name == 'push' && github.ref != 'refs/tags/latest-stable') || inputs.linux | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.