Skip to content

Support Initial Versioning Without Requiring a Pushed Default Tag #52

@christian-draeger

Description

@christian-draeger

Problem Description

I would like to support automatic version creation even when no previous tags exist in the repository (e.g., during the first release). Currently, I work around this by creating and pushing a default tag (0.0.0). However, this approach has several drawbacks:

  • Tag Persistence on Failure: If a subsequent step fails, the default tag is not deleted.
  • Write Permission Requirements: The action requires write permissions to push the default tag, which might not always be desirable or possible in some setups.

Desired Behavior

It would be more elegant and secure if the action could support creating a default tag locally (without pushing it to the remote) and proceed to calculate the next version. Unfortunately, when attempting this, I encounter an error, as the action seems to require a pushed tag to function correctly.
Or even better, if it would support creation of inital version based on commit messages without the need of an already existing tag.

Question

Is this behavior supported, or is there a configuration option I might be missing to enable this? If not, would it be possible to add support for local default tags or version creation without already existing tags as an enhancement?

Current Workflow Example

Here is my current GitHub Actions workflow:

name: Release

on:
  workflow_dispatch:    
    inputs:
      release_type:
        description: 'Create a release with semantic version. Either choose "conventional commit" to determine next release version automatically based on conventional commit messages or force a certain release type by selecting it manually.'
        type: choice
        required: true
        default: 'conventional commit'
        options:
          - 'conventional commit'
          - major
          - minor
          - patch
          - alpha
          - beta
          - pre
          - rc
          - stable

jobs:
  create_release:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
        
      - name: Checkout Code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

### determin previous version tag
      - name: Get latest tag
        id: previoustag
        uses: "WyriHaximus/github-action-get-previous-tag@v1"
        with:
          fallback: 0.0.0

### conventional commit
      - name: Create initial tag if no tag found
        if: ${{ steps.previoustag.outputs.tag == '0.0.0' }}
        run: |
          OLDEST_COMMIT=$(git rev-list --max-parents=0 HEAD)
          git tag 0.0.0 $OLDEST_COMMIT
          git push origin 0.0.0
          
      - name: Get Next Version based on conventional commit messages
        if: ${{ inputs.release_type == 'conventional commit' }}
        id: version_by_conventional_commit
        uses: ietf-tools/semver-action@v1
        with:
          token: ${{ github.token }}
          branch: main
          noVersionBumpBehavior: warn
          skipInvalidTags: true
          fromTag: ${{ steps.previoustag.outputs.tag }}
          
      - name: Delete temporary tag if created
        if: ${{ steps.previoustag.outputs.tag == '0.0.0' }}
        run: |
          git tag -d 0.0.0
          git push origin :0.0.0

### none conventional commit
      - name: Get Next Version based on given version fragment input
        if: ${{ inputs.release_type != 'conventional commit' }}
        id: version_by_fragment
        uses: christian-draeger/increment-semantic-version@1.2.3
        with:
          current-version: ${{ steps.previoustag.outputs.tag }}
          version-fragment: ${{ inputs.release_type }}
          
### set version
      - name: Hold new version
        id: set_version
        run: |
          if [ "${{ inputs.release_type }}" = "conventional commit" ]; then
            echo "::set-output name=new_version::${{ steps.version_by_conventional_commit.outputs.nextStrict }}"
          else
            echo "::set-output name=new_version::${{ steps.version_by_fragment.outputs.next-version }}"
          fi

      - name: Create dummy commit and tag new version
        if: ${{ steps.previoustag.outputs.tag != steps.set_version.outputs.new_version }}
        run: |
          git config user.name "GitHub Actions"
          git config user.email "actions@github.com"
          git commit --allow-empty -m "chore(release): bump version ${{ steps.previoustag.outputs.tag }} -> ${{ steps.set_version.outputs.new_version }}"
          git tag ${{ steps.set_version.outputs.new_version }}
          git push origin main --tags

Proposed Enhancement

Allow the action to:

  • Recognize a locally created default tag without requiring it to be pushed.
  • Optionally, provide a configuration option to bypass the need for a remote tag during the initial versioning step.

This would simplify the workflow, remove the need for write permissions, and ensure a cleaner setup for repositories starting from scratch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions