diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dbbdeb0..bf4ddc3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,85 +1,55 @@ -name: Build and Deploy to IPFS - -# Explicitly declare permissions -permissions: - contents: read - pull-requests: write - statuses: write - -on: - push: - branches: - - main - pull_request: - branches: - - main - -env: - BUILD_PATH: 'dist' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true # Cancel in progress runs if a new run is started - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - outputs: - cid: ${{ steps.deploy.outputs.cid }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Build project - run: npm run build - - - name: Upload static files as artifact - id: upload-artifact - uses: actions/upload-pages-artifact@v3 - with: - path: ${{ env.BUILD_PATH }} - - # - uses: ipfs/ipfs-deploy-action@v1 - # name: Deploy to IPFS - # id: deploy - # with: - # path-to-deploy: ${{ env.BUILD_PATH }} - # storacha-key: ${{ secrets.STORACHA_KEY }} - # storacha-proof: ${{ secrets.STORACHA_PROOF }} - # github-token: ${{ github.token }} - - # - name: Update DNSLink - # if: github.ref == 'refs/heads/main' # only update DNSLink for main branch - # uses: ipfs/dnslink-action@v0.1 - # with: - # cid: ${{ steps.deploy.outputs.cid }} - # dnslink_domain: 'helia.io' - # cf_record_id: ${{ secrets.CF_DNS_RECORD_ID }} - # cf_zone_id: ${{ secrets.CF_DNS_ZONE_ID }} - # cf_auth_token: ${{ secrets.CF_DNS_AUTH_TOKEN }} - # github_token: ${{ github.token }} - # set_github_status: true - - gh-pages: - runs-on: 'ubuntu-latest' - needs: build-and-deploy - if: github.ref == 'refs/heads/main' # only deploy to gh-pages for main branch - permissions: - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source - environment: - name: 'github-pages' - url: ${{ steps.deployment.outputs.page_url }} - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 +# Build workflow - runs for both PRs and main branch pushes +# This workflow builds the website without access to secrets +# For PRs: Runs on untrusted fork code safely (using pull_request event, not pull_request_target) +# For main: Builds and uploads artifacts for deployment +# Artifacts are passed to the deploy workflow which has access to secrets + +name: Build + +permissions: + contents: read + +on: + push: + branches: + - main + pull_request: + branches: + - main + +env: + BUILD_PATH: 'dist' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true # Cancel in progress runs if a new run is started + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci --prefer-offline --no-audit --progress=false + + - name: Build project + run: npm run build + + # Upload artifact for deploy workflow + - name: Upload build artifact + uses: actions/upload-artifact@v4 + with: + name: website-build-${{ github.run_id }} + path: ${{ env.BUILD_PATH }} + retention-days: 1 + include-hidden-files: true diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..4bc8004 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,96 @@ +# Deploy workflow - triggered by workflow_run after successful build +# This workflow has access to secrets but never executes untrusted code +# It only downloads and deploys pre-built artifacts from the build workflow +# Security: Fork code cannot access secrets as it only runs in build workflow +# Deploys to IPFS for all branches and GitHub Pages for main branch only + +name: Deploy + +# Explicitly declare permissions +permissions: + contents: read + pull-requests: write + statuses: write + +on: + workflow_run: + workflows: ["Build"] + types: [completed] + +env: + BUILD_PATH: 'dist' + +jobs: + deploy-ipfs: + if: github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + outputs: + cid: ${{ steps.deploy.outputs.cid }} + environment: + name: 'ipfs-publish' + steps: + - name: Download build artifact + uses: actions/download-artifact@v4 + with: + name: website-build-${{ github.event.workflow_run.id }} + path: ${{ env.BUILD_PATH }} + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ github.token }} + + - name: Deploy to IPFS Mirror Providers + uses: ipshipyard/ipfs-deploy-action@v1 + id: deploy + with: + path-to-deploy: ${{ env.BUILD_PATH }} + cluster-url: "/dnsaddr/ipfs-websites.collab.ipfscluster.io" + cluster-user: ${{ secrets.CLUSTER_USER }} + cluster-password: ${{ secrets.CLUSTER_PASSWORD }} + github-token: ${{ github.token }} + + dnslink-update: + if: github.event.workflow_run.head_branch == 'main' # only update DNSLink for main branch + runs-on: 'ubuntu-latest' + needs: deploy-ipfs + environment: + name: 'cf-dnslink' + url: "https://helia-io.ipns.dweb.link/" + steps: + - name: Update DNSLink + uses: ipfs/dnslink-action@v0.1 + with: + cid: ${{ needs.deploy-ipfs.outputs.cid }} + dnslink_domain: 'helia.io' + cf_record_id: ${{ secrets.CF_DNS_RECORD_ID }} + cf_zone_id: ${{ secrets.CF_DNS_ZONE_ID }} + cf_auth_token: ${{ secrets.CF_DNS_AUTH_TOKEN }} + github_token: ${{ github.token }} + set_github_status: true + + gh-pages: + if: | + github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.head_branch == 'main' + runs-on: 'ubuntu-latest' + permissions: + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source + environment: + name: 'github-pages' + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Download build artifact + uses: actions/download-artifact@v4 + with: + name: website-build-${{ github.event.workflow_run.id }} + path: website-build + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ github.token }} + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: website-build + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4