feat: add publish-static-contents action
This commit is contained in:
parent
8271a9b093
commit
0e441e6161
3 changed files with 120 additions and 0 deletions
|
|
@ -11,6 +11,7 @@ Shared actions for Forgejo CI/CD pipelines.
|
|||
| [aws-configure](aws-configure) | Authenticate with AWS via OIDC |
|
||||
| [checkout](checkout) | Action for checking out a repository |
|
||||
| [pnpm-build](pnpm-build) | Action for building and validating with PNPM |
|
||||
| [publish-static-contents](publish-static-contents) | Syncs frontend assets to S3 and invalidates a CloudFront distribution |
|
||||
|
||||
|
||||
## Security
|
||||
|
|
|
|||
39
publish-static-contents/README.md
Normal file
39
publish-static-contents/README.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# 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 |
|
||||
| `versioned_static_prefix` | No | `''` | S3 prefix under which versioned builds are stored (e.g. `_static`). When set, old versions older than 7 days are deleted, keeping at least the 2 newest |
|
||||
|
||||
## Usage
|
||||
|
||||
```yaml
|
||||
- uses: schmalz/shared-actions/.forgejo/actions/publish-static-contents@v1
|
||||
with:
|
||||
s3_bucket_name: my-bucket
|
||||
cloudfront_distribution_ids: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}
|
||||
```
|
||||
|
||||
With versioned static assets:
|
||||
|
||||
```yaml
|
||||
- uses: schmalz/shared-actions/.forgejo/actions/publish-static-contents@v1
|
||||
with:
|
||||
dist_dir: frontend/dist
|
||||
s3_bucket_name: my-bucket
|
||||
cloudfront_distribution_ids: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}
|
||||
versioned_static_prefix: _static
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- When `versioned_static_prefix` is set, all assets are synced with `Cache-Control: public, max-age=31536000, immutable`.
|
||||
- `index.html` is always synced separately with `Cache-Control: no-cache, max-age=300` so browsers pick up new deployments quickly.
|
||||
- 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.
|
||||
80
publish-static-contents/action.yml
Normal file
80
publish-static-contents/action.yml
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
name: Publish to CloudFront
|
||||
description: Syncs frontend assets to S3 and invalidates the CloudFront distribution
|
||||
|
||||
inputs:
|
||||
dist_dir:
|
||||
description: Path to the frontend dist directory
|
||||
required: false
|
||||
default: frontend/dist
|
||||
s3_bucket_name:
|
||||
description: Name of the S3 bucket to sync assets to
|
||||
required: true
|
||||
cloudfront_distribution_ids:
|
||||
description: Space-separated list of CloudFront distribution IDs to invalidate
|
||||
required: false
|
||||
default: ''
|
||||
versioned_static_prefix:
|
||||
description: S3 prefix under which versioned builds are stored (e.g. _static). When set, old versions older than 7 days are deleted, keeping at least the 2 newest.
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Publish frontend assets
|
||||
shell: bash
|
||||
env:
|
||||
INPUT_DIST_DIR: ${{ inputs.dist_dir }}
|
||||
INPUT_S3_BUCKET_NAME: ${{ inputs.s3_bucket_name }}
|
||||
INPUT_VERSIONED_STATIC_PREFIX: ${{ inputs.versioned_static_prefix }}
|
||||
run: |
|
||||
CACHE_CONTROL_ARG=""
|
||||
if [[ -n "${INPUT_VERSIONED_STATIC_PREFIX}" ]]; then
|
||||
CACHE_CONTROL_ARG="--cache-control 'public, max-age=31536000, immutable'"
|
||||
fi
|
||||
EXCLUDE_INDEX_ARG=""
|
||||
if [[ -n "${INPUT_VERSIONED_STATIC_PREFIX}" && -f "${INPUT_DIST_DIR}/index.html" ]]; then
|
||||
EXCLUDE_INDEX_ARG="--exclude index.html"
|
||||
fi
|
||||
aws s3 sync "${INPUT_DIST_DIR}" "s3://${INPUT_S3_BUCKET_NAME}" $CACHE_CONTROL_ARG $EXCLUDE_INDEX_ARG
|
||||
|
||||
- name: Publish index.html without immutable cache
|
||||
if: ${{ inputs.versioned_static_prefix != '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ -f "${INPUT_DIST_DIR}/index.html" ]]; then
|
||||
aws s3 cp "${INPUT_DIST_DIR}/index.html" "s3://${INPUT_S3_BUCKET_NAME}/index.html" \
|
||||
--cache-control "no-cache, max-age=300" \
|
||||
--metadata-directive REPLACE
|
||||
fi
|
||||
|
||||
- name: Clean up old versioned static builds
|
||||
if: ${{ inputs.versioned_static_prefix != '' }}
|
||||
shell: bash
|
||||
env:
|
||||
INPUT_S3_BUCKET_NAME: ${{ inputs.s3_bucket_name }}
|
||||
INPUT_VERSIONED_STATIC_PREFIX: ${{ inputs.versioned_static_prefix }}
|
||||
run: |
|
||||
aws s3 ls "s3://$INPUT_S3_BUCKET_NAME/$INPUT_VERSIONED_STATIC_PREFIX/" \
|
||||
| grep -oP '(?<=PRE )[0-9]+' \
|
||||
| sort --stable --reverse \
|
||||
| tail -n +3 \
|
||||
| while read version; do
|
||||
now=$(($(date +%s%N)/1000000))
|
||||
diff=$(($now-$version))
|
||||
# delete if older than 7 days
|
||||
if [ $diff -gt 604800000 ]; then
|
||||
echo "Deleting $version"
|
||||
aws s3 rm --recursive "s3://$INPUT_S3_BUCKET_NAME/$INPUT_VERSIONED_STATIC_PREFIX/$version"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Invalidate CloudFront
|
||||
if: ${{ inputs.cloudfront_distribution_ids != '' }}
|
||||
shell: bash
|
||||
env:
|
||||
INPUT_CLOUDFRONT_DISTRIBUTION_IDS: ${{ inputs.cloudfront_distribution_ids }}
|
||||
run: |
|
||||
echo "$INPUT_CLOUDFRONT_DISTRIBUTION_IDS" \
|
||||
| tr ' ' '\n' \
|
||||
| xargs -I% aws cloudfront create-invalidation --distribution-id % --paths '/*'
|
||||
Loading…
Add table
Add a link
Reference in a new issue