From 27ee2a77866c29a98ab3d2a726a79ccc34db9fb5 Mon Sep 17 00:00:00 2001 From: Phil Jay Date: Wed, 18 Oct 2023 23:43:15 +1100 Subject: [PATCH 1/4] Add testing for `use_api` --- .github/workflows/test-and-release.yml | 40 ++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-and-release.yml b/.github/workflows/test-and-release.yml index 1a2bc92..e069e20 100644 --- a/.github/workflows/test-and-release.yml +++ b/.github/workflows/test-and-release.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Run ShellCheck uses: ludeeus/action-shellcheck@2.0.0 @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup bats uses: mig4/setup-bats@af9a00deb21b5d795cabfeaa8d9060410377686d # v1.2.0 @@ -34,14 +34,48 @@ jobs: - name: Test run: bats tests/*.bats + test-api: + runs-on: ubuntu-latest + env: + github_token: ${{ github.token }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Remove .git directory + run: rm -rf .git/ + + - name: Test lookup version (with API) + id: version-lookup + env: + use_api: 'true' + run: ./version-lookup.sh + + - name: Check lookup result + shell: bash + run: '[[ -n "${{ steps.version-lookup.outputs.CURRENT_VERSION }}" ]]' + + - name: Test increment version (with API) + id: version-increment + run: ./version-increment.sh + env: + current_version: ${{ steps.version-lookup.outputs.CURRENT_VERSION }} + scheme: calver + use_api: 'true' + + - name: Check increment result + shell: bash + run: '[[ "$(date +%Y.%m)" == "$(echo "${{ steps.version-increment.outputs.VERSION }}" | cut -d "." -f 1-2)" ]]' + release: needs: - lint - test + - test-api runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Lookup version id: version-lookup From 8b80e081583813da8fcff1b1370666be4bbea446 Mon Sep 17 00:00:00 2001 From: Phil Jay Date: Wed, 18 Oct 2023 23:44:09 +1100 Subject: [PATCH 2/4] Add `use_api` feature So that you don't _need_ to checkout (clone) the repo to the worker --- action.yml | 8 ++++++++ shared.sh | 14 ++++++++++++++ version-increment.sh | 30 ++++++++++++++++++++++-------- version-lookup.sh | 23 ++++++++++++++++++++--- 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/action.yml b/action.yml index 7b51a8f..b4a1e60 100644 --- a/action.yml +++ b/action.yml @@ -26,6 +26,10 @@ inputs: description: 'Specify a non-default branch to use for the release tag (the one without -pre)' required: false type: string + use_api: + description: 'Use the GitHub API to discover current tags, which avoids the need for a git checkout, but requires `curl` and `jq`' + required: false + default: false outputs: current-version: @@ -69,7 +73,9 @@ runs: run: ${{ github.action_path }}/version-lookup.sh shell: bash env: + github_token: ${{ github.token }} scheme: ${{ inputs.scheme }} + use_api: ${{ inputs.use_api }} - id: version-increment run: ${{ github.action_path }}/version-increment.sh @@ -77,6 +83,8 @@ runs: env: current_version: ${{ steps.version-lookup.outputs.CURRENT_VERSION }} increment: ${{ inputs.increment }} + github_token: ${{ github.token }} pep440: ${{ inputs.pep440 }} scheme: ${{ inputs.scheme }} release_branch: ${{ inputs.release_branch }} + use_api: ${{ inputs.use_api }} diff --git a/shared.sh b/shared.sh index ee14092..e1c97e6 100644 --- a/shared.sh +++ b/shared.sh @@ -27,6 +27,20 @@ if [[ "${pep440}" != 'false' && "${pep440}" != 'true' ]] ; then input_errors='true' fi +use_api="${use_api:-false}" +if [[ "${use_api}" != 'false' && "${use_api}" != 'true' ]] ; then + echo "🛑 Value of 'use_api' is not valid, choose from 'false' or 'true'" 1>&2 + input_errors='true' +fi + +if [[ "${use_api}" == 'true' ]] ; then + if [[ -z "${github_token:-}" ]] ; then + echo "🛑 'use_api' is true, but environment variable 'github_token' is not set" 1>&2 + input_errors='true' + fi +fi + + ##==---------------------------------------------------------------------------- ## MacOS compatibility - for local testing diff --git a/version-increment.sh b/version-increment.sh index db956e6..7036524 100755 --- a/version-increment.sh +++ b/version-increment.sh @@ -28,20 +28,34 @@ fi ## Git info - branch names, commit short ref default_branch='main' -# if we're _not_ testing, then _actually_ check the origin -if [[ -z "${BATS_VERSION:-}" ]] ; then - default_branch="$(git remote show origin | ${grep} 'HEAD branch' | cut -d ' ' -f 5)" -fi # use release_branch if not empty if [[ -n "${release_branch:-}" ]] ; then default_branch="${release_branch}" +elif [[ -z "${BATS_VERSION:-}" ]] ; then + # if we're _not_ testing, then _actually_ check the origin + if [[ "${use_api:-}" == 'true' ]] ; then + default_branch="$( + curl -fsSL \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${github_token}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}" \ + | jq -r '.default_branch' + )" + else + default_branch="$(git remote show origin | ${grep} 'HEAD branch' | cut -d ' ' -f 5)" + fi fi current_ref="${GITHUB_REF:-}" -git_commit="$(git rev-parse --short HEAD | sed 's/0*//')" # trim leading zeros, because semver doesn't allow that in - # the 'pre-release version' part, but we can't use the + char - # to make it 'build metadata' as that's not supported in K8s - # labels + +if [[ "${use_api:-}" == 'true' ]] ; then + # because we cannot use `rev-parse` with the API, we'll take a punt that 9 characters is enough for uniqueness + # shellcheck disable=SC2001 + git_commit="$(echo "${GITHUB_SHA:0:9}" | sed 's/0*//')" # Also, trim leading zeros, because semver doesn't allow that in +else # the 'pre-release version' part, but we can't use the + char + git_commit="$(git rev-parse --short HEAD | sed 's/0*//')" # to make it 'build metadata' as that's not supported in K8s +fi # labels ##==---------------------------------------------------------------------------- ## Version increment diff --git a/version-lookup.sh b/version-lookup.sh index 45ed51c..58c3fae 100755 --- a/version-lookup.sh +++ b/version-lookup.sh @@ -25,16 +25,33 @@ fi ##==---------------------------------------------------------------------------- ## Get tags from GitHub repo -# Skip if testing, otherwise pull tags +# Skip if testing, or if use_api is true, otherwise pull tags if [[ -z "${BATS_VERSION:-}" ]] ; then - git fetch --quiet --force origin 'refs/tags/*:refs/tags/*' + if [[ "${use_api:-}" != 'true' ]] ; then + git fetch --quiet --force origin 'refs/tags/*:refs/tags/*' + fi fi ##==---------------------------------------------------------------------------- ## Version parsing # detect current version - removing "v" from start of tag if it exists -current_version="$(git tag -l | { ${grep} -P "${pcre_allow_vprefix}" || true; } | sed 's/^v//g' | sort -V | tail -n 1)" +if [[ "${use_api:-}" == 'true' ]] ; then + current_version="$( + curl -fsSL \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${github_token}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/git/matching-refs/tags/" \ + | jq -r '.[].ref' | sed 's|refs/tags/||g' \ + | { ${grep} -P "${pcre_allow_vprefix}" || true; } | sed 's/^v//g' | sort -V | tail -n 1 + )" +else + current_version="$( + git tag -l \ + | { ${grep} -P "${pcre_allow_vprefix}" || true; } | sed 's/^v//g' | sort -V | tail -n 1 + )" +fi # support transition from an old reecetech calver style (yyyy-mm-Rr, where R is the literal `R`, and r is the nth release for the month) if [[ -z "${current_version:-}" ]] ; then From 95f6bcc37a9d14c619ff03997f6ed6c307dabf02 Mon Sep 17 00:00:00 2001 From: Phil Jay Date: Thu, 19 Oct 2023 00:12:50 +1100 Subject: [PATCH 3/4] Update README --- README.md | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4fadaea..82988f2 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# ➕ Version Increment +# Version Increment ➕ -## 📄 Use +## Use 📄 -### ⌨️ Example +### Example ⌨️ ```yaml - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Get next version uses: reecetech/version-increment@2023.9.3 @@ -23,7 +23,20 @@ context: . ``` -### 🔖 semver +#### API mode 🔗 + +Maybe you don't want to checkout your code in the job that calculates the version number. That's okay, you can +use the API mode: + +```yaml + - name: Get next version + uses: reecetech/version-increment@2023.10.1 + id: version + with: + use_api: true +``` + +### semver 🔖 This action will detect the current latest _normal_ semantic version (semver) from the tags in a git repository. It will increment the version as directed (by default: +1 to @@ -37,7 +50,7 @@ e.g. `1.2.7` See: https://semver.org/spec/v2.0.0.html -### 📅 calver (semver compliant) +### calver (semver compliant) 📅 Optionally, this action can provide semver compliant calendar versions (calver). In this calver scheme, the semver major, minor and patch digits map to year, @@ -57,7 +70,7 @@ If the current latest normal version is not the current year and month, then the year and month digits will be set to the current year and month, and the release digit will be reset to 1. -### 🎋 Default branch vs. any other branch +### Default branch vs. any other branch 🎋 **Default branch** @@ -68,6 +81,17 @@ Examples: * `1.2.7` * `2021.6.2` +You may override the branch to consider the release branch if it is not the default branch, by providing a specific +release branch name as an input. For example: + +```yaml + - name: Get next version + uses: reecetech/version-increment@2023.10.1 + id: version + with: + release_branch: publish +``` + **Any other branch** The action will return a _pre-release_ version if any other branch is detected @@ -79,7 +103,7 @@ Examples: * `1.2.7-pre.41218aa78` * `2021.6.2-pre.32fd19841` -### 📥 Inputs +### Inputs 📥 | name | description | required | default | | :--- | :--- | :--- | :--- | @@ -87,8 +111,9 @@ Examples: | pep440 | Set to `true` for PEP440 compatibility of _pre-release_ versions by making use of the build metadata segment of semver, which maps to local version identifier in PEP440 | No | `false` | | increment | The digit to increment, either `major`, `minor` or `patch`, ignored if `scheme` == `calver` | No | `patch` | | release_branch | Specify a non-default branch to use for the release tag (the one without -pre) | No | | +| use_api | Use the GitHub API to discover current tags, which avoids the need for a git checkout, but requires `curl` and `jq` | No | `false` | -### 📤 Outputs +### Outputs 📤 | name | description | | :--- | :--- | @@ -104,7 +129,7 @@ Examples: | minor-v-version | Minor number of the incremented version, prefixed with a `v` character | | patch-v-version | Patch number of the incremented version, prefixed with a `v` character | -## 💕 Contributing +## Contributing 💕 Please raise a pull request, but note the testing tools below From aac681e0d02b84d892b9fd3af40e4ce2ed23a886 Mon Sep 17 00:00:00 2001 From: Phil Jay Date: Thu, 19 Oct 2023 00:36:27 +1100 Subject: [PATCH 4/4] Improve testing by testing the `action.yml` --- .github/workflows/test-and-release.yml | 47 +++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-and-release.yml b/.github/workflows/test-and-release.yml index e069e20..95e4963 100644 --- a/.github/workflows/test-and-release.yml +++ b/.github/workflows/test-and-release.yml @@ -34,15 +34,15 @@ jobs: - name: Test run: bats tests/*.bats - test-api: + test-api-mode: # requires github API, didn't want to mock it runs-on: ubuntu-latest env: github_token: ${{ github.token }} steps: - - name: Checkout code + - name: Checkout code # have to checkout to have the source code available uses: actions/checkout@v4 - - name: Remove .git directory + - name: Remove .git directory # remove the git directory to make the testing valid run: rm -rf .git/ - name: Test lookup version (with API) @@ -67,11 +67,48 @@ jobs: shell: bash run: '[[ "$(date +%Y.%m)" == "$(echo "${{ steps.version-increment.outputs.VERSION }}" | cut -d "." -f 1-2)" ]]' - release: + test-action-yml: # integration testing needs: - lint - test - - test-api + - test-api-mode + runs-on: ubuntu-latest + steps: + - name: Checkout code # have to checkout to have the source code available + uses: actions/checkout@v4 + + - name: Remove .git directory # remove the git directory to make the testing valid + run: rm -rf .git/ + + - name: Get next version via API + uses: ./ + id: version-via-api + with: + scheme: 'calver' + use_api: true + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Get next version via Git + uses: ./ + id: version-via-git + with: + scheme: 'calver' + use_api: false + + - name: Check results agree + shell: bash + run: | + [[ "${{ steps.version-via-api.outputs.current-version }}" == "${{ steps.version-via-git.outputs.current-version }}" ]] + [[ "${{ steps.version-via-api.outputs.major-version }}" == "${{ steps.version-via-git.outputs.major-version }}" ]] + [[ "${{ steps.version-via-api.outputs.minor-version }}" == "${{ steps.version-via-git.outputs.minor-version }}" ]] + [[ "${{ steps.version-via-api.outputs.patch-version }}" == "${{ steps.version-via-git.outputs.patch-version }}" ]] + # Don't test the full version or pre-version, since the number of digits is likely to be different (9 via api vs. 7 via git) + + release: + needs: + - test-action-yml runs-on: ubuntu-latest steps: - name: Checkout code