Added many, many more actions.

This commit is contained in:
2025-06-24 15:24:16 -07:00
parent 62fbe4dead
commit 57ef232d2b
108 changed files with 4212 additions and 7 deletions

View File

@@ -29,8 +29,8 @@ runs:
echo $USER_UID:$USER_GID
echo "::set-output name=uid::$USER_UID"
echo "::set-output name=gid::$USER_GID"
echo "uid=$USER_UID" >> "$GITHUB_OUTPUT"
echo "gid=$USER_GID" >> "$GITHUB_OUTPUT"
shell: bash
- name: "Take ownership of output."
uses: act/common/distros/busybox@master

View File

@@ -0,0 +1,49 @@
name: compare-files
description: "Compare the output of a command to an expected value."
inputs:
expected:
description: "Expected output file."
required: true
expectedPattern:
description: "Optional pattern to match files in the expected directory."
required: false
actual:
description: "Actual output file."
required: true
actualPattern:
description: "Optional pattern to match files in the actual directory."
required: false
exitOnFail:
description: "Should the program exit on a failure."
required: true
default: "true"
outputs:
success:
description: "The result of the comparison."
value: ${{ steps.compare.outputs.success }}
runs:
using: "composite"
steps:
- name: "Read files."
id: read
run: |
LHS_NUSPEC=$(cat "${{ inputs.expected }}"${{ inputs.expectedPattern }})
RHS_NUSPEC=$(cat "${{ inputs.actual }}"${{ inputs.actualPattern }})
if [[ -n "$LHS_NUSPEC" ]]; then
echo "lhs<<EOF" >> "$GITHUB_OUTPUT"
echo "$LHS_NUSPEC" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
fi
if [[ -n "$RHS_NUSPEC" ]]; then
echo "rhs<<EOF" >> "$GITHUB_OUTPUT"
echo "$RHS_NUSPEC" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
fi
shell: bash
- name: "Build matrix from yaml."
uses: act/common/utils/compare@master
with:
expected: ${{ steps.read.outputs.lhs }}
actual: ${{ steps.read.outputs.rhs }}
exitOnFail: ${{ inputs.exitOnFail }}

View File

@@ -0,0 +1,99 @@
name: compare-nupkg
description: "Compare the contents of a nupkg file to an expected value."
inputs:
lhs:
description: "Left hand side nupkg."
required: true
rhs:
description: "Right hand side nupkg."
required: true
compareNuspec:
description: "Whether or not to compare the .nuspec file when comparing versions."
required: true
default: "false"
exitOnFail:
description: "Should the program exit on a failure."
required: true
default: "false"
tmpDir:
description: "Temporary directory. Default: _tmp"
required: true
default: _tmp
outputs:
success:
description: "The result of the comparison."
value: ${{ steps.compare.outputs.success == 'true' && ( inputs.compareNuspec == 'false' || steps.compare-nuspec.outputs.success == 'true' ) }}
runs:
using: "composite"
steps:
- name: "Make temporary directory for lhs extraction"
id: mktemp-lhs
uses: act/common/utils/mktemp@master
with:
outputType: dir
tmpDir: ${{ inputs.tmpDir }}
- name: "Make temporary directory for rhs extraction"
id: mktemp-rhs
uses: act/common/utils/mktemp@master
with:
outputType: dir
tmpDir: ${{ inputs.tmpDir }}
- name: "Extract lhs."
uses: act/common/utils/extract@master
with:
file: ${{ inputs.lhs }}
outputDir: ${{ steps.mktemp-lhs.outputs.tmp }}
- name: "Extract rhs."
uses: act/common/utils/extract@master
with:
file: ${{ inputs.rhs }}
outputDir: ${{ steps.mktemp-rhs.outputs.tmp }}
- name: "Disassemble lhs dlls."
uses: act/common/mono/ikdasm-files@master
with:
directory: ${{ steps.mktemp-lhs.outputs.tmp }}/lib
deleteAssemblies: true
removeComments: true
- name: "Disassemble rhs dlls."
uses: act/common/mono/ikdasm-files@master
with:
directory: ${{ steps.mktemp-rhs.outputs.tmp }}/lib
deleteAssemblies: true
removeComments: true
- name: "Get shasum for lhs."
id: lhs-shasum
uses: act/common/utils/shasum-files@master
with:
directory: ${{ steps.mktemp-lhs.outputs.tmp }}/lib
pattern: "*"
- name: "Get shasum for rhs."
id: rhs-shasum
uses: act/common/utils/shasum-files@master
with:
directory: ${{ steps.mktemp-rhs.outputs.tmp }}/lib
pattern: "*"
- name: "Compare lhs and rhs."
id: compare
uses: act/common/utils/compare@master
with:
expected: ${{ steps.lhs-shasum.outputs.sums }}
actual: ${{ steps.rhs-shasum.outputs.sums }}
exitOnFail: ${{ inputs.exitOnFail }}
#TODO: Use a yq expression to remove the git sha and version before comparing.
- name: "Compare nuspec files."
id: compare-nuspec
if: ${{ inputs.compareNuspec == 'true' }}
uses: act/common/utils/compare-files@master
with:
expected: ${{ steps.mktemp-lhs.outputs.tmp }}
expectedPattern: /*.nuspec
actual: ${{ steps.mktemp-rhs.outputs.tmp }}
actualPattern: /*.nuspec
exitOnFail: ${{ inputs.exitOnFail }}
- name: "Take ownership of the artifacts."
uses: act/common/utils/chown@master
with:
file: ${{ inputs.tmpDir }}
- name: "Remove temporary files."
run: rm -rf "${{ inputs.tmpDir }}"
shell: bash

44
utils/compare/action.yaml Normal file
View File

@@ -0,0 +1,44 @@
name: compare
description: "Compare the output of a command to an expected value."
inputs:
expected:
description: "Expected output."
required: false
actual:
description: "Actual output."
required: true
exitOnFail:
description: "Should the program exit on a failure."
required: true
default: "true"
outputs:
success:
description: "The result of the comparison."
value: ${{ steps.compare.outputs.success }}
runs:
using: "composite"
steps:
- name: "Compare input and output"
id: compare
run: |
EXPECTED=$(cat <<EOF
${{ inputs.expected }}
EOF
)
ACTUAL=$(cat <<EOF
${{ inputs.actual }}
EOF
)
if [[ "$EXPECTED" == "$ACTUAL" ]]; then
echo "success=true" >> "$GITHUB_OUTPUT"
else
echo "success=false" >> "$GITHUB_OUTPUT"
if [[ "${{ inputs.exitOnFail }}" == "true" ]]; then
echo EXPECTED: "$EXPECTED"
echo --------------------------------
echo ACTUAL: "$ACTUAL"
exit 1
fi
fi
shell: bash

View File

@@ -5,4 +5,5 @@ if [[ -z "$OUTPUT_FILE" ]]; then
OUTPUT_FILE="$(basename $URL)"
fi
wget $URL -O "$OUTPUT_FILE"
echo "::set-output name=file::$OUTPUT_FILE"
echo "file=$OUTPUT_FILE" >> "$GITHUB_OUTPUT"

View File

@@ -0,0 +1,25 @@
#This is an example of a possible way to Unit Test a single action.
name: "Run unit tests."
on: workflow_call
jobs:
run-tests:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v3
- name: "Run Test"
id: test
uses: ./.
env:
TEST_VAR: Hello, world!
with:
input: |
And I say:
"$TEST_VAR"
- name: "Verify output."
uses: act/common/utils/compare@master
with:
expected: |
And I say:
"Hello, world!"
actual: |
${{ steps.test.outputs.result }}

View File

@@ -0,0 +1,31 @@
name: envsubst
description: "Substitute environment variables in the given input."
inputs:
input:
description: "Input to substitute."
required: false
tmpDir:
description: "Temporary directory. Default: _tmp"
required: true
default: _tmp
outputs:
result:
description: "The result of the substitution."
value: ${{ steps.envsubst.outputs.console }}
runs:
using: "composite"
steps:
- name: "Make temporary file of input."
id: mktmp
uses: act/common/utils/mktemp@master
with:
input: ${{ inputs.input }}
tmpDir: ${{ inputs.tmpDir }}
- name: "Download file."
id: envsubst
uses: act/common/distros/rockylinux@master
with:
args: envsubst < ${{ steps.mktmp.outputs.tmp }}
- name: "Remove temporary files."
run: rm -rf "${{ inputs.tmpDir }}"
shell: bash

View File

@@ -27,9 +27,9 @@ runs:
COMMAND="unzip ${{ inputs.prefixArgs }} -o ${{ inputs.file }} ${{ inputs.additionalArgs }}"
OUTPUT_DIR="${{ inputs.outputDir }}"
if [[ -n "$OUTPUT_DIR" ]]; then
COMMAND="$COMMAND" -d "$OUTPUT_DIR"
COMMAND="$COMMAND -d \"$OUTPUT_DIR\""
fi
echo "::set-output name=command::$COMMAND"
echo "command=$COMMAND" >> "$GITHUB_OUTPUT"
shell: bash
- name: "Convert file."
id: convert
@@ -39,7 +39,8 @@ runs:
- name: "Delete source."
run: |
if [[ ${{ inputs.deleteSource }} != "true" ]]; then
return
exit 0
fi
rm ${{ inputs.file }}
shell: bash

View File

@@ -0,0 +1,44 @@
name: get-latest-version
description: "Get the latest version of a package."
inputs:
versions:
description: "Newline-seperated list of package versions."
required: true
filter:
description: "String to filter by."
required: false
filterIsExpression:
description: "Is the first filter a Regular Expression? Values: true, false."
required: false
default: "false"
stripPrerelease:
description: "Whether or not to strip prerelease versions. Values: true, false."
required: false
default: "false"
outputs:
version:
description: "The latest version of the specified package."
value: ${{ steps.parse.outputs.version }}
runs:
using: "composite"
steps:
- name: "Get latest package."
id: parse
run: |
VERSIONS="${{ inputs.versions }}"
# Filter versions, sort them, and get the latest one
if [[ "${{ inputs.filterIsExpression }}" == "true" ]]; then
EXPRESSION_FLAG="-E"
fi
if [[ "${{ inputs.stripPrerelease }}" == "true" ]]; then
VERSIONS=$(echo "$VERSIONS" | grep -E "^(v)?[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?$")
fi
RESULT=$(echo "$VERSIONS" | grep $EXPRESSION_FLAG "${{ inputs.filter }}" || echo "error")
VERSION=$(echo "$RESULT" | sort -rV | head -1)
if [[ "$RESULT" != "error" ]]; then
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
fi
# No error if no versions found.
shell: bash

View File

@@ -0,0 +1,29 @@
name: inputtype
description: "Determine whether the input is a file, directory, or raw input."
inputs:
input:
description: "Input contents."
required: true
outputs:
type:
description: "Whether the input is a file, dir (directory), or raw input."
value: ${{ steps.gettype.outputs.type }}
runs:
using: "composite"
steps:
- name: "Make the temporary file."
id: gettype
run: |
#Store in a heredoc to account for quotes.
INPUT=$(cat <<EOF
${{ inputs.input }}
EOF
)
TYPE="raw"
if [[ -f "$INPUT" ]]; then
TYPE="file"
elif [[ -d "$INPUT" ]]; then
TYPE="dir"
fi
echo "type=$TYPE" >> "$GITHUB_OUTPUT"
shell: bash

55
utils/mktemp/action.yaml Normal file
View File

@@ -0,0 +1,55 @@
name: mktemp
description: "Make a temporary file or directory with the specified contents."
inputs:
input:
description: "Contents of the temporary file or directory."
required: false
default: ""
inputType:
description: "How the input should be parsed. Options: raw, file, dir, expression, auto"
required: false
default: auto
outputType:
description: "How the input should be output. Options: file, dir, auto"
required: false
default: auto
transferType:
description: "How the input should be transferred. Options: copy, move"
required: false
default: copy
tmpDir:
description: "Temporary directory. Default: /tmp"
required: true
default: /tmp
additionalArgs:
description: "Additional arguments to pass in."
required: false
outputs:
tmp:
description: "The name of the temporary file or directory."
value: ${{ steps.mktemp.outputs.tmp }}
runs:
using: "composite"
steps:
- name: "Get the proper input type."
if: ${{ inputs.inputType == 'auto' }}
id: getinputtype
uses: act/common/utils/inputtype@master
with:
input: ${{ inputs.input }}
- name: "Make the temporary file."
id: mktemp
run: |
INPUT_TYPE="${{ inputs.inputType }}"
if [[ $INPUT_TYPE == 'auto' ]]; then
INPUT_TYPE="${{ steps.getinputtype.outputs.type }}"
fi
#Store in a heredoc to account for quotes.
INPUT=$(cat <<EOF
${{ inputs.input }}
EOF
)
bash ${{ github.action_path }}/make_temp.sh "$INPUT" "$INPUT_TYPE" "${{ inputs.outputType }}" "${{ inputs.transferType }}" "${{ inputs.tmpDir }}" "${{ inputs.additionalArgs }}"
shell: bash

54
utils/mktemp/make_temp.sh Normal file
View File

@@ -0,0 +1,54 @@
#!/bin/bash
INPUT="$1"
INPUT_TYPE="$2"
OUTPUT_TYPE="$3"
TRANSFER_TYPE="$4"
TMP_DIR="$5"
MKTEMP_ARGS="$6"
# match up the output type to the input type.
if [[ $OUTPUT_TYPE == 'auto' ]]; then
if [[ $INPUT_TYPE == 'raw' ]]; then
OUTPUT_TYPE="file"
elif [[ $INPUT_TYPE == 'expression' ]]; then
OUTPUT_TYPE="dir"
else
OUTPUT_TYPE="$INPUT_TYPE"
fi
fi
if [[ $INPUT_TYPE == 'raw' && $OUTPUT_TYPE == 'dir' && -n "$INPUT" ]]; then
echo "Can't output raw input to a temporary directory."
exit 1
fi
if [[ $OUTPUT_TYPE == "dir" ]]; then
MKTEMP_ARGS="-d $MKTEMP_ARGS"
fi
mkdir -p "$TMP_DIR"
TMP=$(mktemp -p "$TMP_DIR" $MKTEMP_ARGS)
echo "tmp=$TMP" >> "$GITHUB_OUTPUT"
if [[ -z "$INPUT" ]]; then
exit 0
fi
TRANSFER_COMMAND="cp -r"
if [[ $TRANSFER_TYPE == 'move' ]]; then
TRANSFER_COMMAND="mv"
fi
if [[ $INPUT_TYPE == 'raw' ]]; then
echo "$INPUT" > "$TMP"
elif [[ $OUTPUT_TYPE == 'file' ]]; then
$TRANSFER_COMMAND "$INPUT" "$TMP"
elif [[ $OUTPUT_TYPE == 'dir' ]]; then
if [[ $INPUT_TYPE == "expression" ]]; then
$TRANSFER_COMMAND $INPUT "$TMP"
else
$TRANSFER_COMMAND "$INPUT" "$TMP"
fi
fi

View File

@@ -0,0 +1,28 @@
name: shasum-files
description: "Output the shasum of files in a directory matching a pattern."
inputs:
directory:
description: "Directory to search."
required: true
default: '.'
pattern:
description: "Pattern of files to search for."
required: true
default: '*'
outputs:
sums:
description: "The sums of the files matching the pattern."
value: ${{ steps.sums.outputs.sums }}
runs:
using: "composite"
steps:
- name: "Get sums of files matching the pattern"
id: sums
run: |
OUTPUT=$(bash ${{ github.action_path }}/get_sums.sh "${{ inputs.directory }}" "${{ inputs.pattern }}")
if [[ -n "$OUTPUT" ]]; then
echo "sums<<EOF" >> "$GITHUB_OUTPUT"
echo "$OUTPUT" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
fi
shell: bash

View File

@@ -0,0 +1,12 @@
#!/bin/bash
# Get the directory and pattern as arguments
DIR=$1
PATTERN=$2
find "$DIR" -type f -name "$PATTERN" -print0 | while IFS= read -r -d '' file; do
# compute the sha256 hash of the file using sha256sum command
HASH=$(sha256sum "$file" | cut -d " " -f1)
NAME=$(basename "$file")
# print the file name and hash to a temporary file
echo "$NAME: $HASH"
done

View File

@@ -0,0 +1,47 @@
name: urlencode
description: "Encode or decode the input string as a url."
inputs:
input:
description: "Input to encode/decode."
required: true
mild:
description: "Do a mild conversion."
required: false
default: "false"
decode:
description: "Whether or not to decode instead of encode."
required: true
default: "false"
outputs:
result:
description: "The url-encoded or decoded string."
value: ${{ steps.url.outputs.console }}
runs:
using: "composite"
steps:
- name: "Build the command."
id: command
run: |
COMMAND="urlencode"
DECODE="${{ inputs.decode }}"
if [[ "$DECODE" == "true" ]]; then
COMMAND="$COMMAND -d"
fi
MILD="${{ inputs.mild }}"
if [[ "$MILD" == "true" ]]; then
if [[ "$DECODE" == "true" ]]; then
echo "Cannot perform url decoding in mild mode."
exit 1
fi
COMMAND="$COMMAND -m"
fi
echo "command=$COMMAND" >> "$GITHUB_OUTPUT"
shell: bash
- name: "Encode/decode the input."
id: url
uses: act/common/distros/debian@master
with:
args: ${{ steps.command.outputs.command }} "${{ inputs.input }}"

18
utils/uuid/action.yaml Normal file
View File

@@ -0,0 +1,18 @@
name: uuid
description: "Download a file from a URL."
inputs:
additionalArgs:
description: "Additional arguments to pass in."
required: false
outputs:
uuid:
description: "The unique identifier output."
value: ${{ steps.uuid.outputs.console }}
runs:
using: "composite"
steps:
- name: "Download file."
id: uuid
uses: act/common/distros/rockylinux@master
with:
args: uuid ${{ inputs.additionalArgs }}

View File

@@ -0,0 +1,57 @@
name: version-increment-branch
description: "Get the latest and next version of a package from a NuGet repository based on the current branch and merge target."
inputs:
version:
description: "The version to increment."
required: false
outputs:
nextVersion:
description: "The next version of the package, based on the current branch and merge target."
value: ${{ steps.increment.outputs.nextVersion }}
baseVersion:
description: "Base of the branch-defined version."
value: ${{ steps.branch.outputs.baseVersion }}
majorMinorPatchVersion:
description: "Major.Minor.Patch of the latest version."
value: ${{ steps.branch.outputs.majorMinorPatchVersion }}
runs:
using: "composite"
steps:
- name: "Get latest non-pre-release NuGet package version."
id: parse
uses: act/common/utils/version-parse@master
with:
version: ${{ inputs.version }}
- name: "Build the next version with the given repository information."
id: branch
run: |
EVENT_NAME="${{ github.event_name }}"
HEAD="${{ github.head_ref || github.ref_name }}"
BASE="${{ github.base_ref || github.ref_name }}"
PR_NUMBER="${{ github.event.number || '-1' }}"
MAJOR="${{ steps.parse.outputs.major || '0' }}"
MINOR="${{ steps.parse.outputs.minor || '0' }}"
PATCH="${{ steps.parse.outputs.patch || '0' }}"
LAST_MMP_VERSION="$MAJOR.$MINOR.$PATCH"
REVISION="${{ steps.parse.outputs.revision || '0' }}"
bash ${{ github.action_path }}/get_next_version.sh "$EVENT_NAME" "$HEAD" "$BASE" "$PR_NUMBER" "$LAST_MMP_VERSION" "$REVISION"
shell: bash
- name: "Parse the version to increment."
id: parseNext
uses: act/common/utils/version-parse@master
with:
version: ${{ steps.branch.outputs.currentVersion }}
- name: "Get next version."
id: increment
uses: act/common/utils/version-increment@master
with:
incrementMode: revision
major: ${{ steps.parseNext.outputs.major }}
minor: ${{ steps.parseNext.outputs.minor }}
patch: ${{ steps.parseNext.outputs.patch }}
revision: ${{ steps.parseNext.outputs.revision }}
suffix: ${{ steps.parseNext.outputs.suffix }}
metadata: ${{ steps.parseNext.outputs.metadata }}

View File

@@ -0,0 +1,30 @@
#!/bin/bash
function compare_versions
{
# Check if two arguments are given
if [ $# -ne 2 ]; then
echo "Please provide two version numbers to compare"
return 1
fi
# Assign arguments to local variables
local ver1=$1
local ver2=$2
# Remove dots and pad with zeros
ver1=${ver1//./}
ver2=${ver2//./}
printf -v ver1 "%-4s" "$ver1"
printf -v ver2 "%-4s" "$ver2"
ver1=${ver1// /0}
ver2=${ver2// /0}
# Compare as integers and return result
if [ $ver1 -lt $ver2 ]; then
return -1
elif [ $ver1 -gt $ver2 ]; then
return 1
else
return 0
fi
}

View File

@@ -0,0 +1,52 @@
#!/bin/bash
FILE_PATH=$(readlink -f "$BASH_SOURCE")
FILE_DIR=$(dirname "$FILE_PATH")
source "$FILE_DIR/compare_versions.sh"
EVENT_NAME="$1"
HEAD="$2"
BASE="$3"
PR_NUMBER="$4"
LATEST_MMP_VERSION="$5" # Latest major.minor.patch version.
LATEST_REVISION="${6:-0}"
if [[ ! -f "$GITHUB_OUTPUT" ]]; then
# Write to stdout if the output file doesn't exist.
GITHUB_OUTPUT="/dev/fd/1"
fi
BASE_VERSION=$(echo "$BASE" | cut -d '/' -sf 2 | xargs)
# Remove the first v in the version if it has onem as well as invalid characters.
BASE_VERSION="${BASE_VERSION#v}"
# Convert the base to a valid semver version. Anything not alphanumeric or a - or ..
BASE_VERSION="${BASE_VERSION//[^a-z0-9\-\.]/-}"
if [[ -z "$BASE_VERSION" ]]; then
# Just use the latest version as a base if the release branch has no possible versions.
BASE_VERSION="$LATEST_MMP_VERSION"
fi
echo "majorMinorPatchVersion=$BASE_VERSION" >> "$GITHUB_OUTPUT"
# Convert the head to a valid semver patch version. Anything not alphanumeric or a -.
HEAD="${HEAD//[^a-z0-9\-]/-}"
compare_versions "$BASE_VERSION" "$LATEST_MMP_VERSION"
if [[ $? == 1 ]]; then
# If the base version is greater than the latest version, then set the increment mode to 'patch'
LATEST_REVISION=0
fi
if [[ "$EVENT_NAME" == "pull_request" ]]; then
# Use the branch name as a prerelease version and increment the revision.
BASE_VERSION="$BASE_VERSION-$PR_NUMBER.$HEAD"
CURRENT_VERSION="$BASE_VERSION.$LATEST_REVISION"
elif [[ "$EVENT_NAME" != "push" && "$EVENT_NAME" != "workflow_dispatch" ]]; then
echo "Invalid event name to attempt to push a package on: $EVENT_NAME"
exit 1
fi
CURRENT_VERSION="$BASE_VERSION.$LATEST_REVISION"
echo "baseVersion=$BASE_VERSION" >> "$GITHUB_OUTPUT"
echo "currentVersion=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"

View File

@@ -0,0 +1,59 @@
name: version-increment
description: "Increment a semantic version 2.0."
inputs:
incrementMode:
description: "The mode to increment by. Options: 'default', 'major', 'minor', 'patch', 'revision'"
required: true
default: default
gitShaMetadata:
description: "Whether or not to update the git sha in the metadata."
required: false
default: "false"
major:
description: "The latest major version of the package."
required: false
minor:
description: "The latest minor version of the package."
required: false
patch:
description: "The latest patch version of the package."
required: false
revision:
description: "The latest patch revision version of the package. The suffix treated as a number seperated by a '.'"
required: false
suffix:
description: "The suffix of the package."
required: false
metadata:
description: "The metadata of the package."
required: false
outputs:
nextVersion:
description: "The next version of the package."
value: ${{ steps.parse.outputs.nextVersion }}
nextMajor:
description: "The next major version of the package."
value: ${{ steps.parse.outputs.nextMajor }}
nextMinor:
description: "The next minor version of the package."
value: ${{ steps.parse.outputs.nextMinor }}
nextPatch:
description: "The next patch version of the package."
value: ${{ steps.parse.outputs.nextPatch }}
nextRevision:
description: "The next patch revision version of the package."
value: ${{ steps.parse.outputs.nextRevision }}
nextSuffix:
description: "The next version of suffix of the package."
value: ${{ steps.parse.outputs.nextSuffix }}
nextMetadata:
description: "The next version of metadata of the package."
value: ${{ steps.parse.outputs.nextMetadata }}
runs:
using: "composite"
steps:
- name: "Get next version."
id: parse
run: |
bash ${{ github.action_path }}/increment_version.sh "${{ inputs.major }}" "${{ inputs.minor }}" "${{ inputs.patch }}" "${{ inputs.revision }}" "${{ inputs.suffix }}" "${{ inputs.metadata }}" "${{ inputs.incrementMode }}" "${{ inputs.gitShaMetadata }}"
shell: bash

View File

@@ -0,0 +1,67 @@
#!/bin/bash
MAJOR="$1"
MINOR="$2"
PATCH="$3"
REVISION="$4"
SUFFIX="$5"
METADATA="$6"
INCREMENT_MODE="${7:-default}"
GIT_SHA_METADATA="$8"
if [[ ! -f "$GITHUB_OUTPUT" ]]; then
# Write to stdout if the output file doesn't exist.
GITHUB_OUTPUT="/dev/fd/1"
fi
NEXT_MAJOR=$((MAJOR + 1))
NEXT_MINOR=$((MINOR + 1))
NEXT_PATCH=$((PATCH + 1))
NEXT_REVISION=$((REVISION + 1))
NEXT_SUFFIX="$SUFFIX"
NEXT_METADATA="$METADATA"
if [[ "$GIT_SHA_METADATA" == "true" ]]; then
NEXT_METADATA="$GITHUB_SHA"
fi
echo "nextMajor=$NEXT_MAJOR" >> "$GITHUB_OUTPUT"
echo "nextMinor=$NEXT_MINOR" >> "$GITHUB_OUTPUT"
echo "nextPatch=$NEXT_PATCH" >> "$GITHUB_OUTPUT"
echo "nextRevision=$NEXT_REVISION" >> "$GITHUB_OUTPUT"
echo "nextSuffix=$NEXT_SUFFIX" >> "$GITHUB_OUTPUT"
echo "nextMetadata=$NEXT_METADATA" >> "$GITHUB_OUTPUT"
# This script assumes that thre version numbers is the desired default format.
NEXT_VERSION="${MAJOR:-0}.${MINOR:-0}"
if [[ "$INCREMENT_MODE" == "default" ]]; then
if [[ -n "$REVISION" ]]; then
NEXT_VERSION="$NEXT_VERSION.${PATCH:-0}.$NEXT_REVISION"
elif [[ -n "$PATCH" ]]; then
NEXT_VERSION="$NEXT_VERSION.$NEXT_PATCH"
elif [[ -n "$MINOR" ]]; then
NEXT_VERSION="${MAJOR:-0}.$NEXT_MINOR.0"
else
NEXT_VERSION="$NEXT_MAJOR.0.0"
fi
elif [[ "$INCREMENT_MODE" == "major" ]]; then
NEXT_VERSION="$NEXT_MAJOR.0.0"
elif [[ "$INCREMENT_MODE" == "minor" ]]; then
NEXT_VERSION="${MAJOR:-0}.$NEXT_MINOR.0"
elif [[ "$INCREMENT_MODE" == "patch" ]]; then
NEXT_VERSION="${MAJOR:-0}.${MINOR:-0}.$NEXT_PATCH"
elif [[ "$INCREMENT_MODE" == "revision" ]]; then
NEXT_VERSION="${MAJOR:-0}.${MINOR:-0}.${PATCH:-0}.$NEXT_REVISION"
else
echo "Invalid increment mode: $INCREMENT_MODE"
exit 1
fi
if [[ -n "$NEXT_SUFFIX" ]]; then
NEXT_VERSION="$NEXT_VERSION-$NEXT_SUFFIX"
fi
if [[ -n "$NEXT_METADATA" ]]; then
NEXT_VERSION="$NEXT_VERSION+$NEXT_METADATA"
fi
echo "nextVersion=$NEXT_VERSION" >> "$GITHUB_OUTPUT"

View File

@@ -0,0 +1,38 @@
name: version-parse
description: "Parse a semantic version."
inputs:
version:
description: "The version to parse."
required: true
outputs:
version:
description: "The version of the package."
value: ${{ steps.parse.outputs.version }}
major:
description: "The major version of the package."
value: ${{ steps.parse.outputs.major }}
minor:
description: "The minor version of the package."
value: ${{ steps.parse.outputs.minor }}
patch:
description: "The patch version of the package."
value: ${{ steps.parse.outputs.patch }}
revision:
description: "The patch revision version of the package. The suffix treated as a number seperated by a '.'"
value: ${{ steps.parse.outputs.revision }}
metadata:
description: "The of the package."
value: ${{ steps.parse.outputs.metadata }}
suffix:
description: "The suffix of the package."
value: ${{ steps.parse.outputs.suffix }}
isPrerelease:
description: "Whether or not the package is a prerelease package."
value: ${{ steps.parse.outputs.isPrerelease }}
runs:
using: "composite"
steps:
- name: "Parse version."
id: parse
run: bash ${{ github.action_path }}/parse_version.sh "${{ inputs.version }}"
shell: bash

View File

@@ -0,0 +1,30 @@
#!/bin/bash
VERSION="$1"
if [[ ! -f "$GITHUB_OUTPUT" ]]; then
# Write to stdout if the output file doesn't exist.
GITHUB_OUTPUT="/dev/fd/1"
fi
IS_PRERELEASE=$(echo "$VERSION" | grep -c '-')
if [[ "$IS_PRERELEASE" == 0 ]]; then
IS_PRERELEASE=false
else
IS_PRERELEASE=true
fi
echo "isPrerelease=$IS_PRERELEASE" >> "$GITHUB_OUTPUT"
MAJOR=$(echo "$VERSION" | cut -d '.' -f 1 | cut -d '+' -f 1 | xargs printf %d 2> /dev/null)
MINOR=$(echo "$VERSION" | cut -d '.' -f 2 | cut -d '+' -f 1 | xargs printf %d 2> /dev/null)
PATCH=$(echo "$VERSION" | cut -d '.' -f 3 | cut -d '-' -f 1 | xargs | cut -d '+' -f 1 | xargs printf %d 2> /dev/null)
REVISION=$(echo "$VERSION" | cut -d '.' -f 4 | cut -d '-' -f 1 | cut -d '+' -f 1 | xargs printf %d 2> /dev/null)
SUFFIX=$(echo "$VERSION" | sed "s|^$MAJOR.$MINOR.$PATCH||" | sed "s|^.$REVISION||" | sed "s|^-||" | cut -d '+' -f 1 | xargs)
METADATA=$(echo "$VERSION" | cut -d '+' -sf 2 | xargs) # Empty if no delimeter '+' present.
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "major=$MAJOR" >> "$GITHUB_OUTPUT"
echo "minor=$MINOR" >> "$GITHUB_OUTPUT"
echo "patch=$PATCH" >> "$GITHUB_OUTPUT"
echo "revision=$REVISION" >> "$GITHUB_OUTPUT"
echo "suffix=$SUFFIX" >> "$GITHUB_OUTPUT"
echo "metadata=$METADATA" >> "$GITHUB_OUTPUT"