Skip to main content

Upload Artifact Action

The bffless/upload-artifact action uploads your build artifacts to BFFless.

Quick Start

- uses: bffless/upload-artifact@v1
with:
path: dist
api-url: ${{ vars.BFFLESS_URL }}
api-key: ${{ secrets.BFFLESS_API_KEY }}

Only 3 required inputs. Everything else is auto-detected from GitHub context.

Full Workflow Example

name: Deploy to BFFless

on:
push:
branches: [main]
pull_request:

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for commit timestamp detection

- uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install and build
run: |
npm ci
npm run build

- name: Deploy to BFFless
uses: bffless/upload-artifact@v1
with:
path: dist
api-url: ${{ vars.BFFLESS_URL }}
api-key: ${{ secrets.BFFLESS_API_KEY }}

Inputs

InputRequiredDefaultDescription
pathYes-Build directory to upload
api-urlYes-BFFless platform URL
api-keyYes-API key for authentication
repositoryNoCurrent repoRepository in owner/repo format
commit-shaNoAuto-detectedGit commit SHA
branchNoAuto-detectedBranch name
is-publicNotruePublic visibility
aliasNo-Deployment alias (e.g., production)
base-pathNo/<path>Path prefix in zip
committed-atNoAuto-detectedISO 8601 commit timestamp
descriptionNo-Human-readable description
proxy-rule-set-nameNo-Proxy rule set name
proxy-rule-set-idNo-Proxy rule set ID
tagsNo-Comma-separated tags
summaryNotrueWrite GitHub Step Summary
summary-titleNoDeployment SummarySummary heading
working-directoryNo.Working directory

Outputs

OutputDescription
deployment-urlPrimary URL (SHA-based)
sha-urlImmutable SHA-based URL
alias-urlAlias-based URL
branch-urlBranch-based URL
preview-urlPreview URL (if basePath provided)
deployment-idAPI deployment ID
file-countNumber of files uploaded
total-sizeTotal bytes uploaded
responseRaw JSON response

Using Outputs

- uses: bffless/upload-artifact@v1
id: deploy
with:
path: dist
api-url: ${{ vars.BFFLESS_URL }}
api-key: ${{ secrets.BFFLESS_API_KEY }}

- run: |
echo "SHA URL: ${{ steps.deploy.outputs.sha-url }}"
echo "Files: ${{ steps.deploy.outputs.file-count }}"
echo "Size: ${{ steps.deploy.outputs.total-size }} bytes"

Examples

PR Preview Deployments

Deploy previews for every pull request:

name: PR Preview

on:
pull_request:

jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- run: npm ci && npm run build

- uses: bffless/upload-artifact@v1
id: deploy
with:
path: dist
api-url: ${{ vars.BFFLESS_URL }}
api-key: ${{ secrets.BFFLESS_API_KEY }}
alias: preview
description: 'PR #${{ github.event.pull_request.number }} preview'

- name: Comment PR
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '🚀 Preview deployed: ${{ steps.deploy.outputs.sha-url }}'
})

Production Deployments

Deploy to production on main branch:

name: Production Deploy

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- run: npm ci && npm run build

- uses: bffless/upload-artifact@v1
id: deploy
with:
path: dist
api-url: ${{ vars.BFFLESS_URL }}
api-key: ${{ secrets.BFFLESS_API_KEY }}
alias: production
description: 'Production deploy from ${{ github.sha }}'

- run: echo "Deployed to ${{ steps.deploy.outputs.alias-url }}"

Monorepo with Multiple Apps

Deploy multiple apps from the same repository:

jobs:
deploy-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- run: npm ci && npm run build:frontend

- uses: bffless/upload-artifact@v1
with:
path: apps/frontend/dist
api-url: ${{ vars.BFFLESS_URL }}
api-key: ${{ secrets.BFFLESS_API_KEY }}
alias: frontend-production

deploy-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- run: npm ci && npm run build:docs

- uses: bffless/upload-artifact@v1
with:
path: docs/build
api-url: ${{ vars.BFFLESS_URL }}
api-key: ${{ secrets.BFFLESS_API_KEY }}
alias: docs-production
base-path: /docs/build

With Proxy Rules

Apply proxy rules for API routing:

- uses: bffless/upload-artifact@v1
with:
path: dist
api-url: ${{ vars.BFFLESS_URL }}
api-key: ${{ secrets.BFFLESS_API_KEY }}
proxy-rule-set-name: api-proxy

How It Works

  1. Validates the build directory exists and is non-empty
  2. Zips the directory preserving path structure
  3. Uploads via multipart POST to /api/deployments/zip
  4. Sets outputs from the API response
  5. Writes Step Summary with deployment info
  6. Cleans up the temporary zip file

Auto-Detection

The action automatically detects:

  • Repository: from github.repository
  • Commit SHA: PR events use pull_request.head.sha, push events use github.sha
  • Branch: PR events use pull_request.head.ref, push events extract from github.ref
  • Committed At: runs git log -1 --format=%cI (requires fetch-depth: 0)
  • Base Path: derived from the path input

Troubleshooting

"Committed At" Not Detected

Ensure you're using fetch-depth: 0 in checkout:

- uses: actions/checkout@v4
with:
fetch-depth: 0 # Required for git log

Upload Failed - 401 Unauthorized

  • Verify your API key is correct
  • Check the key hasn't been revoked
  • Ensure BFFLESS_API_KEY secret is set

Upload Failed - 404 Not Found

  • Verify BFFLESS_URL is correct
  • Check your BFFless instance is running
  • Ensure the URL includes the protocol (https://)

Build Directory Empty

  • Verify your build command completed successfully
  • Check the path input matches your build output directory
  • Use working-directory if building in a subdirectory