diff --git a/.changeset/actions-node24-migration.md b/.changeset/actions-node24-migration.md new file mode 100644 index 000000000..3fa3a49f6 --- /dev/null +++ b/.changeset/actions-node24-migration.md @@ -0,0 +1,5 @@ +--- +'dle.dev': patch +--- + +Migrate the GitHub Actions deployment workflows off Node 20-based actions by upgrading the shared setup actions and replacing the Cloudflare Wrangler action with a local Pages deploy action that preserves deployment URLs in the GitHub UI. diff --git a/.github/actions/env-setup/action.yaml b/.github/actions/env-setup/action.yaml index 123e8f2cf..e72d92bdf 100644 --- a/.github/actions/env-setup/action.yaml +++ b/.github/actions/env-setup/action.yaml @@ -25,22 +25,22 @@ name: Setup Environment runs: steps: - name: Git Composite Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: ${{ inputs.fetch-depth }} ref: ${{ inputs.ref }} - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: ${{ inputs.node-version }} - name: Setup PNPM - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v5 with: version: ${{ inputs.pnpm-version }} - id: pnpm-cache name: Setup PNPM cache - uses: actions/cache@v4 + uses: actions/cache@v5 with: # include node version + lockfile hash so caches are stable across node changes key: ${{ runner.os }}-pnpm-v${{ inputs.node-version }}-${{ hashFiles('**/pnpm-lock.yaml') }} diff --git a/.github/actions/pages-deploy/action.yaml b/.github/actions/pages-deploy/action.yaml new file mode 100644 index 000000000..885964fe9 --- /dev/null +++ b/.github/actions/pages-deploy/action.yaml @@ -0,0 +1,94 @@ +name: Deploy Pages +description: Deploy a Cloudflare Pages build and expose the deployment URLs + +inputs: + account-id: + description: Cloudflare account ID + required: true + api-token: + description: Cloudflare API token + required: true + branch: + description: Branch name to attach to the deployment + required: true + directory: + default: ./.svelte-kit/cloudflare + description: Directory to deploy + required: false + project-name: + description: Cloudflare Pages project name + required: true + +outputs: + deployment-url: + description: URL of the deployed Pages site + value: ${{ steps.deploy.outputs.deployment-url }} + pages-deployment-alias-url: + description: Alias URL for preview deployments when available + value: ${{ steps.deploy.outputs.pages-deployment-alias-url }} + pages-deployment-id: + description: Cloudflare Pages deployment ID when available + value: ${{ steps.deploy.outputs.pages-deployment-id }} + pages-environment: + description: Cloudflare Pages deployment environment when available + value: ${{ steps.deploy.outputs.pages-environment }} + +runs: + using: composite + steps: + - id: deploy + name: Deploy Pages + shell: bash + env: + CLOUDFLARE_ACCOUNT_ID: ${{ inputs.account-id }} + CLOUDFLARE_API_TOKEN: ${{ inputs.api-token }} + DEPLOY_BRANCH: ${{ inputs.branch }} + DEPLOY_DIRECTORY: ${{ inputs.directory }} + DEPLOY_PROJECT_NAME: ${{ inputs.project-name }} + run: | + set -euo pipefail + + output_dir="$(mktemp -d)" + export WRANGLER_OUTPUT_FILE_DIRECTORY="$output_dir" + + pnpm wrangler pages deploy "$DEPLOY_DIRECTORY" \ + --project-name="$DEPLOY_PROJECT_NAME" \ + --branch="$DEPLOY_BRANCH" + + artifact="$(find "$output_dir" -maxdepth 1 -type f -name 'wrangler-output-*.json' | head -n 1)" + + if [ -z "$artifact" ]; then + echo "Wrangler deployment output was not written" >&2 + exit 1 + fi + + ARTIFACT_PATH="$artifact" GITHUB_OUTPUT_FILE="$GITHUB_OUTPUT" node --input-type=module <<'EOF' + import fs from 'node:fs'; + + const output = JSON.parse(fs.readFileSync(process.env.ARTIFACT_PATH, 'utf8')); + const entry = output?.type === 'pages-deploy-detailed' + ? output + : Array.isArray(output) + ? output.find((item) => item?.type === 'pages-deploy-detailed') + : undefined; + + if (!entry?.url) { + throw new Error('Pages deployment URL not found in Wrangler output'); + } + + const lines = [`deployment-url=${entry.url}`]; + + if (entry.alias) { + lines.push(`pages-deployment-alias-url=${entry.alias}`); + } + + if (entry.deployment_id) { + lines.push(`pages-deployment-id=${entry.deployment_id}`); + } + + if (entry.environment) { + lines.push(`pages-environment=${entry.environment}`); + } + + fs.appendFileSync(process.env.GITHUB_OUTPUT_FILE, `${lines.join('\n')}\n`); + EOF diff --git a/.github/workflows/changesets.yaml b/.github/workflows/changesets.yaml index 6b36d46b7..a362d3cd4 100644 --- a/.github/workflows/changesets.yaml +++ b/.github/workflows/changesets.yaml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup environment uses: ./.github/actions/env-setup @@ -40,12 +40,12 @@ jobs: - name: Publish Staging id: deploy - uses: cloudflare/wrangler-action@v3 + uses: ./.github/actions/pages-deploy with: - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - command: pages deploy ./.svelte-kit/cloudflare --project-name=dle-dev-staging --branch=master - packageManager: pnpm + account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + branch: master + project-name: dle-dev-staging version: name: Create Release PR @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup environment uses: ./.github/actions/env-setup diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index e9a40a3ca..6c78a33f1 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup environment uses: ./.github/actions/env-setup @@ -41,9 +41,9 @@ jobs: - name: Publish Web App id: deploy - uses: cloudflare/wrangler-action@v3 + uses: ./.github/actions/pages-deploy with: - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - command: pages deploy ./.svelte-kit/cloudflare --project-name=dle-dev --branch=master - packageManager: pnpm + account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + branch: master + project-name: dle-dev diff --git a/.github/workflows/deploy-release.yaml b/.github/workflows/deploy-release.yaml index e1648f16b..ce7a9addf 100644 --- a/.github/workflows/deploy-release.yaml +++ b/.github/workflows/deploy-release.yaml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup environment uses: ./.github/actions/env-setup diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index 9782973a8..b7cddad6d 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup environment uses: ./.github/actions/env-setup @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 # with: # fetch-depth: 1 - name: Setup environment @@ -60,7 +60,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 # with: # fetch-depth: 1 - name: Setup environment @@ -76,18 +76,18 @@ jobs: pnpm run build - name: Publish Web App id: deploy - uses: cloudflare/wrangler-action@v3 + uses: ./.github/actions/pages-deploy with: - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - command: pages deploy ./.svelte-kit/cloudflare --project-name=dle-dev-staging --branch=${{ github.head_ref }} - packageManager: pnpm + account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + branch: ${{ github.head_ref }} + project-name: dle-dev-staging verify: name: Verify runs-on: ubuntu-latest steps: - name: Git Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 # with: # fetch-depth: 1 - name: Setup environment