138 lines
6.6 KiB
YAML
138 lines
6.6 KiB
YAML
# SPDX-License-Identifier: 0BSD
|
|
name: "Upload an artifact with wget"
|
|
author: "Chl"
|
|
|
|
description: |
|
|
Upload an artifact.
|
|
|
|
This is a lighter version of upload-artifact, it only needs a shell, zip
|
|
and the full version of wget.
|
|
|
|
branding:
|
|
icon: archive
|
|
color: gray-dark
|
|
|
|
inputs:
|
|
name:
|
|
description: 'Artifact name'
|
|
default: 'artifact'
|
|
path:
|
|
description: 'A file, directory or wildcard pattern that describes what to upload'
|
|
required: true
|
|
compression:
|
|
description: 'Set to false to upload the (already zipped by yourself) file directly. (default: true)'
|
|
default: true
|
|
compression-level:
|
|
description: 'The level of compression for Zlib to be applied to the artifact archive (between 0 and 9).'
|
|
default: '6'
|
|
|
|
outputs:
|
|
artifact-id:
|
|
description: A unique identifier for the artifact that was just uploaded.
|
|
value: ${{ steps.uploading.outputs.artifact-id }}
|
|
artifact-url:
|
|
description: The URL for the uploaded artifact. Access may require authorization.
|
|
value: ${{ steps.uploading.outputs.artifact-url }}
|
|
|
|
runs:
|
|
using: 'composite'
|
|
steps:
|
|
# ACTIONS_RUNTIME_TOKEN is not yet available (2024-08) for composite actions on Github :
|
|
# https://github.com/actions/runner/issues/3046
|
|
# Forgejo tries to download this remote action even if it's not needed :
|
|
# uncomment if you want to run this action in Github.
|
|
#- name: Expose GitHub Runtime
|
|
# if: env.ACTIONS_RUNTIME_TOKEN == ''
|
|
# uses: "https://github.com/crazy-max/ghaction-github-runtime@v3"
|
|
|
|
- name: Upload artifact (using v4)
|
|
shell: sh
|
|
# id for reference in the outputs extraction
|
|
id: uploading
|
|
run: |
|
|
# Some optional help for debugging.
|
|
set -ex
|
|
|
|
# Compatibility layer for Github
|
|
test -z "$GITHUB_TOKEN" && GITHUB_TOKEN="${{ github.token }}"
|
|
|
|
# Compress the input paths into a zip archive
|
|
# (note: busybox' mktemp doesn't have the --suffix option)
|
|
MYUPLOAD="$( mktemp -u ).zip"
|
|
if [ "${{ inputs.compression }}" = "true" ]; then
|
|
# inputs.path can be a list of files (with wildcards and spaces) and
|
|
# the shell's command substitution + field splitting + pathname
|
|
# expansion gives a behaviour pretty close to the original Github's
|
|
# action.
|
|
# (TODO: the original can also do exclude patterns)
|
|
zip -r -"${{ inputs.compression-level }}" "$MYUPLOAD" -- $( echo "${{ inputs.path }}" ) ;
|
|
else
|
|
MYUPLOAD="${{ inputs.path }}"
|
|
fi
|
|
|
|
# General note:
|
|
# instead of using a proper JSON parser like 'jq', we use the generally
|
|
# available 'sed' in order to help this code being more easily reusable
|
|
# (at the cost of and breaking if the JSON formating happens to change,
|
|
# and readability...)
|
|
|
|
# First we extract the second field from the token (e.g. xxx.yyy.zzz),
|
|
# then we de-base64 and last, we extract the two id from
|
|
# 'Actions.Results:22:33'
|
|
# (note: base64 -d doesn't like when the '==' padding is missing, so 2>/dev/null and relying on the piping to forget about non-zero return code...)
|
|
read WORKFLOW_RUN_BACKEND_ID WORKFLOW_JOB_RUN_BACKEND_ID <<EOF
|
|
$( echo "$ACTIONS_RUNTIME_TOKEN" | sed 's/.*\.\(.*\)\..*/\1/' | base64 -d 2>/dev/null | sed 's/.*Actions.Results:\([^:]\+\):\([^:" ]\+\).*/\1 \2/' )
|
|
EOF
|
|
|
|
# Github compatibility layer: ACTIONS_RESULTS_URL already ends with a '/'
|
|
ACTIONS_RESULTS_URL="$( echo "$ACTIONS_RESULTS_URL" | sed 's/\/$//' )"
|
|
|
|
# Request an upload URL
|
|
RESPONSE="$( wget -O - \
|
|
--header 'Content-Type:application/json' \
|
|
--header "Authorization: Bearer $ACTIONS_RUNTIME_TOKEN" \
|
|
--post-data "$( printf '{"version":4, "name":"%s", "workflow_run_backend_id":"%s", "workflow_job_run_backend_id":"%s"}' "${{ inputs.name }}" "$WORKFLOW_RUN_BACKEND_ID" "$WORKFLOW_JOB_RUN_BACKEND_ID" )" \
|
|
"$ACTIONS_RESULTS_URL"/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact
|
|
)"
|
|
# We get a JSON with an signedUploadUrl similar to :
|
|
# https://entrepot.xlii.si/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=yWWEI8tIIECp8D7E5TVh4_6G2pZxWaVdQcSYaCsx5s0=&expires=2024-08-26+07%3A20%3A49.886890537+%2B0200+CEST&artifactName=mymodule-1.2.3.zip&taskID=63
|
|
SIGNED_UPLOAD_URL="$( echo "$RESPONSE" | sed -n 's/.*"signed_\?[uU]pload_\?[uU]rl" *: *"\([^"]\+\)".*/\1/p' )"
|
|
|
|
# Upload our file
|
|
# (note: adding '&comp=block' at the end of the URL for Forgejo)
|
|
# (note 2: if it fails here, it probably means you are using the busybox
|
|
# variant of wget which can't (as of 2024-08-26) use the PUT method.
|
|
# Install the full one beforehand : apt install wget / pkg add wget / ...)
|
|
if [ "$GITHUB_SERVER_URL" != "https://github.com" ]; then
|
|
SIGNED_UPLOAD_URL="$SIGNED_UPLOAD_URL&comp=block"
|
|
fi
|
|
wget -O /dev/null \
|
|
--method PUT \
|
|
--body-file "$MYUPLOAD" \
|
|
--header "x-ms-blob-content-type: zip" \
|
|
--header "x-ms-blob-type: BlockBlob" \
|
|
"$SIGNED_UPLOAD_URL"
|
|
|
|
# Finalize the artifact
|
|
RESPONSE="$( wget -O - \
|
|
--header 'Content-Type:application/json' \
|
|
--header "Authorization: Bearer $ACTIONS_RUNTIME_TOKEN" \
|
|
--post-data "$( printf '{"hash":"sha256:%s", "name":"%s", "size":"%d", "workflow_run_backend_id":"%s", "workflow_job_run_backend_id":"%s"}' "$( sha256sum $MYUPLOAD | sed 's/[[:space:]]\+.*//' )" "${{ inputs.name }}" "$( stat -c %s $MYUPLOAD )" "$WORKFLOW_RUN_BACKEND_ID" "$WORKFLOW_JOB_RUN_BACKEND_ID" )" \
|
|
"$ACTIONS_RESULTS_URL"/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact
|
|
)"
|
|
|
|
# Store the outputs
|
|
ARTIFACT_ID="$( echo "$RESPONSE" | sed -n 's/.*"artifact_\?Id" *: *"\([^"]\+\)".*/\1/ip' )"
|
|
echo artifact-id="$ARTIFACT_ID" >> $GITHUB_OUTPUT
|
|
if [ "$GITHUB_SERVER_URL" = "https://github.com" ]; then
|
|
# note: as an alternative, there is https://api.github.com/repos/OWNER/REPO/actions/artifacts/ARTIFACT_ID
|
|
echo artifact-url="$GITHUB_SERVER_URL"/"$GITHUB_REPOSITORY"/actions/runs/"$GITHUB_RUN_ID"/artifacts/"$ARTIFACT_ID" >> $GITHUB_OUTPUT
|
|
else
|
|
# Gitea & Forgejo : github.run_number instead of github.run_id and name of the artifact instead of artifact_id
|
|
echo artifact-url="$GITHUB_SERVER_URL"/"$GITHUB_REPOSITORY"/actions/runs/"$GITHUB_RUN_NUMBER"/artifacts/"$INPUT_NAME" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
# Cleanup
|
|
if [ "${{ inputs.compression }}" = "true" ]; then
|
|
rm -f "$MYUPLOAD"
|
|
fi
|