diff --git a/.github/workflows/reusable-manual-update-version.yml b/.github/workflows/reusable-manual-update-version.yml index dfe48dd..96fd994 100644 --- a/.github/workflows/reusable-manual-update-version.yml +++ b/.github/workflows/reusable-manual-update-version.yml @@ -96,23 +96,27 @@ jobs: ;; esac else - current=$(task version:get 2>/dev/null || true) - if [ -z "${current}" ] && [ -f .version ]; then - current=$(tr -d '\n' < .version) - fi - if [ -z "${current}" ]; then - echo "Current version not found" - exit 1 - fi - - no_v=${current#v} - major=$(echo "${no_v}" | awk -F. '{print $1}') - minor=$(echo "${no_v}" | awk -F. '{print $2}') - patch=$(echo "${no_v}" | awk -F. '{print $3}') - if [ -z "${major}" ] || [ -z "${minor}" ] || [ -z "${patch}" ]; then - echo "Invalid current version: ${current}" - exit 1 - fi + normalize_and_validate_version() { + local input="$1" + local candidate + candidate="${input#v}" + if ! printf "%s" "${candidate}" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then + return 1 + fi + printf "v%s" "${candidate}" + } + + get_current_version() { + local current + current=$(task version:get 2>/dev/null || true) + if [ -z "${current}" ] && [ -f .version ]; then + current=$(tr -d '\n' < .version) + fi + if [ -z "${current}" ]; then + return 1 + fi + normalize_and_validate_version "${current}" + } case "${BUMP_TYPE}" in set) @@ -120,16 +124,30 @@ jobs: echo "Missing version for type=set" exit 1 fi - next="${INPUT_VERSION}" - ;; - patch) - next="v${major}.${minor}.$((patch + 1))" - ;; - minor) - next="v${major}.$((minor + 1)).0" + next=$(normalize_and_validate_version "${INPUT_VERSION}") || { + echo "Invalid explicit version: ${INPUT_VERSION}. Expected vX.Y.Z or X.Y.Z" + exit 1 + } ;; - major) - next="v$((major + 1)).0.0" + patch|minor|major) + current=$(get_current_version) || { + echo "Current version not found or invalid. Expected vX.Y.Z" + exit 1 + } + no_v=${current#v} + IFS='.' read -r major minor patch <<< "${no_v}" + + case "${BUMP_TYPE}" in + patch) + next="v${major}.${minor}.$((patch + 1))" + ;; + minor) + next="v${major}.$((minor + 1)).0" + ;; + major) + next="v$((major + 1)).0.0" + ;; + esac ;; *) echo "Unknown type: ${BUMP_TYPE}" @@ -172,30 +190,36 @@ jobs: if: ${{ inputs.build-and-push-only && inputs.profile != 'actions' && inputs.profile != 'dockerized' }} run: echo "Build-only mode requested with docker disabled; skipping image build/push" - - name: Get template + - name: Create and push release tags if: ${{ !inputs.build-and-push-only }} env: - VERSION_SUFFIX: "" + VERSION: ${{ steps.version.outputs.REL_VERSION }} run: | - task git:set-config - task git:get-pr-template + set -eux + version_no_v="${VERSION#v}" + major="v$(echo "${version_no_v}" | awk -F. '{print $1}')" + minor="v$(echo "${version_no_v}" | awk -F. '{print $1"."$2}')" - - name: Push to release branch - if: ${{ !inputs.build-and-push-only }} - uses: devops-infra/action-commit-push@v1 - with: - github_token: ${{ github.token }} - commit_message: ":rocket: Bump version to ${{ steps.version.outputs.REL_VERSION }}" - target_branch: ${{ format('release/{0}', steps.version.outputs.REL_VERSION) }} + if git ls-remote --tags origin "refs/tags/${VERSION}" | grep -q .; then + echo "Release tag ${VERSION} already exists on origin" + exit 1 + fi + + git tag --annotate "${VERSION}" --message "${VERSION}" + git push origin "refs/tags/${VERSION}" + + git tag --force --annotate "${minor}" --message "${VERSION}" + git push --force origin "refs/tags/${minor}" + + git tag --force --annotate "${major}" --message "${VERSION}" + git push --force origin "refs/tags/${major}" - - name: Create Pull Request + - name: Create GitHub release if: ${{ !inputs.build-and-push-only }} - uses: devops-infra/action-pull-request@v1 + uses: softprops/action-gh-release@v2 with: - github_token: ${{ github.token }} - assignee: ${{ github.actor }} - template: .tmp/PULL_REQUEST_TEMPLATE.md - get_diff: true + tag_name: ${{ steps.version.outputs.REL_VERSION }} + generate_release_notes: true - name: Export version output id: export-version