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


##########
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:
   [P1] The RC path scans commit messages, while the merge path reads PR titles 
and bodies. PR #13352 was rebase-merged between v1.3.1-rc1 and rc2: its title 
references #13346 and #13348, but neither resulting commit message contains 
those IDs. With this workflow, the merge job would label both 1.3.2 and this RC 
job would never move them to 1.3.1. Please resolve the PR associated with each 
commit or persist the merge-time issue mapping.



##########
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:
   [P2] This bracket pattern allows bare digits after one #, and the next grep 
extracts every number. For [#1, 2], extract_issues returns both 1 and 2, so 
unrelated issue #2 can be labeled and assigned. Please extract only #N tokens 
from a validated bracket group.



##########
.github/workflows/label-fix-version.yml:
##########
@@ -0,0 +1,85 @@
+#
+# 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.
+#
+
+# Label issues with the release their fix ships in, see
+# dev/ci/label_fix_version.sh for details.
+#
+# - When a PR is merged, its issues get the version of the merge commit,
+#   e.g. main (2.0.0-SNAPSHOT) -> "2.0.0", and unassigned issues are assigned
+#   to the PR author.
+# - The release script bumps to the next SNAPSHOT right after tagging an RC,
+#   so when a later RC is tagged, the issues fixed since the previous RC are
+#   moved to that release, e.g. v1.3.1-rc2 moves them from "1.3.2" to "1.3.1".
+#
+# The merge job uses pull_request_target so that PRs from forks get a token
+# that can write labels. It never checks out PR code, and all PR-controlled
+# values are passed through env to avoid script injection.
+
+name: Label issues with fix version
+
+on:
+  pull_request_target:
+    types: [closed]
+  push:

Review Comment:
   Release-branch RC relabeling depends on this workflow and script being 
present in the tagged commit. Neither current branch-1.3 nor v1.3.1-rc3 
contains them. The PR description notes the required cherry-pick; please link 
the branch-1.3 backport and verify it lands before the next RC tag, otherwise 
this job will not run for that branch.



-- 
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