diff --git a/.bumpversion.toml b/.bumpversion.toml new file mode 100644 index 0000000..bf910c6 --- /dev/null +++ b/.bumpversion.toml @@ -0,0 +1,41 @@ + +[tool.bumpversion] +current_version = "0.1.0" +parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)(-(?Palpha|beta|rc)\\.(?P\\d+))?" +serialize = [ + "{major}.{minor}.{patch}-{pre_label}.{pre_n}", + "{major}.{minor}.{patch}" +] +search = "{current_version}" +replace = "{new_version}" +regex = false +ignore_missing_files = false +ignore_missing_version = false +tag = false +sign_tags = false +tag_name = "v{new_version}" +tag_message = "Release version {new_version}" +allow_dirty = false +commit = false +message = "chore: bump version {current_version} → {new_version}" + +[tool.bumpversion.parts.pre_label] +optional_value = "stable" +first_value = "stable" +values = ["stable", "alpha", "beta", "rc"] + +[tool.bumpversion.parts.pre_n] +optional_value = "0" +first_value = "0" + +# Root pom.xml - project version +[[tool.bumpversion.files]] +filename = "pom.xml" +search = "{current_version}" +replace = "{new_version}" + +# Root pom.xml - lance-flink.version property +[[tool.bumpversion.files]] +filename = "pom.xml" +search = "{current_version}" +replace = "{new_version}" diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000..1ac7750 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,37 @@ + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: 1 +appendOnly: true +# Labels are applied based on conventional commits standard +# https://www.conventionalcommits.org/en/v1.0.0/ +# These labels are later used in release notes. See .github/release.yml +labels: +# If the PR title has an ! before the : it will be considered a breaking change +# For example, `feat!: add new feature` will be considered a breaking change +- label: breaking-change + title: "^[^:]+!:.*" +- label: breaking-change + body: "BREAKING CHANGE" +- label: enhancement + title: "^feat(\\(.+\\))?!?:.*" +- label: bug + title: "^fix(\\(.+\\))?!?:.*" +- label: documentation + title: "^docs(\\(.+\\))?!?:.*" +- label: performance + title: "^perf(\\(.+\\))?!?:.*" +- label: ci + title: "^ci(\\(.+\\))?!?:.*" +- label: chore + title: "^(chore|test|build|style)(\\(.+\\))?!?:.*" diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..5950a9f --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,37 @@ + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +changelog: + exclude: + labels: + - ci + - chore + categories: + - title: Breaking Changes 🛠 + labels: + - breaking-change + - title: New Features 🎉 + labels: + - enhancement + - title: Bug Fixes 🐛 + labels: + - bug + - title: Documentation 📚 + labels: + - documentation + - title: Performance Improvements 🚀 + labels: + - performance + - title: Other Changes + labels: + - "*" diff --git a/.github/workflows/auto-bump.yml b/.github/workflows/auto-bump.yml new file mode 100644 index 0000000..acc5bd9 --- /dev/null +++ b/.github/workflows/auto-bump.yml @@ -0,0 +1,191 @@ + +name: Auto Bump Version + +on: + workflow_dispatch: + inputs: + bump_type: + description: 'Type of version bump' + required: false + default: 'auto' + type: choice + options: + - auto + - patch + - minor + - major + +jobs: + check-for-changes: + runs-on: ubuntu-latest + outputs: + should_bump: ${{ steps.check.outputs.should_bump }} + bump_type: ${{ steps.check.outputs.bump_type }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check for unreleased changes + id: check + run: | + # Get the last tag + LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + + if [ -z "$LAST_TAG" ]; then + echo "No tags found, should create initial release" + echo "should_bump=true" >> $GITHUB_OUTPUT + echo "bump_type=patch" >> $GITHUB_OUTPUT + exit 0 + fi + + # Check for commits since last tag + COMMITS_SINCE_TAG=$(git rev-list --count ${LAST_TAG}..HEAD) + + if [ "$COMMITS_SINCE_TAG" -gt 0 ]; then + echo "Found $COMMITS_SINCE_TAG commits since last tag $LAST_TAG" + + if [ "${{ inputs.bump_type }}" != "auto" ] && [ -n "${{ inputs.bump_type }}" ]; then + BUMP_TYPE="${{ inputs.bump_type }}" + else + BUMP_TYPE="patch" + + if git log ${LAST_TAG}..HEAD --grep="BREAKING CHANGE" --grep="!:" | grep -q .; then + BUMP_TYPE="major" + elif git log ${LAST_TAG}..HEAD --grep="^feat" --grep="^feature" | grep -q .; then + BUMP_TYPE="minor" + fi + fi + + echo "should_bump=true" >> $GITHUB_OUTPUT + echo "bump_type=$BUMP_TYPE" >> $GITHUB_OUTPUT + else + echo "No commits since last tag $LAST_TAG" + echo "should_bump=false" >> $GITHUB_OUTPUT + fi + + - name: Summary + run: | + echo "## Auto Bump Check" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + if [ "${{ steps.check.outputs.should_bump }}" == "true" ]; then + echo "✅ Version bump needed" >> $GITHUB_STEP_SUMMARY + echo "- **Bump Type:** ${{ steps.check.outputs.bump_type }}" >> $GITHUB_STEP_SUMMARY + else + echo "⏭️ No version bump needed" >> $GITHUB_STEP_SUMMARY + fi + + create-bump-pr: + needs: check-for-changes + if: needs.check-for-changes.outputs.should_bump == 'true' + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'temurin' + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + pip install packaging lxml + + - name: Get current version + id: current_version + run: | + CURRENT_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + echo "Current version: $CURRENT_VERSION" + + - name: Calculate new version + id: new_version + run: | + python ci/calculate_version.py \ + --current "${{ steps.current_version.outputs.version }}" \ + --type "${{ needs.check-for-changes.outputs.bump_type }}" \ + --channel "stable" + + - name: Create feature branch + run: | + BRANCH_NAME="auto-bump-${{ steps.new_version.outputs.version }}" + git checkout -b $BRANCH_NAME + echo "branch=$BRANCH_NAME" >> $GITHUB_ENV + + - name: Bump version + run: | + python ci/bump_version.py --version "${{ steps.new_version.outputs.version }}" + + - name: Configure git + run: | + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Commit changes + run: | + git add -A + git commit -m "chore: bump version to ${{ steps.new_version.outputs.version }} + + Automated version bump from ${{ steps.current_version.outputs.version }} to ${{ steps.new_version.outputs.version }}. + Bump type: ${{ needs.check-for-changes.outputs.bump_type }}" + + - name: Push changes + run: | + git push origin ${{ env.branch }} + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ env.branch }} + base: main + title: "chore: bump version to ${{ steps.new_version.outputs.version }}" + body: | + ## Automated Version Bump + + This PR automatically bumps the version from `${{ steps.current_version.outputs.version }}` to `${{ steps.new_version.outputs.version }}`. + + ### Details + - **Bump Type:** ${{ needs.check-for-changes.outputs.bump_type }} + - **Triggered By:** Manual trigger + + ### Checklist + - [ ] Review version bump changes + - [ ] Verify pom.xml is updated + - [ ] Confirm CI checks pass + + ### Next Steps + After merging this PR, you can create a release by: + 1. Going to Actions → Create Release workflow + 2. Selecting the release channel (stable/preview) + 3. Running the workflow + + --- + *This PR was automatically generated by the auto-bump workflow.* + labels: | + version-bump + automated + assignees: ${{ github.actor }} + + - name: Summary + run: | + echo "## Version Bump PR Created" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Current Version:** ${{ steps.current_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "- **New Version:** ${{ steps.new_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "- **Bump Type:** ${{ needs.check-for-changes.outputs.bump_type }}" >> $GITHUB_STEP_SUMMARY + echo "- **Branch:** ${{ env.branch }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "✅ Pull request created successfully!" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/flink.yml b/.github/workflows/flink.yml new file mode 100644 index 0000000..f996436 --- /dev/null +++ b/.github/workflows/flink.yml @@ -0,0 +1,82 @@ + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Flink + +on: + push: + branches: + - main + paths-ignore: + - 'docs/**' + - 'README.md' + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths-ignore: + - 'docs/**' + - 'README.md' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + lint: + name: Lint + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: "maven" + - name: Check code style + run: make lint + + build: + name: Build + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: "maven" + - name: Build + run: make install + + test: + name: Test + runs-on: ubuntu-24.04 + timeout-minutes: 30 + needs: build + steps: + - uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: "maven" + - name: Run tests + run: make test diff --git a/.github/workflows/lance-release-timer.yml b/.github/workflows/lance-release-timer.yml new file mode 100644 index 0000000..480692d --- /dev/null +++ b/.github/workflows/lance-release-timer.yml @@ -0,0 +1,95 @@ + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Lance Release Timer + +on: + schedule: + - cron: "*/10 * * * *" + workflow_dispatch: + +permissions: + contents: read + actions: write + +concurrency: + group: lance-release-timer + cancel-in-progress: false + +jobs: + trigger-update: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install Python dependencies + run: | + pip install lxml + + - name: Check for new Lance tag + id: check + env: + GH_TOKEN: ${{ secrets.LANCE_RELEASE_TOKEN }} + run: | + python3 ci/check_lance_release.py --github-output "$GITHUB_OUTPUT" + + - name: Look for existing PR + if: steps.check.outputs.needs_update == 'true' + id: pr + env: + GH_TOKEN: ${{ secrets.LANCE_RELEASE_TOKEN }} + run: | + set -euo pipefail + TITLE="chore: update lance dependency to v${{ steps.check.outputs.latest_version }}" + COUNT=$(gh pr list --search "\"$TITLE\" in:title" --state open --limit 1 --json number --jq 'length') + if [ "$COUNT" -gt 0 ]; then + echo "Open PR already exists for $TITLE" + echo "pr_exists=true" >> "$GITHUB_OUTPUT" + else + echo "No existing PR for $TITLE" + echo "pr_exists=false" >> "$GITHUB_OUTPUT" + fi + + - name: Create update PR + if: steps.check.outputs.needs_update == 'true' && steps.pr.outputs.pr_exists != 'true' + env: + GH_TOKEN: ${{ secrets.LANCE_RELEASE_TOKEN }} + run: | + set -euo pipefail + LATEST_VERSION="${{ steps.check.outputs.latest_version }}" + CURRENT_VERSION="${{ steps.check.outputs.current_version }}" + BRANCH_NAME="auto/update-lance-${LATEST_VERSION//[^a-zA-Z0-9]/-}" + + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + + git checkout -b "$BRANCH_NAME" + + # Update lance.version in pom.xml + sed -i "s|${CURRENT_VERSION}|${LATEST_VERSION}|" pom.xml + + git add pom.xml + git commit -m "chore: update lance dependency to v${LATEST_VERSION}" + git push origin "$BRANCH_NAME" + + gh pr create \ + --title "chore: update lance dependency to v${LATEST_VERSION}" \ + --body "Automated update of lance-core dependency from v${CURRENT_VERSION} to v${LATEST_VERSION}." \ + --base main \ + --head "$BRANCH_NAME" diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml new file mode 100644 index 0000000..2a3a0ab --- /dev/null +++ b/.github/workflows/pr-title.yml @@ -0,0 +1,95 @@ + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: PR Title Checks + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + - reopened + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + labeler: + permissions: + pull-requests: write + name: Label PR + runs-on: ubuntu-latest + steps: + - uses: srvaroa/labeler@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + fail_on_error: true + commitlint: + permissions: + pull-requests: write + name: Verify PR title / description conforms to semantic-release + runs-on: ubuntu-latest + steps: + - uses: actions/setup-node@v4 + with: + node-version: "20" + - run: npm install @commitlint/config-conventional + - run: > + echo 'module.exports = { + "rules": { + "body-max-line-length": [0, "always", Infinity], + "footer-max-line-length": [0, "always", Infinity], + "body-leading-blank": [0, "always"] + } + }' > .commitlintrc.js + - run: npx commitlint --extends @commitlint/config-conventional --verbose <<< $COMMIT_MSG + env: + COMMIT_MSG: > + ${{ github.event.pull_request.title }} + + ${{ github.event.pull_request.body }} + - if: failure() + uses: actions/github-script@v7 + with: + script: | + const message = `**ACTION NEEDED** + Lance follows the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) for release automation. + + The PR title and description are used as the merge commit message.\ + Please update your PR title and description to match the specification. + + For details on the error please inspect the "PR Title Check" action. + ` + // Get list of current comments + const comments = await github.paginate(github.rest.issues.listComments, { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number + }); + // Check if this job already commented + for (const comment of comments) { + if (comment.body === message) { + return // Already commented + } + } + // Post the comment about Conventional Commits + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: message + }) + core.setFailed(message) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..2ad7459 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,133 @@ + +name: Publish Flink packages +on: + release: + types: [published] + pull_request: + paths: + - .github/workflows/publish.yml + types: + - opened + - synchronize + - ready_for_review + - reopened + workflow_dispatch: + inputs: + mode: + description: 'Release mode' + required: true + type: choice + default: dry_run + options: + - dry_run + - release + ref: + description: 'The branch, tag or SHA to checkout' + required: false + type: string + +jobs: + release: + name: Release Flink + runs-on: ubuntu-24.04 + timeout-minutes: 60 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.tag_name || inputs.ref }} + - name: Set up Java 17 + uses: actions/setup-java@v4 + with: + distribution: corretto + java-version: 17 + cache: "maven" + server-id: ossrh + server-username: SONATYPE_USER + server-password: SONATYPE_TOKEN + gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }} + - name: Set github + run: | + git config --global user.email "Lance Github Runner" + git config --global user.name "dev+gha@lancedb.com" + - name: Dry run + if: | + github.event_name == 'pull_request' || + inputs.mode == 'dry_run' + run: | + ./mvnw --batch-mode -DskipTests package + - name: Publish to Maven Central + if: | + github.event_name == 'release' || + inputs.mode == 'release' + run: | + echo "use-agent" >> ~/.gnupg/gpg.conf + echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf + export GPG_TTY=$(tty) + ./mvnw --batch-mode -DskipTests -DpushChanges=false -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} deploy -P deploy-to-ossrh + env: + SONATYPE_USER: ${{ secrets.SONATYPE_USER }} + SONATYPE_TOKEN: ${{ secrets.SONATYPE_TOKEN }} + + - name: Get published version + if: | + github.event_name == 'release' || + inputs.mode == 'release' + id: get_version + run: | + VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Published version: $VERSION" + + - name: Wait for Maven Central availability + if: | + github.event_name == 'release' || + inputs.mode == 'release' + run: | + VERSION="${{ steps.get_version.outputs.version }}" + GROUP_ID="org.lance" + ARTIFACT_ID="lance-flink" + + echo "Waiting for version $VERSION to be available in Maven Central..." + echo "This typically takes 10-30 minutes after publishing to OSSRH." + + # Maximum wait time: 60 minutes + MAX_WAIT=3600 + INTERVAL=60 + ELAPSED=0 + + while [ $ELAPSED -lt $MAX_WAIT ]; do + URL="https://repo1.maven.org/maven2/org/lance/${ARTIFACT_ID}/${VERSION}/${ARTIFACT_ID}-${VERSION}.pom" + + if curl --head --silent --fail "$URL" > /dev/null 2>&1; then + echo "" + echo "🎉 Artifact is now available in Maven Central!" + echo "" + echo "Users can now add the following dependency:" + echo "" + echo "Maven:" + echo "" + echo " org.lance" + echo " lance-flink" + echo " ${VERSION}" + echo "" + echo "" + echo "Gradle:" + echo "implementation 'org.lance:lance-flink:${VERSION}'" + exit 0 + fi + + ELAPSED=$((ELAPSED + INTERVAL)) + + if [ $ELAPSED -lt $MAX_WAIT ]; then + echo "Artifact not yet available. Waiting ${INTERVAL} seconds... (${ELAPSED}s elapsed)" + sleep $INTERVAL + fi + done + + echo "" + echo "⚠️ WARNING: Artifact not yet available in Maven Central after ${MAX_WAIT} seconds." + echo "This is normal - Maven Central sync can take up to 2 hours." + echo "Check status at: https://central.sonatype.com/artifact/org.lance/lance-flink/${VERSION}" + exit 0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..68d9cdf --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,178 @@ + +name: Create Release + +on: + workflow_dispatch: + inputs: + release_type: + description: 'Version bump type (patch/minor/major bumps version, current keeps it unchanged)' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - major + - current + release_channel: + description: 'Release channel (preview creates beta tag, stable creates release tag)' + required: true + default: 'preview' + type: choice + options: + - preview + - stable + dry_run: + description: 'Dry run (simulate the release without pushing)' + required: true + default: true + type: boolean + +jobs: + create-release: + runs-on: ubuntu-latest + steps: + - name: Output Inputs + run: echo "${{ toJSON(github.event.inputs) }}" + + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: main + token: ${{ secrets.LANCE_RELEASE_TOKEN }} + fetch-depth: 0 + + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'temurin' + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + pip install packaging lxml bump-my-version + + - name: Get current version + id: current_version + run: | + CURRENT_VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout) + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + echo "Current version: $CURRENT_VERSION" + + - name: Calculate base version + id: base_version + run: | + python ci/calculate_version.py \ + --current "${{ steps.current_version.outputs.version }}" \ + --type "${{ inputs.release_type }}" \ + --channel "${{ inputs.release_channel }}" + + - name: Determine tag and pom version + id: versions + run: | + BASE_VERSION="${{ steps.base_version.outputs.version }}" + CURRENT_VERSION="${{ steps.current_version.outputs.version }}" + if [ "${{ inputs.release_channel }}" == "stable" ]; then + TAG="v${BASE_VERSION}" + POM_VERSION="${BASE_VERSION}" + else + # For preview releases, find the next beta number for this base version + BETA_TAGS=$(git tag -l "v${BASE_VERSION}-beta.*" | sort -V) + if [ -z "$BETA_TAGS" ]; then + BETA_NUM=1 + else + LAST_BETA=$(echo "$BETA_TAGS" | tail -n 1) + LAST_NUM=$(echo "$LAST_BETA" | sed "s/v${BASE_VERSION}-beta.//") + BETA_NUM=$((LAST_NUM + 1)) + fi + TAG="v${BASE_VERSION}-beta.${BETA_NUM}" + POM_VERSION="${BASE_VERSION}-beta.${BETA_NUM}" + fi + + # Check if version actually changes + if [ "$CURRENT_VERSION" != "$POM_VERSION" ]; then + VERSION_CHANGED="true" + else + VERSION_CHANGED="false" + fi + + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "pom_version=$POM_VERSION" >> $GITHUB_OUTPUT + echo "version_changed=$VERSION_CHANGED" >> $GITHUB_OUTPUT + echo "Tag will be: $TAG" + echo "POM version will be: $POM_VERSION" + echo "Version changed: $VERSION_CHANGED" + + - name: Update version (when version changes) + if: steps.versions.outputs.version_changed == 'true' + run: | + python ci/bump_version.py --version "${{ steps.versions.outputs.pom_version }}" + + - name: Configure git identity + run: | + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Create release commit (when version changes) + if: steps.versions.outputs.version_changed == 'true' + run: | + git add -A + git commit -m "chore: bump version to ${{ steps.versions.outputs.pom_version }}" || echo "No changes to commit" + + - name: Create tag + run: | + git tag -a "${{ steps.versions.outputs.tag }}" -m "Release ${{ steps.versions.outputs.tag }}" + + - name: Push changes (if not dry run) + if: ${{ !inputs.dry_run }} + env: + GITHUB_TOKEN: ${{ secrets.LANCE_RELEASE_TOKEN }} + run: | + git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git" + + if [ "${{ steps.versions.outputs.version_changed }}" == "true" ]; then + git push origin main + fi + git push origin "${{ steps.versions.outputs.tag }}" + + - name: Create GitHub Release Draft (if not dry run) + if: ${{ !inputs.dry_run }} + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.versions.outputs.tag }} + name: ${{ steps.versions.outputs.tag }} + generate_release_notes: true + draft: true + prerelease: ${{ inputs.release_channel == 'preview' }} + token: ${{ secrets.LANCE_RELEASE_TOKEN }} + + - name: Summary + run: | + echo "## Release Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- **Release Type:** ${{ inputs.release_type }}" >> $GITHUB_STEP_SUMMARY + echo "- **Release Channel:** ${{ inputs.release_channel }}" >> $GITHUB_STEP_SUMMARY + echo "- **Current Version:** ${{ steps.current_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY + if [ "${{ steps.versions.outputs.version_changed }}" == "true" ]; then + echo "- **New Version:** ${{ steps.versions.outputs.pom_version }}" >> $GITHUB_STEP_SUMMARY + fi + echo "- **Tag:** ${{ steps.versions.outputs.tag }}" >> $GITHUB_STEP_SUMMARY + echo "- **Dry Run:** ${{ inputs.dry_run }}" >> $GITHUB_STEP_SUMMARY + + if [ "${{ inputs.dry_run }}" == "true" ]; then + echo "" >> $GITHUB_STEP_SUMMARY + echo "⚠️ This was a dry run. No changes were pushed." >> $GITHUB_STEP_SUMMARY + else + echo "" >> $GITHUB_STEP_SUMMARY + echo "📝 Draft release created successfully!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Next Steps:" >> $GITHUB_STEP_SUMMARY + echo "1. Review the draft release on the [releases page](https://github.com/${{ github.repository }}/releases)" >> $GITHUB_STEP_SUMMARY + echo "2. Edit the release notes if needed" >> $GITHUB_STEP_SUMMARY + echo "3. Publish the release to trigger automatic publishing to Maven Central" >> $GITHUB_STEP_SUMMARY + fi diff --git a/.gitignore b/.gitignore index cd2d973..44cf224 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,36 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +### Maven ### target/ -!.mvn/wrapper/maven-wrapper.jar -!**/src/main/**/target/ -!**/src/test/**/target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar ### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ +.idea *.iws *.iml *.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ ### Eclipse ### .apt_generated @@ -20,6 +40,9 @@ target/ .settings .springBeans .sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ ### NetBeans ### /nbproject/private/ @@ -27,15 +50,25 @@ target/ /dist/ /nbdist/ /.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ ### VS Code ### .vscode/ +.metals/ ### Mac OS ### .DS_Store ### CodeBuddy ### -.codebuddy/ \ No newline at end of file +.codebuddy/ + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Test data +test-data/ \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..6b04698 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..881a504 --- /dev/null +++ b/Makefile @@ -0,0 +1,72 @@ + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================= +# Build commands +# ============================================================================= + +.PHONY: install +install: + ./mvnw install -DskipTests + +.PHONY: test +test: + ./mvnw test + +.PHONY: build +build: lint install + +.PHONY: package +package: + ./mvnw package -DskipTests + +# ============================================================================= +# Code style +# ============================================================================= + +.PHONY: lint +lint: + ./mvnw checkstyle:check spotless:check + +.PHONY: format +format: + ./mvnw spotless:apply + +# ============================================================================= +# Clean +# ============================================================================= + +.PHONY: clean +clean: + ./mvnw clean + +# ============================================================================= +# Help +# ============================================================================= + +.PHONY: help +help: + @echo "Lance Flink Makefile" + @echo "" + @echo "Build commands:" + @echo " install - Install without tests" + @echo " test - Run tests" + @echo " build - Lint and install" + @echo " package - Package without tests" + @echo "" + @echo "Code style:" + @echo " lint - Check code style (checkstyle + spotless)" + @echo " format - Apply spotless formatting" + @echo "" + @echo "Clean:" + @echo " clean - Clean build artifacts" diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 0000000..834b98b --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ci/bump_version.py b/ci/bump_version.py new file mode 100755 index 0000000..01d4b93 --- /dev/null +++ b/ci/bump_version.py @@ -0,0 +1,138 @@ + +#!/usr/bin/env python3 +""" +Version management script for Lance Flink project. +Uses bump-my-version to handle version bumping across all project components. + +Versioning scheme: + - Stable releases: X.Y.Z (e.g., 0.1.0, 1.0.0) + - Pre-releases: X.Y.Z-