jerryshao commented on code in PR #13501:
URL: https://github.com/apache/gravitino/pull/13501#discussion_r4092176606


##########
dev/ci/label_fix_version.sh:
##########
@@ -0,0 +1,224 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+# Labels issues with the release their fix ships in. Used by
+# .github/workflows/label-fix-version.yml.
+#
+#   label_fix_version.sh merge  A PR was merged. Label its issues with the
+#                               release of the merge commit and assign
+#                               unassigned issues to the PR author.
+#                               Env: REPO, PR_TITLE, PR_BODY, MERGE_SHA,
+#                               PR_AUTHOR, PR_AUTHOR_TYPE.
+#   label_fix_version.sh rc     A release candidate tag was pushed. Move the
+#                               issues fixed since the previous RC to this
+#                               release. Needs full git history.
+#                               Env: REPO, TAG.
+#
+# Issues are taken from "[#N]" in the PR title or commit subject, e.g.
+# "[#1][#2]" or "[#1, #2]", and from closing keywords in the body, e.g.
+# "Fix: #1". Set DRY_RUN=true to print writes instead of running them.
+
+set -euo pipefail
+
+: "${REPO:?REPO must be set}"
+DRY_RUN=${DRY_RUN:-false}
+
+write() {
+  if [ "$DRY_RUN" = "true" ]; then
+    echo "[dry-run] $*"
+  else
+    "$@"
+  fi
+}
+
+# Prints the issue ids referenced by a subject and a body, one per line.
+extract_issues() {
+  local subject=$1 body=$2
+  {
+    printf '%s\n' "$subject" | grep -oE 
'\[[#0-9,[:space:]]*#[0-9]+[#0-9,[:space:]]*\]' \
+      | grep -oE '[0-9]+' || true
+    printf '%s\n' "$body" \
+      | grep -oiE 
'(^|[^[:alnum:]_])(close[sd]?|fix(e[sd])?|resolve[sd]?):?[[:space:]]+#[0-9]+' \
+      | grep -oE '[0-9]+$' || true
+  } | sort -un
+}
+
+# Reads gradle.properties from stdin and prints the version without -SNAPSHOT.
+parse_version() {
+  sed -n 's/^version[[:space:]]*=[[:space:]]*//p' | tr -d '[:space:]' | sed 
's/-SNAPSHOT$//'
+}
+
+is_version() {
+  printf '%s' "$1" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'
+}
+
+version_lt() {
+  [ "$1" != "$2" ] && [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -1)" = 
"$1" ]
+}
+
+# Creates the version label if missing, following the existing convention.
+ensure_label() {
+  local version=$1
+  if ! gh label list --repo "$REPO" --search "$version" --limit 100 --json 
name --jq '.[].name' \
+      | grep -qxF "$version"; then
+    write gh label create "$version" --repo "$REPO" \
+      --description "Release v$version" --color "$(openssl rand -hex 3)" \
+      || echo "Label $version may already exist."
+  fi
+}
+
+# Prints the release that contains the given merge commit.
+release_of_commit() {
+  local sha=$1 version tag status
+  version=$(gh api "repos/$REPO/contents/gradle.properties?ref=$sha" --jq 
'.content' \
+    | base64 -d | parse_version)
+  if ! is_version "$version"; then
+    echo "Unexpected version '$version' at $sha." >&2
+    return 1
+  fi
+
+  # The release script bumps to the next SNAPSHOT right after tagging an RC,
+  # so a commit is in an earlier release only if a later RC of that release
+  # was cut after it. Check the latest RC of each earlier release on this line.
+  for tag in $(gh api --paginate 
"repos/$REPO/git/matching-refs/tags/v${version%.*}." \
+      --jq '.[].ref | sub("^refs/tags/"; "") | select(test("-rc[0-9]+$"))' \
+      | sort -V | awk -F'-rc' '!($1 in last) { order[++n] = $1 } { last[$1] = 
$0 }
+          END { for (i = 1; i <= n; i++) print last[order[i]] }'); do
+    local tag_version=${tag#v}
+    tag_version=${tag_version%-rc*}
+    version_lt "$tag_version" "$version" || continue
+    status=$(gh api "repos/$REPO/compare/$tag...$sha" --jq '.status')
+    if [ "$status" = "behind" ] || [ "$status" = "identical" ]; then
+      echo "$tag_version"
+      return 0
+    fi
+  done
+  echo "$version"
+}
+
+on_merge() {
+  : "${PR_TITLE:?}" "${MERGE_SHA:?}" "${PR_AUTHOR:?}" "${PR_AUTHOR_TYPE:?}"
+  local issues version issue info is_pr assignee_count assigned
+  issues=$(extract_issues "$PR_TITLE" "${PR_BODY:-}")
+  if [ -z "$issues" ]; then
+    echo "No linked issue found, skipping."
+    return 0
+  fi
+
+  version=$(release_of_commit "$MERGE_SHA")
+  echo "Merge commit $MERGE_SHA ships in $version."
+  ensure_label "$version"
+
+  for issue in $issues; do
+    info=$(gh api "repos/$REPO/issues/$issue" --jq '"\(has("pull_request")) 
\(.assignees | length)"')
+    read -r is_pr assignee_count <<< "$info"
+    if [ "$is_pr" != "false" ]; then
+      echo "#$issue is a pull request, skipping."
+      continue
+    fi
+    write gh issue edit "$issue" --repo "$REPO" --add-label "$version"
+    echo "Labeled issue #$issue with $version."
+
+    if [ "$assignee_count" != "0" ]; then
+      continue
+    fi
+    if [ "$PR_AUTHOR_TYPE" = "Bot" ]; then
+      echo "PR author $PR_AUTHOR is a bot, not assigning #$issue."
+      continue
+    fi
+    if [ "$DRY_RUN" = "true" ]; then
+      echo "[dry-run] assign #$issue to $PR_AUTHOR"
+      continue
+    fi
+    # GitHub silently drops assignees it doesn't accept, so check the result.
+    assigned=$(gh api -X POST "repos/$REPO/issues/$issue/assignees" -f 
"assignees[]=$PR_AUTHOR" \
+      --jq '[.assignees[].login] | index(env.PR_AUTHOR) != null')
+    if [ "$assigned" = "true" ]; then
+      echo "Assigned issue #$issue to $PR_AUTHOR."
+    else
+      echo "Could not assign issue #$issue to $PR_AUTHOR."
+    fi
+  done
+}
+
+# Prints the issues referenced by the commits in the given git log range.
+issues_in_range() {
+  local sha
+  for sha in $(git rev-list "$@"); do
+    extract_issues "$(git log -1 --format=%s "$sha")" "$(git log -1 
--format=%b "$sha")"

Review Comment:
   Fixed: the RC job now resolves each commit in the range to its merged PR via 
`commits/{sha}/pulls` and parses that PR's title and body, the same inputs as 
the merge job; commits without a PR fall back to their message. Verified on 
`v1.3.1-rc2`: #13346 and #13348 from the rebase-merged #13352 are now moved to 
1.3.1.
   
   _🤖 Addressed by [Claude Code](https://claude.com/claude-code)_



##########
dev/ci/label_fix_version.sh:
##########
@@ -0,0 +1,224 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+# Labels issues with the release their fix ships in. Used by
+# .github/workflows/label-fix-version.yml.
+#
+#   label_fix_version.sh merge  A PR was merged. Label its issues with the
+#                               release of the merge commit and assign
+#                               unassigned issues to the PR author.
+#                               Env: REPO, PR_TITLE, PR_BODY, MERGE_SHA,
+#                               PR_AUTHOR, PR_AUTHOR_TYPE.
+#   label_fix_version.sh rc     A release candidate tag was pushed. Move the
+#                               issues fixed since the previous RC to this
+#                               release. Needs full git history.
+#                               Env: REPO, TAG.
+#
+# Issues are taken from "[#N]" in the PR title or commit subject, e.g.
+# "[#1][#2]" or "[#1, #2]", and from closing keywords in the body, e.g.
+# "Fix: #1". Set DRY_RUN=true to print writes instead of running them.
+
+set -euo pipefail
+
+: "${REPO:?REPO must be set}"
+DRY_RUN=${DRY_RUN:-false}
+
+write() {
+  if [ "$DRY_RUN" = "true" ]; then
+    echo "[dry-run] $*"
+  else
+    "$@"
+  fi
+}
+
+# Prints the issue ids referenced by a subject and a body, one per line.
+extract_issues() {
+  local subject=$1 body=$2
+  {
+    printf '%s\n' "$subject" | grep -oE 
'\[[#0-9,[:space:]]*#[0-9]+[#0-9,[:space:]]*\]' \

Review Comment:
   Fixed: a bracket group must now be a list of `#N` tokens (optionally 
comma/space separated), and only `#N` tokens are extracted, so `[#1, 2]` and 
`[docs #42]` yield nothing while `[#1][#2]`, `[#1 ][#2]` and `[#1, #2]` still 
work.
   
   _🤖 Addressed by [Claude Code](https://claude.com/claude-code)_



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to