Skip to content
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

feat: publish succeess state & support base58 keys #3

Merged
merged 25 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 36 additions & 108 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build and Publish to IPFS
name: Build and Deploy to IPFS

# Explicitly declare permissions
permissions:
Expand All @@ -14,116 +14,44 @@ on:
branches:
- main

env:
NODE_VERSION: '20'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # Cancel in progress runs if a new run is started

jobs:
build:
build-and-deploy:
uses: ./.github/workflows/ipfs-deploy.yml
with:
node-version: '20'
kubo-version: 'v0.33.0-rc3'
build-command: 'npm run build'
build-output-dir: 'out'
pinata: true
secrets:
STORACHA_KEY: ${{ secrets.STORACHA_KEY }}
STORACHA_PROOF: ${{ secrets.STORACHA_PROOF }}
PINATA_JWT_TOKEN: ${{ secrets.PINATA_JWT_TOKEN }}
update-dnslink:
runs-on: 'ubuntu-latest'
outputs:
cid: ${{ steps.merklize.outputs.cid }}
needs: build-and-deploy
if: github.ref == 'refs/heads/main' # only update for main branch
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'

- name: Install dependencies
run: |
npm ci
npm install -g ipfs-car

- name: Build project
run: npm run build

- name: Merkelize Build
id: merklize
- name: Update DNSLink
run: |
# Capture stderr to which the CID is printed. See https://github.com/storacha/ipfs-car/pull/169
CID=$(npx ipfs-car pack out --no-wrap --output build.car 2>&1 | tail -n 1)
echo "cid=$CID" >> "$GITHUB_OUTPUT"
echo $CID

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-output-car
path: build.car

publish-to-ipfs:
runs-on: 'ubuntu-latest'
needs: 'build'
if: success() && (github.event_name == 'push' || github.event_name == 'pull_request')
steps:
- name: Check required secrets
run: |
if [ -z "${{ secrets.STORACHA_KEY }}" ] || [ -z "${{ secrets.STORACHA_PROOF }}" ]; then
echo "::error::Missing required secrets STORACHA_KEY and/or STORACHA_PROOF"
exit 1
fi

- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-output-car

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}

- name: Configure and upload CAR to Storacha
echo "Updating DNSLink for: ${{ env.DNSLINK_NAME }}"
curl --request PUT \
--header "Authorization: Bearer ${AUTH_TOKEN}" \
--header 'Content-Type: application/json' \
--url "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \
--data "{
\"type\": \"TXT\",
\"name\": \"_dnslink.${DNSLINK_NAME}\",
\"content\": \"dnslink=/ipfs/${DNSLINK_CID}\",
\"comment\": \"${{ github.repository }}/${{ github.sha }}\"
}"
env:
W3_PRINCIPAL: ${{ secrets.STORACHA_KEY }}
run: |
npm install -g @web3-storage/w3cli
w3 space add ${{ secrets.STORACHA_PROOF }}
# Delete previous CARs - disabled for now
# w3 ls | while read -r cid; do
# w3 rm --shards "$cid"
# done
if ! w3 up --car build.car; then
echo "::error::Failed to upload to IPFS"
exit 1
fi

- name: Update commit status
uses: actions/github-script@v7
with:
script: |
const cid = '${{ needs.build.outputs.cid }}';
github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: context.sha,
state: 'success',
target_url: `https://w3s.link/ipfs/${cid}`,
description: `CID: ${cid}`,
context: 'IPFS Preview'
});

- name: Find Comment to update
if: github.event_name == 'pull_request'
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: '🚀 Build'

- name: Create or update comment
if: github.event_name == 'pull_request'
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### 🚀 Build Preview on IPFS ready
- 🔏 CID `${{ needs.build.outputs.cid }}`
- 📦 [Preview](https://w3s.link/ipfs/${{ needs.build.outputs.cid }})
- 🔗 [Service Worker Preview](https://inbrowser.link/ipfs/${{ needs.build.outputs.cid }})
edit-mode: replace
DNSLINK_NAME: 'ipns.ipfs.network'
DNSLINK_CID: ${{ needs.build-and-deploy.outputs.cid }}
ZONE_ID: ${{ secrets.CF_IPNS_NETWORK_ZONE_ID }}
RECORD_ID: ${{ secrets.CF_IPNS_NETWORK_RECORD_ID }}
AUTH_TOKEN: ${{ secrets.CF_IPNS_NETWORK_AUTH_TOKEN }}
209 changes: 209 additions & 0 deletions .github/workflows/ipfs-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
name: Build and Pin to IPFS

on:
workflow_call:
inputs:
node-version:
description: 'Node.js version to use'
default: '20'
required: false
type: string
kubo-version:
description: 'Kubo version to use for pinning https://dist.ipfs.tech/kubo/versions'
default: 'v0.33.0-rc3'
required: false
type: string
build-command:
description: 'Command to build the project'
default: 'npm run build'
required: false
type: string
build-output-dir:
description: 'Directory containing build output that will be merkelized'
default: 'out'
required: false
type: string
pinata:
description: 'Whether to pin builds to Pinata after uploading the CAR to Storacha'
default: false
required: false
type: boolean
pinata-pinning-url:
description: 'Pinata Pinning Service URL'
default: 'https://api.pinata.cloud/psa'
required: false
type: string
filebase-bucket:
description: 'Filebase bucket name'
required: false
type: string
filebase:
description: 'Whether to upload to Filebase (requires paid account for html uploads)'
default: false
required: false
type: boolean
secrets:
STORACHA_KEY:
required: true
STORACHA_PROOF:
required: true
FILEBASE_SECRET_KEY:
required: false
FILEBASE_ACCESS_KEY:
required: false
PINATA_JWT_TOKEN:
required: false
outputs:
cid:
description: 'The IPFS CID of the uploaded content'
value: ${{ jobs.build.outputs.cid }}

permissions:
contents: read
pull-requests: write
statuses: write

jobs:
build:
runs-on: 'ubuntu-latest'
outputs:
cid: ${{ steps.merklize.outputs.cid }}
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'

- name: Install dependencies
run: |
npm ci
npm install -g ipfs-car@2

- name: Build project
run: ${{ inputs.build-command }}

- name: Merkelize Build
id: merklize
run: |
CID=$(npx ipfs-car pack ${{ inputs.build-output-dir }} --no-wrap --output build.car 2>&1 | tail -n 1)
echo "cid=$CID" >> "$GITHUB_OUTPUT"
echo $CID

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-output-car
path: build.car

upload-car-to-storacha:
runs-on: 'ubuntu-latest'
needs: 'build'
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-output-car

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}

- name: Configure and upload CAR to Storacha
env:
W3_PRINCIPAL: ${{ secrets.STORACHA_KEY }}
run: |
npm install -g @web3-storage/w3cli
w3 space add ${{ secrets.STORACHA_PROOF }}
if ! w3 up --car build.car; then
echo "::error::Failed to upload to IPFS"
exit 1
fi
# Upload the CAR to Filebase
upload-car-to-filebase:
runs-on: 'ubuntu-latest'
needs: 'build'
if: inputs.filebase
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-output-car

- name: Upload CAR to Filebase
env:
AWS_ACCESS_KEY_ID: ${{ secrets.FILEBASE_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.FILEBASE_SECRET_KEY }}
FILEBASE_BUCKET: ${{ inputs.filebase-bucket }}
run: |
aws --endpoint https://s3.filebase.com s3 cp build.car s3://${FILEBASE_BUCKET} --metadata 'import=car'

# Once CAR has been uploaded to storacha, pin it to Pinata so we have multiple providers.
# With the Pinning API, we just instruct Pinata to fetch and pin the blocks of the build.
# Uploading CAR would be better (since its explciit) but Pinata doesn't support CAR uploads
pin-cid-to-pinata:
runs-on: 'ubuntu-latest'
needs: ['build', 'upload-car-to-storacha']
if: inputs.pinata
steps:
- uses: ipfs/download-ipfs-distribution-action@v1
with:
name: kubo
version: '${{ inputs.kubo-version }}'
- name: Pin CID to Pinata
run: |
ipfs init
ipfs pin remote service add pinata "${{ inputs.pinata-pinning-url }}" ${{ secrets.PINATA_JWT_TOKEN }}
ipfs pin remote add --service=pinata --name="build-${{ github.event.pull_request.head.sha }}" ${{ needs.build.outputs.cid }}

update-commit-status:
runs-on: 'ubuntu-latest'
needs: ['build', 'upload-car-to-storacha']
steps:
- name: Update commit status
uses: actions/github-script@v7
with:
script: |
const cid = '${{ needs.build.outputs.cid }}';

// For PR events, we need to use the head SHA
const sha = context.eventName === 'pull_request'
? context.payload.pull_request.head.sha
: context.sha;

await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: sha,
state: 'success',
target_url: `https://w3s.link/ipfs/${cid}`,
description: `CID: ${cid}`,
context: 'IPFS Preview'
});

- name: Find Comment to update
if: github.event_name == 'pull_request'
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: '🚀 Build'

- name: Create or update comment
if: github.event_name == 'pull_request'
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
### 🚀 Build Preview on IPFS ready
- 🔎 Commit: ${{ github.event.pull_request.head.sha }}
- 🔏 CID `${{ needs.build.outputs.cid }}`
- 📦 [Preview](https://w3s.link/ipfs/${{ needs.build.outputs.cid }})
- 🔗 [Service Worker Preview](https://inbrowser.link/ipfs/${{ needs.build.outputs.cid }})
edit-mode: replace
Loading