-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
workflows: add safe-upload-artifacts action
Add safe-upload-artifacts to combine the functionality of both the mask_secrets and upload-artifact actions. Signed-off-by: Mike Szczys <mike@golioth.io>
- Loading branch information
Showing
2 changed files
with
103 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,33 @@ | ||
# Safe Upload Artifacts Github Action | ||
|
||
Upload artifacts from a given set of paths. Before the archive is | ||
uploaded the files will be scanned for GitHub secrets and masked when | ||
found with `***NAME_OF_SECRET***`. This prevents secrets from appearing | ||
in publicly-downloadable archives attached to workflow runs. | ||
|
||
## Known Issues | ||
|
||
The regex used for the replacement cannot be applied to secrets that | ||
have linefeed characters in them. These secrets will be skipped without | ||
notice. | ||
|
||
## Usage | ||
|
||
``` | ||
- name: Safe upload artifacts | ||
id: safe-upload-artifacts | ||
if: always() | ||
uses: ./.github/actions/safe-upload-artifacts | ||
with: | ||
secrets-json: ${{ toJson(secrets) }} | ||
name: name-for-the-uploaded-archive | ||
path: | | ||
path-to/file-to-archive.log | ||
``` | ||
|
||
- The `uses` path may change based on how your workflow checks out the | ||
repository. (eg: `uses: | ||
./modules/lib/golioth-firmware-sdk/.github/actions/safe-upload-artifacts`). | ||
- Secrets must be passed as serialized JSON as in the example above. | ||
This is because actions cannot inherit secrets. Reusable workflows can | ||
inherit secrets but they cannot be run as steps (only as jobs). |
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,70 @@ | ||
name: Mask secrets in files | ||
|
||
description: | | ||
Search all files in a given path(s) and replace any GitHub secrets with ***NAME_OF_SECRET*** | ||
inputs: | ||
secrets-json: | ||
description: 'Secrets context to be masked, in JSON format' | ||
required: true | ||
name: | ||
description: 'String to use as the archive name' | ||
required: true | ||
path: | ||
description: 'Path(s) to the files to be include in the upload' | ||
required: true | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Check for installed commands | ||
shell: bash | ||
run: | | ||
if ! command -v jq; then | ||
apt update && apt install -y jq | ||
if ! command -v jq; then | ||
echo "Could not install command: jq" | ||
exit 1 | ||
fi | ||
fi | ||
- name: Find and mask | ||
id: find-and-mask | ||
shell: bash | ||
env: | ||
SECRETS_CONTEXT: '${{ inputs.secrets-json }}' | ||
run: | | ||
rm -rf __grep_search_output.txt | ||
# Enable globbing | ||
shopt -s globstar | ||
for key in $(jq -r "keys[]" <<< "$SECRETS_CONTEXT"); | ||
do | ||
secret_val=$(jq -r ".$key" <<< "$SECRETS_CONTEXT") | ||
if [[ ! $secret_val =~ "\n" ]]; then | ||
# This approach to escaping the regex found: https://stackoverflow.com/a/29613573/922013 | ||
ESCAPED_SECRET=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< "$secret_val") | ||
# Iterate list of input path patterns and use grep to create a list of files that | ||
# contain secrets | ||
while IFS= read -r search_path || [[ -n $search_path ]]; | ||
do | ||
[ $(grep -Rl $ESCAPED_SECRET $search_path 2>/dev/null >> __grep_search_output.txt) >= 0 ] | ||
done < <(printf '%s' "${{ inputs.path }}") | ||
if [ -s __grep_search_output.txt ]; then | ||
uniq __grep_search_output.txt | xargs -I{} sed -i "s/$ESCAPED_SECRET/***$key***/g" {} | ||
fi | ||
rm -rf __grep_search_output.txt | ||
fi | ||
done | ||
- name: Upload artifacts | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: ${{ inputs.name }} | ||
path: ${{ inputs.path }} |