diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml new file mode 100644 index 0000000..3de2f6e --- /dev/null +++ b/.github/workflows/shellcheck.yml @@ -0,0 +1,14 @@ +on: + - push + +name: Check shell scripts using shellcheck +permissions: {} + +jobs: + shellcheck: + name: Shellcheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Run ShellCheck + uses: ludeeus/action-shellcheck@2.0.0 diff --git a/README.md b/README.md index 607496d..ab5c2fd 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ jobs: | retry | **Optional** | How many times retrying if upload fails. `3` by default. | | post_command | **Optional** | Extra command that will be executed for teardown work. e.g. you can use it to upload artifacts to AWS s3 or aliyun OSS | | compress_assets | **Optional** | `auto` default will produce a `zip` file for Windows and `tar.gz` for others. `zip` will force the use of of `zip`. `OFF` will disable packaging of assets. | +| tarbomb | **Optional* | Should the archive be rootless - i.e. a Tarbomb? Set to `FALSE` to ensure the release archive has a root directory. [More information on tarbombs](https://en.wikipedia.org/wiki/Tar_(computing)). `TRUE` by default. | ### Advanced Example diff --git a/action.yml b/action.yml index cdbea88..68d8368 100644 --- a/action.yml +++ b/action.yml @@ -91,6 +91,10 @@ inputs: description: 'Compress assets before uploading' required: false default: 'TRUE' + tarbomb: + description: 'Should the archive be rootless - i.e. a Tarbomb?' + required: false + default: 'TRUE' runs: using: 'docker' @@ -117,6 +121,7 @@ runs: - ${{ inputs.retry }} - ${{ inputs.post_command }} - ${{ inputs.compress_assets }} + - ${{ inputs.tarbomb }} branding: icon: 'package' diff --git a/entrypoint.sh b/entrypoint.sh index f83fb1e..578c108 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,7 +1,8 @@ #!/bin/bash -eux # prepare golang -source /setup-go.sh +# shellcheck disable=SC1091 +source /setup-go.sh # easy to debug if anything wrong go version @@ -9,4 +10,3 @@ env # build & release go binaries /release.sh - diff --git a/release.sh b/release.sh index ae07752..f887f1b 100755 --- a/release.sh +++ b/release.sh @@ -1,35 +1,36 @@ #!/bin/bash -eux # prepare binary_name/release_tag/release_asset_name -BINARY_NAME=$(basename ${GITHUB_REPOSITORY}) -if [ x${INPUT_BINARY_NAME} != x ]; then - BINARY_NAME=${INPUT_BINARY_NAME} +BINARY_NAME=$(basename "$GITHUB_REPOSITORY") +if [[ $INPUT_BINARY_NAME ]]; then + BINARY_NAME=$INPUT_BINARY_NAME fi -RELEASE_TAG=$(basename ${GITHUB_REF}) -if [ ! -z "${INPUT_RELEASE_TAG}" ]; then - RELEASE_TAG=${INPUT_RELEASE_TAG} -elif [ ! -z "${INPUT_RELEASE_NAME}" ]; then # prevent upload-asset by tag due to github-ref default if a name is given - RELEASE_TAG="" +RELEASE_TAG=$(basename "$GITHUB_REF") +if [[ $INPUT_RELEASE_TAG ]]; then + RELEASE_TAG=${INPUT_RELEASE_TAG} +elif [[ $INPUT_RELEASE_NAME ]]; then + # prevent upload-asset by tag due to github-ref default if a name is given + RELEASE_TAG="" fi -RELEASE_NAME=${INPUT_RELEASE_NAME} +RELEASE_NAME=$INPUT_RELEASE_NAME RELEASE_ASSET_NAME=${BINARY_NAME}-${RELEASE_TAG}-${INPUT_GOOS}-${INPUT_GOARCH} -if [ ! -z "${INPUT_GOAMD64}" ]; then +if [[ $INPUT_GOAMD64 ]]; then RELEASE_ASSET_NAME=${BINARY_NAME}-${RELEASE_TAG}-${INPUT_GOOS}-${INPUT_GOARCH}-${INPUT_GOAMD64} fi -if [ ! -z "${INPUT_ASSET_NAME}" ]; then +if [[ $INPUT_ASSET_NAME ]]; then RELEASE_ASSET_NAME=${INPUT_ASSET_NAME} fi # prompt error if non-supported event -if [ ${GITHUB_EVENT_NAME} == 'release' ]; then +if [[ $GITHUB_EVENT_NAME == release ]]; then echo "Event: ${GITHUB_EVENT_NAME}" -elif [ ${GITHUB_EVENT_NAME} == 'push' ]; then +elif [[ $GITHUB_EVENT_NAME == push ]]; then echo "Event: ${GITHUB_EVENT_NAME}" -elif [ ${GITHUB_EVENT_NAME} == 'workflow_dispatch' ]; then +elif [[ $GITHUB_EVENT_NAME == workflow_dispatch ]]; then echo "Event: ${GITHUB_EVENT_NAME}" -elif [ ${GITHUB_EVENT_NAME} == 'workflow_run' ]; then +elif [[ $GITHUB_EVENT_NAME == workflow_run ]]; then echo "Event: ${GITHUB_EVENT_NAME}" else echo "Unsupport event: ${GITHUB_EVENT_NAME}!" @@ -37,32 +38,32 @@ else fi # execute pre-command if exist, e.g. `go get -v ./...` -if [ ! -z "${INPUT_PRE_COMMAND}" ]; then - eval ${INPUT_PRE_COMMAND} +if [[ $INPUT_PRE_COMMAND ]]; then + eval "$INPUT_PRE_COMMAND" fi # binary suffix EXT='' -if [ ${INPUT_GOOS} == 'windows' ]; then - EXT='.exe' +if [[ $INPUT_GOOS == windows ]]; then + EXT='.exe' fi # prefix for ldflags LDFLAGS_PREFIX='' -if [ ! -z "${INPUT_LDFLAGS}" ]; then +if [[ $INPUT_LDFLAGS ]]; then LDFLAGS_PREFIX="-ldflags" fi # fulfill GOAMD64 option -if [ ! -z "${INPUT_GOAMD64}" ]; then - if [[ "${INPUT_GOARCH}" =~ amd64 ]]; then - GOAMD64_FLAG="${INPUT_GOAMD64}" +if [[ $INPUT_GOAMD64 ]]; then + if [[ $INPUT_GOARCH =~ amd64 ]]; then + GOAMD64_FLAG=$INPUT_GOAMD64 else - echo "GOAMD64 should only be use with amd64 arch." >>/dev/stderr + echo "GOAMD64 should only be use with amd64 arch." >&2 GOAMD64_FLAG="" fi else - if [[ "${INPUT_GOARCH}" =~ amd64 ]]; then + if [[ $INPUT_GOARCH =~ amd64 ]]; then GOAMD64_FLAG="v1" else GOAMD64_FLAG="" @@ -71,90 +72,139 @@ fi # build BUILD_ARTIFACTS_FOLDER=build-artifacts-$(date +%s) -mkdir -p ${INPUT_PROJECT_PATH}/${BUILD_ARTIFACTS_FOLDER} -cd ${INPUT_PROJECT_PATH} -if [[ "${INPUT_BUILD_COMMAND}" =~ ^make.* ]]; then +mkdir -p "${INPUT_PROJECT_PATH}/${BUILD_ARTIFACTS_FOLDER}" +cd "${INPUT_PROJECT_PATH}" +if [[ $INPUT_BUILD_COMMAND =~ ^make.* ]]; then # start with make, assumes using make to build golang binaries, execute it directly - GOAMD64=${GOAMD64_FLAG} GOOS=${INPUT_GOOS} GOARCH=${INPUT_GOARCH} eval ${INPUT_BUILD_COMMAND} - if [ -f "${BINARY_NAME}${EXT}" ]; then + GOAMD64=$GOAMD64_FLAG \ + GOOS=$INPUT_GOOS \ + GOARCH=$INPUT_GOARCH \ + eval "$INPUT_BUILD_COMMAND" + if [[ -f ${BINARY_NAME}${EXT} ]]; then # assumes the binary will be generated in current dir, copy it for later processes - cp ${BINARY_NAME}${EXT} ${BUILD_ARTIFACTS_FOLDER}/ + cp "${BINARY_NAME}${EXT}" "${BUILD_ARTIFACTS_FOLDER}/" fi else - GOAMD64=${GOAMD64_FLAG} GOOS=${INPUT_GOOS} GOARCH=${INPUT_GOARCH} ${INPUT_BUILD_COMMAND} -o ${BUILD_ARTIFACTS_FOLDER}/${BINARY_NAME}${EXT} ${INPUT_BUILD_FLAGS} ${LDFLAGS_PREFIX} "${INPUT_LDFLAGS}" + GOAMD64=$GOAMD64_FLAG \ + GOOS=$INPUT_GOOS \ + GOARCH=$INPUT_GOARCH \ + eval "$INPUT_BUILD_COMMAND" \ + -o "${BUILD_ARTIFACTS_FOLDER}/${BINARY_NAME}${EXT}" \ + "$INPUT_BUILD_FLAGS" \ + "$LDFLAGS_PREFIX" "$INPUT_LDFLAGS" fi # executable compression -if [ ! -z "${INPUT_EXECUTABLE_COMPRESSION}" ]; then -if [[ "${INPUT_EXECUTABLE_COMPRESSION}" =~ ^upx.* ]]; then - # start with upx, use upx to compress the executable binary - eval ${INPUT_EXECUTABLE_COMPRESSION} ${BUILD_ARTIFACTS_FOLDER}/${BINARY_NAME}${EXT} -else - echo "Unsupport executable compression: ${INPUT_EXECUTABLE_COMPRESSION}!" +if [[ $INPUT_EXECUTABLE_COMPRESSION =~ ^upx.* ]]; then + eval "$INPUT_EXECUTABLE_COMPRESSION" \ + "${BUILD_ARTIFACTS_FOLDER}/${BINARY_NAME}${EXT}" +elif [[ $INPUT_EXECUTABLE_COMPRESSION ]]; then + echo "Unsupported executable compression: ${INPUT_EXECUTABLE_COMPRESSION}!" >&2 exit 1 fi -fi # prepare extra files -if [ ! -z "${INPUT_EXTRA_FILES}" ]; then - cd ${GITHUB_WORKSPACE} - cp -r ${INPUT_EXTRA_FILES} ${INPUT_PROJECT_PATH}/${BUILD_ARTIFACTS_FOLDER}/ - cd ${INPUT_PROJECT_PATH} -fi - -cd ${BUILD_ARTIFACTS_FOLDER} -ls -lha - -# INPUT_COMPRESS_ASSETS=='TRUE' is used for backwards compatability. `AUTO`, `ZIP`, `OFF` are the recommended values -if [ ${INPUT_COMPRESS_ASSETS^^} == "TRUE" ] || [ ${INPUT_COMPRESS_ASSETS^^} == "AUTO" ] || [ ${INPUT_COMPRESS_ASSETS^^} == "ZIP" ]; then - # compress and package binary, then calculate checksum - RELEASE_ASSET_EXT='.tar.gz' - MEDIA_TYPE='application/gzip' - RELEASE_ASSET_FILE=${RELEASE_ASSET_NAME}${RELEASE_ASSET_EXT} - if [ ${INPUT_GOOS} == 'windows' ] || [ ${INPUT_COMPRESS_ASSETS^^} == "ZIP" ]; then - RELEASE_ASSET_EXT='.zip' - MEDIA_TYPE='application/zip' +if [[ $INPUT_EXTRA_FILES ]]; then + cd "$GITHUB_WORKSPACE" + # shellcheck disable=SC2086 + cp -r $INPUT_EXTRA_FILES "${INPUT_PROJECT_PATH}/${BUILD_ARTIFACTS_FOLDER}/" + cd - +fi + +if [[ ${INPUT_TARBOMB^^} == TRUE ]]; then + cd "$BUILD_ARTIFACTS_FOLDER" + SOURCE_DIR=. + ls -lha +else + ls -lha "$BUILD_ARTIFACTS_FOLDER" + SOURCE_DIR=$BUILD_ARTIFACTS_FOLDER +fi + +# INPUT_COMPRESS_ASSETS=='TRUE' is used for backwards compatability. `AUTO`, +# `ZIP`, `OFF` are the recommended values +if [[ ${INPUT_COMPRESS_ASSETS^^} =~ ^(TRUE|AUTO|ZIP)$ ]]; then + # compress and package binary, then calculate checksum + RELEASE_ASSET_EXT='.tar.gz' + MEDIA_TYPE='application/gzip' RELEASE_ASSET_FILE=${RELEASE_ASSET_NAME}${RELEASE_ASSET_EXT} - ( shopt -s dotglob; zip -vr ${RELEASE_ASSET_FILE} * ) - else - ( shopt -s dotglob; tar cvfz ${RELEASE_ASSET_FILE} * ) - fi -elif [ ${INPUT_COMPRESS_ASSETS^^} == "OFF" ] || [ ${INPUT_COMPRESS_ASSETS^^} == "FALSE" ]; then - RELEASE_ASSET_EXT=${EXT} - MEDIA_TYPE="application/octet-stream" - RELEASE_ASSET_FILE=${RELEASE_ASSET_NAME}${RELEASE_ASSET_EXT} - cp ${BINARY_NAME}${EXT} ${RELEASE_ASSET_FILE} + if [[ $INPUT_GOOS == windows || ${INPUT_COMPRESS_ASSETS^^} == "ZIP" ]]; then + RELEASE_ASSET_EXT='.zip' + MEDIA_TYPE='application/zip' + RELEASE_ASSET_FILE=${RELEASE_ASSET_NAME}${RELEASE_ASSET_EXT} + ( + shopt -s dotglob + zip -vr "$RELEASE_ASSET_FILE" "$SOURCE_DIR/"* + ) + else + ( + shopt -s dotglob + tar -czvf "$RELEASE_ASSET_FILE" "$SOURCE_DIR/"* + ) + fi +elif [[ ${INPUT_COMPRESS_ASSETS} =~ ^(OFF|FALSE)$ ]]; then + RELEASE_ASSET_EXT=$EXT + MEDIA_TYPE="application/octet-stream" + RELEASE_ASSET_FILE=${RELEASE_ASSET_NAME}${RELEASE_ASSET_EXT} + cp "${BINARY_NAME}${EXT}" "$RELEASE_ASSET_FILE" else - echo "Invalid value for INPUT_COMPRESS_ASSETS: ${INPUT_COMPRESS_ASSETS} . Acceptable values are AUTO,ZIP, or OFF." - exit 1 + echo "Invalid value for INPUT_COMPRESS_ASSETS: ${INPUT_COMPRESS_ASSETS} . Acceptable values are AUTO,ZIP, or OFF." >&2 + exit 1 fi -MD5_SUM=$(md5sum ${RELEASE_ASSET_FILE} | cut -d ' ' -f 1) -SHA256_SUM=$(sha256sum ${RELEASE_ASSET_FILE} | cut -d ' ' -f 1) +MD5_SUM=$(md5sum "$RELEASE_ASSET_FILE" | cut -d ' ' -f 1) +SHA256_SUM=$(sha256sum "$RELEASE_ASSET_FILE" | cut -d ' ' -f 1) # prefix upload extra params GITHUB_ASSETS_UPLOADR_EXTRA_OPTIONS='' -if [ ${INPUT_OVERWRITE^^} == 'TRUE' ]; then +if [[ ${INPUT_OVERWRITE^^} == TRUE ]]; then GITHUB_ASSETS_UPLOADR_EXTRA_OPTIONS="-overwrite" fi # update binary and checksum -github-assets-uploader -logtostderr -f ${RELEASE_ASSET_FILE} -mediatype ${MEDIA_TYPE} ${GITHUB_ASSETS_UPLOADR_EXTRA_OPTIONS} -repo ${GITHUB_REPOSITORY} -token ${INPUT_GITHUB_TOKEN} -tag=${RELEASE_TAG} -releasename=${RELEASE_NAME} -retry ${INPUT_RETRY} -if [ ${INPUT_MD5SUM^^} == 'TRUE' ]; then -MD5_EXT='.md5' -MD5_MEDIA_TYPE='text/plain' -echo ${MD5_SUM} >${RELEASE_ASSET_FILE}${MD5_EXT} -github-assets-uploader -logtostderr -f ${RELEASE_ASSET_FILE}${MD5_EXT} -mediatype ${MD5_MEDIA_TYPE} ${GITHUB_ASSETS_UPLOADR_EXTRA_OPTIONS} -repo ${GITHUB_REPOSITORY} -token ${INPUT_GITHUB_TOKEN} -tag=${RELEASE_TAG} -releasename=${RELEASE_NAME} -retry ${INPUT_RETRY} -fi - -if [ ${INPUT_SHA256SUM^^} == 'TRUE' ]; then -SHA256_EXT='.sha256' -SHA256_MEDIA_TYPE='text/plain' -echo ${SHA256_SUM} >${RELEASE_ASSET_FILE}${SHA256_EXT} -github-assets-uploader -logtostderr -f ${RELEASE_ASSET_FILE}${SHA256_EXT} -mediatype ${SHA256_MEDIA_TYPE} ${GITHUB_ASSETS_UPLOADR_EXTRA_OPTIONS} -repo ${GITHUB_REPOSITORY} -token ${INPUT_GITHUB_TOKEN} -tag=${RELEASE_TAG} -releasename=${RELEASE_NAME} -retry ${INPUT_RETRY} +github-assets-uploader \ + -logtostderr \ + -f "$RELEASE_ASSET_FILE" \ + -mediatype "$MEDIA_TYPE" \ + $GITHUB_ASSETS_UPLOADR_EXTRA_OPTIONS \ + -repo "$GITHUB_REPOSITORY" \ + -token "$INPUT_GITHUB_TOKEN" \ + -tag="$RELEASE_TAG" \ + -releasename="$RELEASE_NAME" \ + -retry "$INPUT_RETRY" + +if [[ ${INPUT_MD5SUM^^} == TRUE ]]; then + MD5_EXT='.md5' + MD5_MEDIA_TYPE='text/plain' + echo "$MD5_SUM" > "${RELEASE_ASSET_FILE}${MD5_EXT}" + github-assets-uploader \ + -logtostderr \ + -f "${RELEASE_ASSET_FILE}${MD5_EXT}" \ + -mediatype "$MD5_MEDIA_TYPE" \ + $GITHUB_ASSETS_UPLOADR_EXTRA_OPTIONS \ + -repo "$GITHUB_REPOSITORY" \ + -token "$INPUT_GITHUB_TOKEN" \ + -tag="$RELEASE_TAG" \ + -releasename="$RELEASE_NAME" \ + -retry "$INPUT_RETRY" +fi + +if [[ ${INPUT_SHA256SUM^^} == TRUE ]]; then + SHA256_EXT='.sha256' + SHA256_MEDIA_TYPE='text/plain' + echo "$SHA256_SUM" > "${RELEASE_ASSET_FILE}${SHA256_EXT}" + github-assets-uploader \ + -logtostderr \ + -f "${RELEASE_ASSET_FILE}${SHA256_EXT}" \ + -mediatype "$SHA256_MEDIA_TYPE" \ + $GITHUB_ASSETS_UPLOADR_EXTRA_OPTIONS \ + -repo "$GITHUB_REPOSITORY" \ + -token "$INPUT_GITHUB_TOKEN" \ + -tag="$RELEASE_TAG" \ + -releasename="$RELEASE_NAME" \ + -retry "$INPUT_RETRY" fi # execute post-command if exist, e.g. upload to AWS s3 or aliyun OSS -if [ ! -z "${INPUT_POST_COMMAND}" ]; then - eval ${INPUT_POST_COMMAND} +if [[ $INPUT_POST_COMMAND ]]; then + eval "${INPUT_POST_COMMAND}" fi diff --git a/setup-go.sh b/setup-go.sh index 7fa9302..ce092c9 100755 --- a/setup-go.sh +++ b/setup-go.sh @@ -2,33 +2,30 @@ ARCH=$(dpkg --print-architecture) GO_LINUX_PACKAGE_URL="https://go.dev/dl/$(curl https://go.dev/VERSION?m=text).linux-${ARCH}.tar.gz" -if [[ ${INPUT_GOVERSION} == "1.19" ]]; then +if [[ $INPUT_GOVERSION == 1.19 ]]; then GO_LINUX_PACKAGE_URL="https://go.dev/dl/go1.19.1.linux-${ARCH}.tar.gz" -elif [[ ${INPUT_GOVERSION} == "1.18" ]]; then +elif [[ $INPUT_GOVERSION == 1.18 ]]; then GO_LINUX_PACKAGE_URL="https://go.dev/dl/go1.18.6.linux-${ARCH}.tar.gz" -elif [[ ${INPUT_GOVERSION} == "1.17" ]]; then +elif [[ $INPUT_GOVERSION == 1.17 ]]; then GO_LINUX_PACKAGE_URL="https://go.dev/dl/go1.17.13.linux-${ARCH}.tar.gz" -elif [[ ${INPUT_GOVERSION} == "1.16" ]]; then +elif [[ $INPUT_GOVERSION == 1.16 ]]; then GO_LINUX_PACKAGE_URL="https://go.dev/dl/go1.16.15.linux-${ARCH}.tar.gz" -elif [[ ${INPUT_GOVERSION} == "1.15" ]]; then +elif [[ $INPUT_GOVERSION == 1.15 ]]; then GO_LINUX_PACKAGE_URL="https://go.dev/dl/go1.15.15.linux-${ARCH}.tar.gz" -elif [[ ${INPUT_GOVERSION} == "1.14" ]]; then +elif [[ $INPUT_GOVERSION == 1.14 ]]; then GO_LINUX_PACKAGE_URL="https://go.dev/dl/go1.14.15.linux-${ARCH}.tar.gz" -elif [[ ${INPUT_GOVERSION} == "1.13" ]]; then +elif [[ $INPUT_GOVERSION == 1.13 ]]; then GO_LINUX_PACKAGE_URL="https://go.dev/dl/go1.13.15.linux-${ARCH}.tar.gz" -elif [[ ${INPUT_GOVERSION} == http* ]]; then - GO_LINUX_PACKAGE_URL=${INPUT_GOVERSION} -elif [[ -n ${INPUT_GOVERSION} ]]; then +elif [[ ${INPUT_GOVERSION^^} == HTTP* ]]; then # URL scheme isn't case sensitive. + GO_LINUX_PACKAGE_URL=$INPUT_GOVERSION +elif [[ $INPUT_GOVERSION ]]; then GO_LINUX_PACKAGE_URL="https://go.dev/dl/go${INPUT_GOVERSION}.linux-${ARCH}.tar.gz" fi -wget --progress=dot:mega ${GO_LINUX_PACKAGE_URL} -O go-linux.tar.gz -tar -zxf go-linux.tar.gz -mv go /usr/local/ +wget --progress=dot:mega "$GO_LINUX_PACKAGE_URL" -O go-linux.tar.gz +tar -C /usr/local -zxf go-linux.tar.gz go mkdir -p /go/bin /go/src /go/pkg export GO_HOME=/usr/local/go export GOPATH=/go export PATH=${GOPATH}/bin:${GO_HOME}/bin/:$PATH - -