{"id":26995921,"url":"https://github.com/ipshipyard/ipfs-deploy-action","last_synced_at":"2026-04-03T23:05:56.673Z","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-04-03T23:05:56.657Z","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 [IPFS Cluster](https://ipfscluster.io/) or a single [Kubo](https://github.com/ipfs/kubo) instance, as well as supporting additional pinning to [Pinata](https://pinata.cloud) and [Filebase](https://filebase.com). 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](https://ipshipyard.com/).\n\u003ca href=\"https://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- [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 IPFS Cluster or a single Kubo instance\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.\n\n- Merkleizes the build into a CAR file in GitHub Actions using Kubo. 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 IPFS Cluster or a single Kubo instance.\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.\n- Updates the PR/commit status with the deployment information and preview links.\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\n### CAR Upload Provider (at least one required)\n\n\u003e [!IMPORTANT]\n\u003e You must configure at least one of the CAR upload providers below. Pinata cannot be the sole provider until CAR upload support is tested ([ipshipyard/ipfs-deploy-action#42](https://github.com/ipshipyard/ipfs-deploy-action/pull/42)).\n\n#### IPFS Cluster\n\n[ipfscluster.io](https://ipfscluster.io/)\n\n| Input              | Description                                      |\n| ------------------ | ------------------------------------------------ |\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\n#### Kubo\n\n[github.com/ipfs/kubo](https://github.com/ipfs/kubo) · [RPC API docs](https://docs.ipfs.tech/reference/kubo/rpc/)\n\n| Input           | Description                                                                                          |\n| --------------- | ---------------------------------------------------------------------------------------------------- |\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\n#### Filebase\n\n[filebase.com](https://filebase.com)\n\n| Input                | Description        |\n| -------------------- | ------------------ |\n| `filebase-access-key` | Filebase access key |\n| `filebase-secret-key` | Filebase secret key |\n| `filebase-bucket`     | Filebase bucket name |\n\n#### Storacha (deprecated)\n\n\u003e [!WARNING]\n\u003e [Storacha uploads will stop working on April 15, 2026.](https://medium.com/@storacha/an-update-on-storacha-and-important-news-for-you-and-your-data-15a5d10b7da0) Please switch to an alternative provider.\n\n| Input            | Description                          |\n| ---------------- | ------------------------------------ |\n| `storacha-key`   | Storacha base64 encoded key          |\n| `storacha-proof` | Storacha Base64 encoded proof UCAN   |\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| `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          cluster-url: ${{ secrets.CLUSTER_URL }}\n          cluster-user: ${{ secrets.CLUSTER_USER }}\n          cluster-password: ${{ secrets.CLUSTER_PASSWORD }}\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          cluster-url: ${{ secrets.CLUSTER_URL }}\n          cluster-user: ${{ secrets.CLUSTER_USER }}\n          cluster-password: ${{ secrets.CLUSTER_PASSWORD }}\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. CAR uploads are supported by Kubo, IPFS Cluster, and Filebase.\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"}