feat: add filecoin-pin CLI as built-in CAR upload provider#51
Conversation
Wires `filecoin-pin import` into action.yml as a peer to IPFS Cluster, Kubo, and Filebase, so setting `filecoin-wallet-key` satisfies the at-least-one-provider gate. Same root CID is preserved (no repacking). New inputs: - `filecoin-wallet-key`: gates the entire upload step. - `filecoin-network`: defaults to `mainnet`; set `calibnet` for testing. - `filecoin-min-runway-days`, `filecoin-max-balance`: required when wallet key is set, no defaults. Both cap wallet spend per run; the right value depends on the caller's traffic and budget, so we force an explicit choice rather than picking one that could drain a wallet. - `filecoin-pin-version`: pinned to `0.20.1` (first release with `--min-runway-days` and `--max-balance` on `--auto-fund`). The step bakes in a fork-PR fence (same-repo events only), so a non-maintainer PR author cannot trigger USDFC deposits. action.yml top-level description drops the stale Storacha mention and now lists the active providers. Storacha-specific code paths are otherwise untouched and remain deprecated; full removal is a separate concern. Companion to #49 (docs-only composition recipe). Both branches are intended to be shown to upstream maintainers to choose between.
| # Block fork PRs from this wallet-spending step: same-repo events only, | ||
| # so non-maintainer authors cannot trigger USDFC deposits. | ||
| if: ${{ inputs.filecoin-wallet-key != '' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }} |
There was a problem hiding this comment.
The step bakes in a fork-PR fence (same-repo events only), so a non-maintainer PR author cannot trigger USDFC deposits, but we dont have that limitation for other pin providers, so maybe not necessary?
There was a problem hiding this comment.
I think not necessary as long as you clearly document the implications. Let's it potentially behave like other "deploy and preview" services if you're willing to pay for it, but make sure they're willing cause a contributor could cost you a lot, but then you have "approve" for GHA now.
| # Capture output so we can dump it in the step summary even on failure | ||
| # (debugging insufficient USDFC, runway, provider issues, etc). | ||
| EXIT=0 | ||
| npx -y filecoin-pin@${{ inputs.filecoin-pin-version }} import build.car \ |
There was a problem hiding this comment.
I can't find any hard constraint, we have no "engines" but we don't test 20, we do test lts/* though but that recently got bumped to 24.
I think 20 should be fine, our imports are all 20 compatible at the moment, if we must enforce this we could add it in our CI. Node.js 20 did leave maintenance at the end of last month though, so it's already old enough to retire, maybe this action should be proactive and install newer?
There was a problem hiding this comment.
I think we could add a cache in the action somewhere, maybe if it's based on actions/setup-node, to avoid having to download and reinstall filecoin-pin and all its dependencies every time it's run
but in #49 you said
What is the preferred shape of this? is there an in-between you'd rather? Do we need to expose the guts of filecoin-pin better to let you code it directly? You have Filebase already and did have Pinata, was it the same problem with those? |
| # (debugging insufficient USDFC, runway, provider issues, etc). | ||
| EXIT=0 | ||
| npx -y filecoin-pin@${{ inputs.filecoin-pin-version }} import build.car \ | ||
| --${{ inputs.filecoin-network }} \ |
There was a problem hiding this comment.
| --${{ inputs.filecoin-network }} \ | |
| --network ${{ inputs.filecoin-network }} \ |
| | `cluster-timeout-minutes` | Timeout in minutes for each IPFS Cluster upload attempt | `'2'` | | ||
| | `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. | - | | ||
| | `pin-name` | Custom name for the pin. If unset, defaults to "{repo-name}-{commit-sha-short}" for both IPFS Cluster and Pinata. | - | | ||
| | `filecoin-network` | Filecoin network for `filecoin-pin`: `mainnet` or `calibnet` | `'mainnet'` | |
There was a problem hiding this comment.
| | `filecoin-network` | Filecoin network for `filecoin-pin`: `mainnet` or `calibnet` | `'mainnet'` | | |
| | `filecoin-network` | Filecoin network for `filecoin-pin`: `mainnet` or `calibration` | `'mainnet'` | |
fwiw I've opened an issue to allow calibnet but currently calibration is the correct form
| description: 'Filecoin wallet private key (passed via PRIVATE_KEY env). Enables CAR upload to a Filecoin storage provider via filecoin-pin import. Fund the wallet with FIL (gas) and USDFC (storage). Fork PRs skip this step so untrusted contributors cannot trigger wallet deposits.' | ||
| required: false | ||
| filecoin-network: | ||
| description: 'Filecoin network for filecoin-pin: mainnet or calibnet' |
There was a problem hiding this comment.
| description: 'Filecoin network for filecoin-pin: mainnet or calibnet' | |
| description: 'Filecoin network for filecoin-pin: mainnet or calibration' |
| --max-balance ${{ inputs.filecoin-max-balance }} 2>&1 | tee filecoin-pin.log || EXIT=$? | ||
|
|
||
| if [ "$EXIT" -eq 0 ]; then | ||
| HEADLINE="✅ Uploaded CAR with CID \`${{ steps.merkleize.outputs.cid }}\` to Filecoin (\`${{ inputs.filecoin-network }}\`)" |
There was a problem hiding this comment.
there is more we can add to this output, a successful filecoin-pin.log should be greppable; I'll attach a successful log output to this PR so you can see what's possible. At a minimum it would be good to show something about the providers and and/or data set IDs, even inbrowser.link URL would be neat. We could get more sophisticated with links to dashboard to show on-chain stuff but we can start simple.
successful filecoin-pin.log exampleFilecoin Pin Add ✓ Directory validated ✓ Connected to Filecoin - Calibration testnet ✓ Minimum payment setup verified (~0.066 USDFC required) ✓ Directory packed with root CID: bafybeichpyg7nzco3ef733ipvg4st36nphydv3d6uwyst7jdcz6xr3oe7a ✓ IPFS content loaded (1.6 MiB) ✓ Payment capacity verified for 1.6 MiB ✓ [Primary] Stored on provider 4 ✓ [Secondary] Stored on provider 2 ✓ [Secondary] Piece added to Data Set (unconfirmed on-chain) Tx: https://calibration.filfox.info/en/message/0xe7a29c03a94af8f6d502d8b3aa0fa29d2ba5c44fd74e574efd42f040f3ace7c4 Tx: https://calibration.filfox.info/en/message/0x8cc61051b0c184d0587a06cf0eebb5f50c79bac6a08e1f82857fd933b49469cb IPFS Retrieval URLs ✓ [Primary] Piece added to Data Set (confirmed on-chain) ✓ [Secondary] Piece added to Data Set (confirmed on-chain) ━━━ Add Complete ━━━ Network: Filecoin - Calibration testnet Add Details Filecoin Storage Copies this is with calibnet so we can't assume that but things we could pull out of here:
|
v2 drops native Pinata, Filebase, and Storacha steps and moves third-party pinning to recipes under docs/recipes/ that run as user steps against the same CAR. Users on @v1 are unaffected until they bump to @v2; bumping without migrating errors fast with a step-summary migration table. Closes #39 (filecoin-pin via docs/recipes/filecoin-pin.md) Closes #49 (docs-only filecoin-pin proposal, this PR adopts it) Closes #51 (native filecoin-pin wrap, rejected in favor of the recipe) Supersedes #47 (car-file-name input adopted) - action.yml: drop pinata/filebase/storacha inputs and steps; add cid-profile input (default unixfs-v1-2025 per IPIP-0499); bump kubo-version default to v0.41.0; default ipfs-add-options to '' so the profile governs CID generation; add car-file-name input (default 'build.car'); flip set-pr-comment and set-github-status defaults to '' so they post only when kubo or cluster is configured; add validation step that errors on partial Cluster or Kubo configs (no silent skips); add a compute-reporting-flags step that DRYs the comment/status auto-on logic; expose car-path and car-artifact-name outputs; trap step errors with a migration table when v1 inputs are still passed. Shell-side service inputs routed through env with an INPUT_ prefix so they cannot collide with user-set secrets. - docs/recipes/: filecoin-pin (CLI), pinata (V3 Files API), filebase (S3 endpoint with import=car). Recipes use the car-path output, ship with explicit cid-profile, and leave fork-PR gating to the workflow author. - README: lead and Features rewritten around CAR + own-infra pinning; v2 callout; new Pinning to external services section linking to the recipes; FAQ entry for the migration error. Workflow examples reference @v2 and use a generic make-build placeholder. - CHANGELOG: v2.0.0 Unreleased entry with per-input migration table. - All cross-file links in markdown use absolute GitHub URLs so they render on the Marketplace page and in release notes.
v2 narrows this action to the merkleization stage: turning your site into a CAR file with a deterministic root CID under your CI. Once the CAR exists, pinning is composable. Pin to your own Kubo or IPFS Cluster natively, or pass the same CAR to Filecoin, Pinata, Filebase, or anywhere else as a follow-up step. Users on @v1 are unaffected until they bump. Closes #39 (filecoin-pin via docs/recipes/filecoin-pin.md) Closes #49 (docs-only filecoin-pin proposal, this PR adopts it) Closes #51 (native filecoin-pin wrap, rejected in favor of the recipe) Supersedes #47 (car-file-name input adopted) - action.yml: drop pinata/filebase/storacha inputs and steps; add cid-profile input (default unixfs-v1-2025 per IPIP-0499); bump kubo-version default to v0.41.0; default ipfs-add-options to '' so the profile governs CID generation; add car-file-name input (default 'build.car'); flip set-pr-comment and set-github-status defaults to '' so they post only when kubo or cluster is configured; add validation step that errors on partial Cluster or Kubo configs (no silent skips); add a compute-reporting-flags step that DRYs the comment/status auto-on logic; expose car-path and car-artifact-name outputs; trap step errors with a migration table when v1 inputs are still passed. Shell-side service inputs routed through env with an INPUT_ prefix so they cannot collide with user-set secrets. - docs/recipes/: filecoin-pin (CLI), pinata (V3 Files API), filebase (S3 endpoint with import=car). Recipes use the car-path output, ship with explicit cid-profile, and leave fork-PR gating to the workflow author. - README: lead and How-does-this-compare rewritten around the merkleization-ownership framing; v2 callout; new Pinning to external services section linking to the recipes; FAQ entry for the migration error. Workflow examples reference @v2 and use a generic make-build placeholder. - CHANGELOG: v2.0.0 entry in announcement style (What you can do now / Backward compatibility / Breaking changes) with per-input migration table. - All cross-file links in markdown use absolute GitHub URLs.
|
Closing this one in favor of #53. Thinking through the wallet caps, retry semantics, and step-summary details in this PR made it clear that those decisions belong with the Filecoin Pin team. They know the protocol, the economics, and their users better than this action can, and wedging the integration here would only slow their iteration. Moving to a docs recipe gives them room to ship without us in the middle. The CLI invocation worked out here shaped the initial stub at |
Wires
filecoin-pin importinto action.yml as a peer to IPFS Cluster, Kubo, and Filebase, so settingfilecoin-wallet-keysatisfies the at-least-one-provider gate.New inputs:
filecoin-wallet-key: gates the entire upload step.filecoin-network: defaults tomainnet; setcalibnetfor testing.filecoin-min-runway-days,filecoin-max-balance: required when wallet key is set, no defaults. Both cap wallet spend per run; the right value depends on the caller's traffic and budget, so we force an explicit choice rather than picking one that could drain a wallet.filecoin-pin-version: pinned to0.20.1(first release with--min-runway-daysand--max-balanceon--auto-fund).This is alternative to #49 (docs-only composition recipe). TBD which one is chosen -- cc @BigLep @rvagg @SgtPooki for visibility and feedback,
Important
I'm not a fan of this as it is just wrapping and shifting maintenance cost, triaging bug reports to this repo, instead of the repo where filecoin-pin CLI lives.