-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sc 28936 create a generic GitHub action to push frontend (#17)
* test action * test * Test each scenario * Adding inputs * change input * Finalizing inputs * Adding readme and removed echos * changed the env var * test github context * Debug * Accept pull request number as input * update readme * Added separate steps for upload and delete based on user input * Adding generic steps * Check for case * Bugfix with if statement * bugfix * bugfix * debug if statements * debug if statements * bugfix * Fixed bugs in expressions * Fixed exlude-files input * Update readme * Adding newline * Remove echos * Update exclude files logic Co-authored-by: Rashid N H M <[email protected]> * Implementing changes based on review Co-authored-by: Rashid N H M <[email protected]>
- Loading branch information
1 parent
cf96005
commit a931277
Showing
2 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# Action to push files to an S3 bucket to deploy a static web application | ||
|
||
This action can be used to update a static web application that is built using AWS S3 and Cloudfront. The action pushes built code to an S3 bucket that already exists. One of the intended use cases for this action is Pull Request previews. | ||
|
||
Files are pushed to the S3 bucket depending on the user inputs supplied when the action is called. Some inputs have default values or may be inferred from the github context. | ||
Following examples describe how to use the action. | ||
|
||
## Uploading to S3 based on user input | ||
This example will **upload** the specified folder (`build-directory`) to a folder named `blog` on the S3 bucket(`myS3Bucket`). The action will not exclude any files while uploading them. The action will also invalidate the cloudfront cache. | ||
|
||
```yaml | ||
- uses: XanaduAI/cloud-actions/push-to-s3-and-invalidate-cloudfront@main | ||
with: | ||
build-directory: build-dir | ||
pull-request-number: 123 | ||
aws-cloudfront-distribution-id: ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} | ||
aws-region: ${{ secrets.AWS_REGION }} | ||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
s3-bucket: myS3Bucket | ||
s3-action: "upload" | ||
s3-dir-to-upload-to: "blog" | ||
s3-files-to-exclude: "" | ||
invalidate-cloudfront-cache: "true" | ||
``` | ||
## Deleting from S3 based on user input | ||
This example will **delete** the specified folder (`build-directory`) from the S3 bucket(`myS3Bucket`). The action will also invalidate the cloudfront cache. | ||
|
||
```yaml | ||
- uses: XanaduAI/cloud-actions/push-to-s3-and-invalidate-cloudfront@main | ||
with: | ||
build-directory: build-dir | ||
pull-request-number: 123 | ||
aws-cloudfront-distribution-id: ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} | ||
aws-region: ${{ secrets.AWS_REGION }} | ||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
s3-bucket: myS3Bucket | ||
s3-action: "delete" | ||
s3-dir-to-delete-from: "blog" | ||
invalidate-cloudfront-cache: "true" | ||
``` | ||
|
||
## Uploading/Deleting to/from S3 with minimal user unput | ||
If this action is called when a `pull_request` is `opened` or `syncronized`, then the example will **upload** the specified folder (`build-directory`) to a folder named `pr-previews/PR-123` on the S3 bucket (`myS3Bucket`). The action will exclude any files that start with the default `pr-previews` prefix. The action will not invalidate the cloudfront cache. | ||
|
||
If this action is called when a `pull_request` is `closed`, then the example will **delete** the folder named `pr-previews/PR-123` on the S3 bucket (`myS3Bucket`). | ||
|
||
```yaml | ||
- uses: XanaduAI/cloud-actions/push-to-s3-and-invalidate-cloudfront@main | ||
with: | ||
build-directory: build-dir | ||
pull-request-number: 123 | ||
aws-cloudfront-distribution-id: ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} | ||
aws-region: ${{ secrets.AWS_REGION }} | ||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
s3-bucket: myS3Bucket | ||
``` | ||
## AWS Permissions | ||
The IAM machine user needs the following permissions on the S3 bucket and the Cloudfront distribution: | ||
``` | ||
s3:ListBucket | ||
s3:GetObject | ||
s3:PutObject | ||
s3:DeleteObject | ||
cloudfront:CreateInvalidation | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
name: Push files to an S3 bucket destination and invalidate the cloudfront cache | ||
description: | | ||
This action will push files to a destination S3 bucket (or a folder within a bucket) and invalidates the cloudfront cache. | ||
The action also removes any stale files from the bucket. The action can also delete files/folders from the bucket. | ||
inputs: | ||
build-directory: | ||
description: The directory that contains the build files to upload to S3 | ||
required: true | ||
aws-cloudfront-distribution-id: | ||
description: The cloudfront distribution ID for the app | ||
required: true | ||
aws-region: | ||
description: The aws region used by the IAM machine user | ||
required: true | ||
aws-access-key-id: | ||
description: The aws access key id for the IAM machine user | ||
required: true | ||
aws-secret-access-key: | ||
description: The aws secret access key for the IAM machine user | ||
required: true | ||
s3-bucket: | ||
description: The name of the S3 bucket | ||
required: true | ||
|
||
pull-request-number: | ||
description: The pull request number for which a preview needs to be generated/updated. This is required if you do not specify the s3-directory variable. | ||
required: false | ||
s3-action: | ||
description: | | ||
The action to take on the S3 bucket. Typically this should be `update` to push the latest files to S3 or `delete` to delete the folder from S3. | ||
If this is not specified, the action will be infered from the $github.event.action variable | ||
required: false | ||
default: "" | ||
s3-directory: | ||
description: | | ||
The S3 directory to upload the files to or delete the files from. If unspecified, the default `PR-$pull-request-number` will be used | ||
or the directory may be infered from the github context. A value of `/` indicates the root of the bucket. | ||
required: false | ||
default: "pr-previews" | ||
s3-files-to-exclude: | ||
description: | | ||
A pattern or a comma separated list of files to exclude when running the aws s3 sync command. | ||
Refer to https://docs.aws.amazon.com/cli/latest/reference/s3/index.html#use-of-exclude-and-include-filters or more information | ||
Set this variable to an empty string if you don't want to exlcude any files | ||
If unspecified will default to `pr-previews/*` | ||
required: false | ||
default: "pr-previews/*" | ||
invalidate-cloudfront-cache: | ||
description: A flag to indicate if the cloudfront cache should be invalidated | ||
required: false | ||
default: "false" | ||
|
||
outputs: | ||
dir_name: | ||
description: The S3 directory to upload the files to or delete files from. Computed based on user input. | ||
value: ${{ steps.directory.dir_name }} | ||
files_to_exlude: | ||
description: Files to exclude from S3 when using the sync command. | ||
value: ${{ steps.exclude.files_to_exclude }} | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Input validation for pull-request-number | ||
if: inputs.s3-directory == 'pr-previews' && inputs.pull-request-number == '' | ||
uses: actions/github-script@v6 | ||
with: | ||
script: | | ||
core.setFailed('Either of the pull-request-number or the s3-directory are required') | ||
- name: Compute the S3 directory to upload to or delete from | ||
shell: bash | ||
id: directory | ||
run: | | ||
if [[ "${{ inputs.s3-directory }}" == "pr-previews" ]] | ||
then | ||
dir_name="${{ inputs.s3-directory }}/PR-${{ inputs.pull-request-number }}" | ||
elif [[ "${{ inputs.s3-directory }}" == "/" ]] | ||
then | ||
dir_name="" | ||
else | ||
dir_name="${{ inputs.s3-directory }}" | ||
fi | ||
echo "dir_name=$dir_name" >> $GITHUB_OUTPUT | ||
- name: Compute files to exclude | ||
shell: bash | ||
id: exclude | ||
run: | | ||
files_to_exlude="" | ||
if [[ "${{ inputs.s3-files-to-exclude }}" == *,* ]] | ||
then | ||
IFS=',' | ||
for i in `echo "${{ inputs.s3-files-to-exclude }}"` | ||
do | ||
files_to_exlude="$files_to_exlude --exclude \"$i\"" | ||
done | ||
unset IFS | ||
elif [[ "${{ inputs.s3-files-to-exclude }}" != "" ]] | ||
then | ||
files_to_exlude="--exclude \"${{ inputs.s3-files-to-exclude }}\"" | ||
fi | ||
echo "files_to_exlude=$files_to_exlude" >> $GITHUB_OUTPUT | ||
- name: Upload the files to S3 | ||
shell: bash | ||
if: inputs.s3-action == 'upload' || (inputs.s3-action == '' && github.event_name == 'pull_request' && contains(fromJson('["opened", "synchronize"]'), github.event.action)) | ||
env: | ||
AWS_REGION: ${{ inputs.aws-region }} | ||
AWS_ACCESS_KEY_ID: ${{ inputs.aws-access-key-id }} | ||
AWS_SECRET_ACCESS_KEY: ${{ inputs.aws-secret-access-key }} | ||
run: | | ||
aws s3 sync ${{ inputs.build-directory }}/ s3://${{ inputs.s3-bucket }}/${{ steps.directory.outputs.dir_name }} ${{ steps.exclude.outputs.files_to_exlude }} | ||
- name: Delete the files on S3 | ||
shell: bash | ||
if: inputs.s3-action == 'delete' || (inputs.s3-action == '' && github.event_name == 'pull_request' && github.event.action == 'closed') | ||
env: | ||
AWS_REGION: ${{ inputs.aws-region }} | ||
AWS_ACCESS_KEY_ID: ${{ inputs.aws-access-key-id }} | ||
AWS_SECRET_ACCESS_KEY: ${{ inputs.aws-secret-access-key }} | ||
run: aws s3 rm s3://${{ inputs.s3-bucket }}/${{ steps.directory.outputs.dir_name }}/ --recursive ${{ steps.exclude.outputs.files_to_exlude }} | ||
|
||
- name: Invalidate the cloudfront cache | ||
shell: bash | ||
if: inputs.invalidate-cloudfront-cache == 'true' | ||
env: | ||
AWS_REGION: ${{ inputs.aws-region }} | ||
AWS_ACCESS_KEY_ID: ${{ inputs.aws-access-key-id }} | ||
AWS_SECRET_ACCESS_KEY: ${{ inputs.aws-secret-access-key }} | ||
run: | | ||
aws cloudfront create-invalidation --distribution-id ${{ inputs.aws-cloudfront-distribution-id }} --paths "/${{ steps.directory.outputs.dir_name }}/*" |