{"id":26995921,"url":"https://github.com/ipshipyard/ipfs-deploy-action","last_synced_at":"2026-01-16T12:28:36.883Z","repository":{"id":275173702,"uuid":"924776151","full_name":"ipshipyard/ipfs-deploy-action","owner":"ipshipyard","description":"Official IPFS GitHub Action for deploying static sites (or builds) to IPFS nodes/pinning services with CAR files, and addressing site builds with CIDs","archived":false,"fork":false,"pushed_at":"2026-01-14T18:12:57.000Z","size":332,"stargazers_count":50,"open_issues_count":9,"forks_count":14,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-15T08:39:02.295Z","etag":null,"topics":["actions","car-file","cid","deploy","github","ipfs","ipfs-cluster","kubo","pinata","storacha","upload"],"latest_commit_sha":null,"homepage":"https://github.com/marketplace/actions/deploy-to-ipfs","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ipshipyard.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-30T16:26:10.000Z","updated_at":"2026-01-14T18:13:15.000Z","dependencies_parsed_at":"2025-01-31T17:33:56.644Z","dependency_job_id":"1e53e919-661a-4731-8db7-2c73ccd316cb","html_url":"https://github.com/ipshipyard/ipfs-deploy-action","commit_stats":null,"previous_names":["ipfs/ipfs-deploy-action","ipshipyard/ipfs-deploy-action"],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/ipshipyard/ipfs-deploy-action","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipshipyard%2Fipfs-deploy-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipshipyard%2Fipfs-deploy-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipshipyard%2Fipfs-deploy-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipshipyard%2Fipfs-deploy-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ipshipyard","download_url":"https://codeload.github.com/ipshipyard/ipfs-deploy-action/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipshipyard%2Fipfs-deploy-action/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28478650,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","car-file","cid","deploy","github","ipfs","ipfs-cluster","kubo","pinata","storacha","upload"],"created_at":"2025-04-04T01:16:34.552Z","updated_at":"2026-01-16T12:28:36.876Z","avatar_url":"https://github.com/ipshipyard.png","language":null,"readme":"# Deploy to IPFS Action\n\nThis GitHub Action automates the deployment of static sites to IPFS using [CAR files](https://docs.ipfs.tech/concepts/glossary/#car). It pins to either Kubo, IPFS Cluster, or [Storacha](https://storacha.network), as well as supporting additional pinning to [Pinata](https://pinata.cloud). The action will automatically create a preview link and update your PR/commit status with the deployment information.\n\nThis action is built and maintained by [Interplanetary Shipyard](http://ipshipyard.com/).\n\u003ca href=\"http://ipshipyard.com/\"\u003e\u003cimg align=\"right\" src=\"https://github.com/user-attachments/assets/39ed3504-bb71-47f6-9bf8-cb9a1698f272\" /\u003e\u003c/a\u003e\n\nThe [composite action](https://docs.github.com/en/actions/sharing-automations/creating-actions/about-custom-actions#composite-actions) makes no assumptions about your build process. You should just run your build and then call this action (as a step in an existing job) with the `path-to-deploy` input set to the path of your build output directory.\n\n![Setting commit status](./screenshot-commit-status.png)\n\n![PR comment with CID and preview links](./screenshot-pr-comment.png)\n\n## Table of Contents\n\n- [Features](#features)\n- [How does this compare to the other IPFS actions?](#how-does-this-compare-to-the-other-ipfs-actions)\n- [Storacha configuration](#storacha-configuration)\n- [Inputs](#inputs)\n  - [Required Inputs](#required-inputs)\n  - [Optional Inputs](#optional-inputs)\n- [Outputs](#outputs)\n- [Usage](#usage)\n  - [Simple Workflow (No Fork PRs)](#simple-workflow-no-fork-prs)\n  - [Dual Workflows (With Fork PRs)](#dual-workflows-with-fork-prs)\n- [FAQ](#faq)\n\n## Features\n\n- 📦 Merkleizes your static site into a CAR file\n- 🚀 Uploads CAR file to either Storacha, IPFS Cluster, or Kubo\n- 📍 Optional pinning to Pinata\n- 💾 Optional CAR file upload to Filebase\n- 📤 CAR file attached to Github Action run Summary page\n- 🔗 Automatic preview links\n- 💬 Optional PR comments with CID and preview links\n- ✅ Optional commit status updates with build CID\n\n## How does this compare to the other IPFS actions?\n\nThis action encapsulates the established best practices for deploying static sites to IPFS in 2025\n\n- Merkleizes the build into a CAR file in GitHub Actions using `ipfs-car`. This ensures that the CID is generated in the build process and is the same across multiple providers.\n- Uploads the CAR file to IPFS via [Storacha](https://storacha.network).\n- Optionally pins the CID of the CAR file to Pinata. This is useful for redundancy (multiple providers). The pinning here is done in the background and non-blocking. (When pinning, Pinata will fetch the data from Storacha.)\n- Updates the PR/commit status with the deployment information and preview links.\n\n## Storacha configuration\n\nTo set up Storacha, you will need to install [@storacha/cli](https://github.com/storacha/upload-service/tree/main/packages/cli) and login with your Storacha account.\n\nOnce logged in:\n\n- [Create a new space](https://docs.storacha.network/how-to/ci/#create-a-space) (like an S3 bucket) to which you will upload the merkleized CAR files.\n- [Create a signing key](https://docs.storacha.network/how-to/ci/#create-a-signing-key) that will be used in CI to sign requests to Storacha.\n- [Create a UCAN proof](https://docs.storacha.network/how-to/ci/#create-a-proof) that will be used in CI to sign requests to Storacha.\n\nThe signing key and proof will be used as [inputs](#inputs) to the action.\n\n## Inputs\n\n### Required Inputs\n\n| Input              | Description                                                                                                                                                                                                  |\n| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `path-to-deploy`   | Path to the directory containing the frontend build to merkleize into a CAR file and deploy to IPFS                                                                                                          |\n| `github-token`     | GitHub token for updating commit status and PR comments                                                                                                                                                      |\n| `kubo-api-url`     | Kubo RPC API URL to pass to `ipfs --api`, e.g. `/dns/YOUR_DOMAIN/tcp/443/https`                                                                                                                              |\n| `kubo-api-auth`    | Kubo RPC API auth secret to pass to `ipfs --api-auth`, e.g. `basic:hello:world` (defined as `AuthSecret` in `API.Authorizations` config)                                                                     |\n| `cluster-url`      | IPFS Cluster URL to pass to `ipfs-cluster-ctl --host`                                                                                                                                                        |\n| `cluster-user`     | IPFS Cluster username for basic http auth                                                                                                                                                                    |\n| `cluster-password` | IPFS Cluster password for basic http auth                                                                                                                                                                    |\n| `storacha-key`     | Storacha base64 encoded key to use to sign UCAN invocations. Create one using `storacha key create --json` (and use `key` from the output). See: https://github.com/storacha/upload-service/tree/main/packages/cli#storacha_principal |\n| `storacha-proof`   | Storacha Base64 encoded proof UCAN with capabilities for the space. Create one using `storacha delegation create did:key:DID_OF_KEY -c space/blob/add -c space/index/add -c filecoin/offer -c upload/add --base64` |\n\n\u003e [!IMPORTANT]\n\u003e To use this action, you must configure the inputs for either: **Kubo, IPFS Cluster, or Storacha**.\n\u003e\n\u003e - Kubo: `kubo-api-url` and `kubo-api-auth`\n\u003e - IPFS Cluster: `cluster-url`, `cluster-user`, `cluster-password`\n\u003e - Storacha: `storacha-key`, `storacha-proof`\n\u003e\n\u003e Pinata can only be used in addition (but not exclusively) to the above providers/nodes. This may change in the future if Pinata adds support for CAR uploads.\n\n### Optional Inputs\n\n| Input                     | Description                                                                                                                                         | Default                                    |\n| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |\n| `node-version`            | Node.js version to use                                                                                                                              | `'20'`                                     |\n| `cluster-ctl-version`     | IPFS Cluster CLI version to use                                                                                                                     | `'v1.1.2'`                                 |\n| `kubo-version`            | Kubo CLI version to use for pinning API and CAR uploads                                                                                             | `'v0.33.0'`                                |\n| `ipfs-add-options`        | Options to pass to `ipfs add` command that is used to merkleize the build. See [ipfs add docs](https://docs.ipfs.tech/reference/kubo/cli/#ipfs-add) | `'--cid-version 1 --chunker size-1048576'` |\n| `pinata-pinning-url`      | Pinata Pinning Service URL                                                                                                                          | `'https://api.pinata.cloud/psa'`           |\n| `pinata-jwt-token`        | Pinata JWT token for authentication                                                                                                                 | -                                          |\n| `filebase-bucket`         | Filebase bucket name                                                                                                                                | -                                          |\n| `filebase-access-key`     | Filebase access key                                                                                                                                 | -                                          |\n| `filebase-secret-key`     | Filebase secret key                                                                                                                                 | -                                          |\n| `set-github-status`       | Set GitHub commit status with build CID. Use \"true\" or \"false\" (as strings)                                                                         | `'true'`                                   |\n| `set-pr-comment`          | Set PR comments with IPFS deployment information. Use \"true\" or \"false\" (as strings)                                                                | `'true'`                                   |\n| `github-status-gw`        | Gateway to use for the links in commit status updates (The green checkmark with the CID)                                                            | `'inbrowser.link'`                         |\n| `upload-car-artifact`     | Upload and publish the CAR file on GitHub Action Summary pages                                                                                      | `'true'`                                   |\n| `cluster-retry-attempts`  | Number of retry attempts for IPFS Cluster uploads                                                                                                   | `'5'`                                      |\n| `cluster-timeout-minutes` | Timeout in minutes for each IPFS Cluster upload attempt                                                                                             | `'2'`                                      |\n| `cluster-pin-expire-in`   | Time duration after which the pin will expire in IPFS Cluster (e.g. 720h for 30 days). If unset, the CID will be pinned with no expiry.             | -                                          |\n| `pin-name`                | Custom name for the pin. If unset, defaults to \"{repo-name}-{commit-sha-short}\" for both IPFS Cluster and Pinata.                                   | -                                          |\n\n## Outputs\n\n| Output | Description                          |\n| ------ | ------------------------------------ |\n| `cid`  | The IPFS CID of the uploaded content |\n\n## Usage\n\n### Simple Workflow (No Fork PRs)\n\nFor repositories that don't accept PRs from forks, you can use a single workflow:\n\n```yaml\nname: Build and Deploy to IPFS\n\npermissions:\n  contents: read\n  pull-requests: write\n  statuses: write\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n\njobs:\n  build-and-deploy:\n    runs-on: ubuntu-latest\n    outputs:\n      cid: ${{ steps.deploy.outputs.cid }}\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n          cache: 'npm'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Build project\n        run: npm run build\n\n      - name: Deploy to IPFS\n        uses: ipfs/ipfs-deploy-action@v1\n        id: deploy\n        with:\n          path-to-deploy: out\n          storacha-key: ${{ secrets.STORACHA_KEY }}\n          storacha-proof: ${{ secrets.STORACHA_PROOF }}\n          github-token: ${{ github.token }}\n```\n\n### Dual Workflows (With Fork PRs)\n\nFor secure deployments of PRs from forks, use two separate workflows that pass artifacts between them:\n\n**`.github/workflows/build.yml`** - Builds without secrets access:\n```yaml\nname: Build\n\npermissions:\n  contents: read\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n      - main\n\nenv:\n  BUILD_PATH: 'out'  # Update this to your build output directory\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          ref: ${{ github.event_name == 'pull_request' \u0026\u0026 github.event.pull_request.head.sha || github.sha }}\n\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n          cache: 'npm'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Build project\n        run: npm run build\n\n      - name: Upload build artifact\n        uses: actions/upload-artifact@v4\n        with:\n          name: website-build-${{ github.run_id }}\n          path: ${{ env.BUILD_PATH }}\n          retention-days: 1\n```\n\n**`.github/workflows/deploy.yml`** - Deploys with secrets access:\n```yaml\nname: Deploy\n\npermissions:\n  contents: read\n  pull-requests: write\n  statuses: write\n\non:\n  workflow_run:\n    workflows: [\"Build\"]\n    types: [completed]\n\nenv:\n  BUILD_PATH: 'website-build'  # Directory where artifact from build.yml will be unpacked\n\njobs:\n  deploy-ipfs:\n    if: github.event.workflow_run.conclusion == 'success'\n    runs-on: ubuntu-latest\n    outputs:\n      cid: ${{ steps.deploy.outputs.cid }}\n    steps:\n      - name: Download build artifact\n        uses: actions/download-artifact@v4\n        with:\n          name: website-build-${{ github.event.workflow_run.id }}\n          path: ${{ env.BUILD_PATH }}\n          run-id: ${{ github.event.workflow_run.id }}\n          github-token: ${{ github.token }}\n\n      - name: Deploy to IPFS\n        uses: ipfs/ipfs-deploy-action@v1\n        id: deploy\n        with:\n          path-to-deploy: ${{ env.BUILD_PATH }}\n          storacha-key: ${{ secrets.STORACHA_KEY }}\n          storacha-proof: ${{ secrets.STORACHA_PROOF }}\n          github-token: ${{ github.token }}\n```\n\nSee real-world examples:\n- [IPFS Specs](https://github.com/ipfs/specs/tree/main/.github/workflows) - Uses the secure two-workflow pattern\n- [IPFS Docs](https://github.com/ipfs/ipfs-docs/tree/main/.github/workflows) - Uses the secure two-workflow pattern\n\n## FAQ\n\n- How can I safely build on PRs from forks?\n  - Use the two-workflow pattern shown above. The build workflow runs on untrusted fork code without secrets access, while the deploy workflow only runs after a successful build and has access to secrets but never executes untrusted code. This pattern uses GitHub's `workflow_run` event to securely pass artifacts between workflows.\n- What's the difference between uploading a CAR and using the Pinning API?\n  - Since the CAR is like a tarball of the full build with some additional metadata (merkle proofs), the upload will be as big as the build output. Pinning with the [Pinning API](https://github.com/ipfs/pinning-services-api-spec) in contrast is just a request to instruct the pinning service to retrieve and pin the data. At the time this action is first released, CAR uploads is supported by Kubo, Storacha, and Filebase, but not Pinata.\n- How can I update DNSLink?\n  - See https://github.com/ipfs/dnslink-action as a complement to this action.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipshipyard%2Fipfs-deploy-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fipshipyard%2Fipfs-deploy-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipshipyard%2Fipfs-deploy-action/lists"}