shared-actions/publish-static-contents
Michael Seele c690178858
All checks were successful
validate-shared-actions / validate-shared-actions (pull_request) Successful in 29s
Aikido Security PR Check / Aikido Security Scan (pull_request) Successful in 1m17s
feat: add per-file cache_rules and fix argument escaping
- Add cache_rules input: JSON array of per-file cache overrides, each uploaded individually with its own Cache-Control and Content-Type headers and excluded from the bulk sync
- When versioning is true and cache_rules is empty, auto short-cache index.html (no-cache, max-age=300) if it exists in dist_dir
- Fix EXCLUDE_ARGS and CT_ARG to use bash arrays for correct handling of filenames and content-type values containing spaces
2026-05-22 05:06:42 +00:00
..
action.yml feat: add per-file cache_rules and fix argument escaping 2026-05-22 05:06:42 +00:00
README.md feat: add per-file cache_rules and fix argument escaping 2026-05-22 05:06:42 +00:00

publish-static-contents

Syncs frontend assets to S3 and invalidates a CloudFront distribution. Optionally manages versioned static builds by cleaning up old versions.

Inputs

Input Required Default Description
dist_dir No frontend/dist Path to the frontend dist directory
s3_bucket_name Yes Name of the S3 bucket to sync assets to
cloudfront_distribution_ids No '' Space-separated list of CloudFront distribution IDs to invalidate
versioning No false When true, enables versioned builds. All assets get Cache-Control: public, max-age=31536000, immutable. Old versions older than 7 days are deleted, keeping at least the 2 newest
versioning_prefix No '' S3 prefix under which versioned builds are stored (e.g. _static_static/1234567890/). Requires versioning: true
cache_rules No [] JSON array of per-file cache overrides. Each matched file is uploaded individually with the given headers and excluded from the bulk sync. When versioning is true and cache_rules is empty and index.html exists, defaults to short-caching index.html

Usage

Plain sync:

- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/publish-static-contents@publish-static-contents-v1
  with:
    s3_bucket_name: my-bucket
    cloudfront_distribution_ids: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}

With versioned static assets:

- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/publish-static-contents@publish-static-contents-v1
  with:
    s3_bucket_name: my-bucket
    cloudfront_distribution_ids: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}
    versioning: true

With versioned static assets under a prefix:

- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/publish-static-contents@publish-static-contents-v1
  with:
    s3_bucket_name: my-bucket
    cloudfront_distribution_ids: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}
    versioning: true
    versioning_prefix: _static

With custom per-file cache rules (e.g. for a PWA):

- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/publish-static-contents@publish-static-contents-v1
  with:
    s3_bucket_name: my-bucket
    cloudfront_distribution_ids: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}
    versioning: true
    cache_rules: |
      [
        {"file": "index.html", "cache_control": "no-cache, no-store, must-revalidate", "content_type": "text/html"},
        {"file": "sw.js", "cache_control": "no-cache, no-store, must-revalidate", "content_type": "application/javascript"},
        {"file": "manifest.webmanifest", "cache_control": "no-cache, max-age=300", "content_type": "application/manifest+json"}
      ]

Notes

  • When versioning is true and cache_rules is empty, index.html is automatically short-cached (no-cache, max-age=300) if it exists in the dist directory.
  • cache_rules works independently of versioning and can be used for plain syncs too.
  • Old versioned builds are pruned: any version folder older than 7 days is deleted, with at least the 2 newest versions always retained.
  • CloudFront invalidation is skipped when cloudfront_distribution_ids is empty.