diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml new file mode 100644 index 0000000..5db39ba --- /dev/null +++ b/.github/workflows/auto-tag.yml @@ -0,0 +1,201 @@ +name: Auto Tag + +on: + push: + branches: + - main + pull_request: + types: + - labeled + issue_comment: + types: + - created + workflow_dispatch: + inputs: + force_bump: + description: 'Force version bump (major, minor, or patch)' + required: false + type: choice + options: + - major + - minor + - patch + +permissions: + contents: write + +jobs: + auto-tag: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check for release trigger + id: check-trigger + run: | + SHOULD_RUN=false + + if [[ "${{ github.event_name }}" == "push" ]]; then + SHOULD_RUN=true + echo "Triggered by push to main" + elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + SHOULD_RUN=true + echo "Triggered by manual workflow dispatch" + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + LABEL="${{ github.event.label.name }}" + if [[ "$LABEL" == "release" ]] || [[ "$LABEL" == "autorelease" ]]; then + SHOULD_RUN=true + echo "Triggered by label: $LABEL" + fi + elif [[ "${{ github.event_name }}" == "issue_comment" ]]; then + COMMENT="${{ github.event.comment.body }}" + if [[ "$COMMENT" == "/release" ]] || [[ "$COMMENT" == "/autorelease" ]]; then + SHOULD_RUN=true + echo "Triggered by comment: $COMMENT" + fi + fi + + echo "should-run=${SHOULD_RUN}" >> $GITHUB_OUTPUT + + if [ "$SHOULD_RUN" = false ]; then + echo "Release trigger not found, skipping" + exit 0 + fi + + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Get current version from pom.xml + id: current-version + run: | + VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "Current version: ${VERSION}" + + - name: Get latest tag + id: latest-tag + run: | + LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + echo "tag=${LATEST_TAG}" >> $GITHUB_OUTPUT + echo "Latest tag: ${LATEST_TAG}" + + - name: Analyze commits since last tag + id: analyze-commits + run: | + # Check if force_bump is provided + if [ -n "${{ inputs.force_bump }}" ]; then + echo "Force bump: ${{ inputs.force_bump }}" + echo "bump=${{ inputs.force_bump }}" >> $GITHUB_OUTPUT + exit 0 + fi + + # For label/comment triggers, default to patch + if [[ "${{ github.event_name }}" == "pull_request" ]] || [[ "${{ github.event_name }}" == "issue_comment" ]]; then + echo "Label/comment trigger, defaulting to patch bump" + echo "bump=patch" >> $GITHUB_OUTPUT + exit 0 + fi + + if [ -z "${{ steps.latest-tag.outputs.tag }}" ]; then + COMMIT_RANGE="HEAD" + else + COMMIT_RANGE="${{ steps.latest-tag.outputs.tag }}..HEAD" + fi + + echo "Analyzing commits: ${COMMIT_RANGE}" + + # Get commit messages + COMMITS=$(git log ${COMMIT_RANGE} --pretty=format:"%s") + + if [ -z "$COMMITS" ]; then + echo "No commits to analyze" + echo "bump=none" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "Commits:" + echo "$COMMITS" + + # Determine version bump based on conventional commits + BUMP="patch" + + while IFS= read -r commit; do + # Check for breaking changes (feat! or !:) + if [[ "$commit" =~ ^feat!|!.*: ]] || [[ "$commit" =~ BREAKING\ CHANGE ]]; then + BUMP="major" + echo "Found breaking change: ${commit}" + break + # Check for features + elif [[ "$commit" =~ ^feat: ]]; then + if [ "$BUMP" != "major" ]; then + BUMP="minor" + echo "Found feature: ${commit}" + fi + fi + done <<< "$COMMITS" + + echo "bump=${BUMP}" >> $GITHUB_OUTPUT + echo "Version bump: ${BUMP}" + + - name: Calculate new version + id: new-version + run: | + CURRENT="${{ steps.current-version.outputs.version }}" + BUMP="${{ steps.analyze-commits.outputs.bump }}" + + if [ "$BUMP" = "none" ]; then + echo "No version bump needed" + echo "new-version=${CURRENT}" >> $GITHUB_OUTPUT + echo "should-tag=false" >> $GITHUB_OUTPUT + exit 0 + fi + + # Parse current version (remove -SNAPSHOT if present) + CLEAN_VERSION=${CURRENT%-SNAPSHOT} + + # Split version into parts + IFS='.' read -r MAJOR MINOR PATCH <<< "$CLEAN_VERSION" + + # Apply version bump + case "$BUMP" in + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + patch) + PATCH=$((PATCH + 1)) + ;; + esac + + NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}" + echo "new-version=${NEW_VERSION}" >> $GITHUB_OUTPUT + echo "should-tag=true" >> $GITHUB_OUTPUT + echo "New version: ${NEW_VERSION}" + + - name: Update pom.xml version + if: steps.new-version.outputs.should-tag == 'true' + run: | + NEW_VERSION="${{ steps.new-version.outputs.new-version }}" + mvn versions:set -DnewVersion=${NEW_VERSION} + git add pom.xml + git commit -m "chore: bump version to ${NEW_VERSION}" + git push + + - name: Create and push tag + if: steps.new-version.outputs.should-tag == 'true' + run: | + NEW_VERSION="${{ steps.new-version.outputs.new-version }}" + git tag -a v${NEW_VERSION} -m "Release v${NEW_VERSION}" + git push origin v${NEW_VERSION} diff --git a/.github/workflows/create-tag.yml b/.github/workflows/create-tag.yml new file mode 100644 index 0000000..98b0ead --- /dev/null +++ b/.github/workflows/create-tag.yml @@ -0,0 +1,48 @@ +name: Create Tag + +on: + workflow_dispatch: + inputs: + version: + description: 'Version tag (e.g., v0.2.0)' + required: true + type: string + prerelease: + description: 'Mark as prerelease' + required: false + type: boolean + default: false + +permissions: + contents: write + +jobs: + create-tag: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure Git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Update pom.xml version + run: | + VERSION=${{ inputs.version }} + # Remove 'v' prefix if present + CLEAN_VERSION=${VERSION#v} + mvn versions:set -DnewVersion=${CLEAN_VERSION} + git add pom.xml + git commit -m "chore: bump version to ${CLEAN_VERSION}" + git push + + - name: Create and push tag + run: | + git tag -a ${{ inputs.version }} -m "Release ${{ inputs.version }}" + git push origin ${{ inputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..7a568fb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,87 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + version: + description: 'Version to release (e.g., v0.2.0)' + required: true + type: string + prerelease: + description: 'Mark as prerelease' + required: false + type: boolean + default: false + +permissions: + contents: write + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up JDK 25 + uses: actions/setup-java@v4 + with: + java-version: '25' + distribution: 'temurin' + cache: 'maven' + + - name: Extract version from tag or input + id: version + run: | + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + VERSION="${{ inputs.version }}" + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "prerelease=${{ inputs.prerelease }}" >> $GITHUB_OUTPUT + elif [[ "${{ github.ref }}" == refs/tags/* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + echo "version=${VERSION}" >> $GITHUB_OUTPUT + + # Detect if this is a prerelease + if [[ "$VERSION" =~ -alpha|-beta|-rc|-prerelease|prerelease ]]; then + echo "prerelease=true" >> $GITHUB_OUTPUT + else + echo "prerelease=false" >> $GITHUB_OUTPUT + fi + else + echo "version=dev" >> $GITHUB_OUTPUT + echo "prerelease=false" >> $GITHUB_OUTPUT + fi + + - name: Build with Maven + run: mvn clean package -DskipTests + + - name: Run tests + run: mvn test + + - name: Create JAR with dependencies + run: mvn clean package -DskipTests + + - name: Generate Javadoc + run: mvn javadoc:javadoc + + - name: Create Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' + with: + tag_name: ${{ steps.version.outputs.version }} + name: Release ${{ steps.version.outputs.version }} + files: | + target/typedmemory-*.jar + target/typedmemory-*-sources.jar + target/typedmemory-*-javadoc.jar + generate_release_notes: true + draft: false + prerelease: ${{ steps.version.outputs.prerelease }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pom.xml b/pom.xml index 783fcaa..3924458 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.github.mambastudio typedmemory - 0.1.0 + 0.1.1 jar TypedMemory Strongly typed views over contiguous off-heap memory for Java.