diff --git a/.github/workflows/validate-script.yml b/.github/workflows/validate-script.yml new file mode 100644 index 0000000..b5186b0 --- /dev/null +++ b/.github/workflows/validate-script.yml @@ -0,0 +1,11 @@ +on: [push] + +jobs: + validate-script: + runs-on: ubuntu-latest + container: + image: koalaman/shellcheck-alpine:latest + steps: + - uses: actions/checkout@v2 + - name: Validate script + run: shellcheck version.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f83af92 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM alpine:latest + +RUN apk add --no-cache bash git sed +COPY version.sh /version.sh + +ENTRYPOINT ["/version.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..6e397cc --- /dev/null +++ b/README.md @@ -0,0 +1,92 @@ +# Set version action + +This action sets the version based on either the current commit hash or tag. +The result can either be stored in the action's output or be written to a file directly. + +**Note:** Tags **MUST** be in one of the following formats or this action will fail: `vMAJOR.MINOR.PATCH` or `vMAJOR.MINOR.PATCH-identifier`. + +## Inputs + +### `target` + +**Required** Target for the version, either output or file. Default `"output"`. + +### `source` + +**Required** Source for the version, either commit or tag. Default `"commit"`. + +### `file_path` + +File path in case of file target, relative to the workspace. + +### `version_placeholder` + +Version placeholder to replace in case of file target. Default `"0.0.0+development"`. + +## Outputs + +### `version` + +The current version + +## Example usage + +### Build a Docker image using the current Git tag + +This example uses the version variable directly in the `docker build` command. + +```yaml +jobs: + build: + - name: Checkout + uses: actions/checkout@v2 + - name: Set version + uses: weareyipyip/set-version-action@v1 + id: set-version + with: + target: output + source: tag + - name: Build Docker image + run: 'docker build -t some-image:${{ steps.set-version.outputs.version }}' +``` + +### Build a Node package using the current Git tag + +This example directly replaces the version placeholder in `package.json` with the parsed version. + +```yaml +jobs: + build: + - name: Checkout + uses: actions/checkout@v2 + - name: Set version + uses: weareyipyip/set-version-action@v1 + id: set-version + with: + target: file + source: tag + file_path: package.json + - name: Build Node package + run: 'npm build' +``` + +### Build a Node package using the current Git commit + +This example directly replaces the version placeholder in `package.json` with the parsed version. +The commit hash can be used for builds that aren't tagged, e.g. automated test builds. + +```yaml +jobs: + build: + - name: Checkout + uses: actions/checkout@v2 + - name: Set version + uses: weareyipyip/set-version-action@v1 + id: set-version + with: + target: file + source: commit + file_path: package.json + - name: Build Node package + run: 'npm build' +``` diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..423ca45 --- /dev/null +++ b/action.yml @@ -0,0 +1,29 @@ +name: 'Set version' +description: 'Set the version from the current commit or tag' +inputs: + target: + description: 'Target for the version, either output or file' + required: true + default: 'output' + source: + description: 'Source for the version, either commit or tag' + required: true + default: 'commit' + file_path: + description: 'File path in case of file target, relative to the workspace' + required: false + version_placeholder: + description: 'Version placeholder to replace in case of file target' + required: false + default: '0.0.0+development' +outputs: + version: + description: 'The current version' +runs: + using: 'docker' + image: 'Dockerfile' + args: + - ${{ inputs.target }} + - ${{ inputs.source }} + - ${{ inputs.file_path }} + - ${{ inputs.version_placeholder }} diff --git a/version.sh b/version.sh new file mode 100755 index 0000000..13dec4b --- /dev/null +++ b/version.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +exit_error() { + echo "$1" 1>&2 + exit 1 +} + +parse_tag() { + if [[ "$1" =~ ^v[0-9]\.[0-9]\.[0-9](-[0-9A-Za-z\.]+)?$ ]]; then + echo -n "${1:1}" + else + exit_error "Tag must be in format 'vMAJOR.MINOR.PATCH' or 'vMAJOR.MINOR.PATCH-identifier'" + fi +} + +get_version() { + case "$1" in + "commit") + SHORT_SHA="$(git rev-parse --short "$GITHUB_SHA")" || exit 1 + echo -n "0.0.0+$SHORT_SHA" + ;; + "tag") + TAG="${GITHUB_REF#refs/*/}" + VERSION="$(parse_tag "$TAG")" || exit 1 + echo -n "$VERSION" + ;; + *) + exit_error "Invalid second argument (must be 'commit' or 'tag')" + ;; + esac +} + +case "$1" in + "output") + VERSION="$(get_version "$2")" || exit 1 + echo "::set-output name=version::$VERSION" + ;; + "file") + VERSION="$(get_version "$2")" || exit 1 + sed -i "s/$4/$VERSION/g" "$GITHUB_WORKSPACE/$3" + ;; + *) + exit_error "Invalid first argument (must be 'output' or 'file')" + ;; +esac