mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 16:10:43 +00:00
271 lines
12 KiB
YAML
271 lines
12 KiB
YAML
name: Auto Assign Metadata
|
|
|
|
on:
|
|
issues:
|
|
types: [opened]
|
|
# pull_request_target runs with base-repo secrets for fork PRs — safe as long
|
|
# as no actions/checkout step is added without pinning ref to the base branch.
|
|
pull_request_target:
|
|
types: [opened, ready_for_review]
|
|
|
|
permissions: {}
|
|
|
|
env:
|
|
PROJECT_NUMBER: "19"
|
|
|
|
jobs:
|
|
auto-assign:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
# ── Classify creator: team | internal | stranger ──
|
|
- name: Classify creator
|
|
id: classify
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
ORG: ${{ github.repository_owner }}
|
|
CREATOR: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.user.login || github.event.issue.user.login }}
|
|
run: |
|
|
ALLOWLIST=" bjp232004 hengfeiyang prabhatsharma uddhavdave oasisk haohuaijin Subhra264 Loaki07 007harshmahajan chaitanya-sistla ktx-kirtan omkarK06 ktx-vaidehi ktx-abhay neha00290 ktx-akshay ktx-sadhna nikhilsaikethe YashodhanJoshi1 ktx-riya mmosarafO2 Shrinath-O2 ktx-mihir vamsikarthikr pr1sm8 "
|
|
CREATOR_LOWER=$(echo "$CREATOR" | tr '[:upper:]' '[:lower:]')
|
|
ALLOWLIST_LOWER=$(echo "$ALLOWLIST" | tr '[:upper:]' '[:lower:]')
|
|
if echo "$ALLOWLIST_LOWER" | grep -q " $CREATOR_LOWER "; then
|
|
echo "category=team" >> "$GITHUB_OUTPUT"
|
|
echo "Creator $CREATOR is on the engineering team"
|
|
elif gh api "orgs/$ORG/members/$CREATOR" --silent 2>/dev/null; then
|
|
echo "category=internal" >> "$GITHUB_OUTPUT"
|
|
echo "Creator $CREATOR is an internal member (not engineering team) — skipping"
|
|
else
|
|
echo "category=stranger" >> "$GITHUB_OUTPUT"
|
|
echo "Creator $CREATOR is an external contributor"
|
|
fi
|
|
|
|
# ── PR: assign creator ──
|
|
- name: Assign PR creator
|
|
if: github.event_name == 'pull_request_target' && steps.classify.outputs.category == 'team'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
NUMBER: ${{ github.event.pull_request.number }}
|
|
CREATOR: ${{ github.event.pull_request.user.login }}
|
|
run: |
|
|
gh pr edit "$NUMBER" --add-assignee "$CREATOR" \
|
|
&& echo "Assigned $CREATOR to PR #$NUMBER" \
|
|
|| echo "::warning::Could not assign $CREATOR to PR #$NUMBER"
|
|
|
|
# ── PR: add lowest open milestone (skip drafts) ──
|
|
- name: Add milestone to PR
|
|
if: github.event_name == 'pull_request_target' && steps.classify.outputs.category == 'team' && github.event.pull_request.draft == false && github.event.pull_request.base.ref == 'main'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
NUMBER: ${{ github.event.pull_request.number }}
|
|
run: |
|
|
CURRENT=$(gh api "repos/$GH_REPO/pulls/$NUMBER" --jq '.milestone.title // empty')
|
|
if [ -n "$CURRENT" ]; then
|
|
echo "Milestone already set to '$CURRENT' — skipping"
|
|
exit 0
|
|
fi
|
|
|
|
MILESTONE=$(gh api "repos/$GH_REPO/milestones?state=open&per_page=100" --jq '
|
|
[.[] | select(.title != "Backlog")] |
|
|
map({
|
|
title: .title,
|
|
due_ts: (if .due_on then (.due_on | fromdateiso8601) else null end),
|
|
sort_key: ([.title | scan("[0-9]+")] | map(tonumber))
|
|
}) |
|
|
map(select(.sort_key | length > 0)) |
|
|
sort_by(.sort_key) |
|
|
if length == 0 then empty
|
|
elif (.[0].due_ts != null and .[0].due_ts < now) then (.[1].title // .[0].title)
|
|
else .[0].title
|
|
end')
|
|
|
|
if [ -n "$MILESTONE" ]; then
|
|
gh pr edit "$NUMBER" -m "$MILESTONE" \
|
|
&& echo "Set milestone: $MILESTONE" \
|
|
|| echo "::warning::Could not set milestone $MILESTONE"
|
|
else
|
|
echo "::warning::No open milestones found"
|
|
fi
|
|
|
|
# ── PR: add to project ──
|
|
- name: Add PR to project
|
|
if: github.event_name == 'pull_request_target' && steps.classify.outputs.category == 'team'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
NODE_ID: ${{ github.event.pull_request.node_id }}
|
|
ORG: ${{ github.repository_owner }}
|
|
run: |
|
|
PROJECT_ID=$(gh api graphql \
|
|
-f query='query($org:String!,$num:Int!){organization(login:$org){projectV2(number:$num){id}}}' \
|
|
-F org="$ORG" -F num="$PROJECT_NUMBER" \
|
|
--jq '.data.organization.projectV2.id')
|
|
|
|
[ -n "$PROJECT_ID" ] || { echo "::warning::Project not found — check PROJECT_NUMBER and token scope"; exit 0; }
|
|
|
|
gh api graphql \
|
|
-f query='mutation($project:ID!,$content:ID!){addProjectV2ItemById(input:{projectId:$project,contentId:$content}){item{id}}}' \
|
|
-f project="$PROJECT_ID" \
|
|
-f content="$NODE_ID" \
|
|
&& echo "Added PR to project" \
|
|
|| echo "::warning::Could not add PR to project"
|
|
|
|
# ── Issue: assign creator if unassigned ──
|
|
- name: Assign issue creator
|
|
if: github.event_name == 'issues' && steps.classify.outputs.category == 'team'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
NUMBER: ${{ github.event.issue.number }}
|
|
CREATOR: ${{ github.event.issue.user.login }}
|
|
run: |
|
|
ASSIGNEE_COUNT=$(gh api "repos/$GH_REPO/issues/$NUMBER" --jq '.assignees | length')
|
|
if [ "$ASSIGNEE_COUNT" -eq 0 ]; then
|
|
gh issue edit "$NUMBER" --add-assignee "$CREATOR" \
|
|
&& echo "Assigned $CREATOR to issue #$NUMBER" \
|
|
|| echo "::warning::Could not assign $CREATOR to issue #$NUMBER"
|
|
else
|
|
echo "Issue already has assignees — skipping"
|
|
fi
|
|
|
|
# ── Issue: add lowest open milestone ──
|
|
- name: Add milestone to issue
|
|
if: github.event_name == 'issues' && steps.classify.outputs.category == 'team'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
NUMBER: ${{ github.event.issue.number }}
|
|
run: |
|
|
CURRENT=$(gh api "repos/$GH_REPO/issues/$NUMBER" --jq '.milestone.title // empty')
|
|
if [ -n "$CURRENT" ]; then
|
|
echo "Milestone already set to '$CURRENT' — skipping"
|
|
exit 0
|
|
fi
|
|
|
|
MILESTONE=$(gh api "repos/$GH_REPO/milestones?state=open&per_page=100" --jq '
|
|
[.[] | select(.title != "Backlog")] |
|
|
map({
|
|
title: .title,
|
|
due_ts: (if .due_on then (.due_on | fromdateiso8601) else null end),
|
|
sort_key: ([.title | scan("[0-9]+")] | map(tonumber))
|
|
}) |
|
|
map(select(.sort_key | length > 0)) |
|
|
sort_by(.sort_key) |
|
|
if length == 0 then empty
|
|
elif (.[0].due_ts != null and .[0].due_ts < now) then (.[1].title // .[0].title)
|
|
else .[0].title
|
|
end')
|
|
|
|
if [ -n "$MILESTONE" ]; then
|
|
gh issue edit "$NUMBER" -m "$MILESTONE" \
|
|
&& echo "Set milestone: $MILESTONE" \
|
|
|| echo "::warning::Could not set milestone $MILESTONE"
|
|
else
|
|
echo "::warning::No open milestones found"
|
|
fi
|
|
|
|
# ── Issue: add to project ──
|
|
- name: Add issue to project
|
|
id: add_issue_to_project
|
|
if: github.event_name == 'issues' && steps.classify.outputs.category == 'team'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
NODE_ID: ${{ github.event.issue.node_id }}
|
|
ORG: ${{ github.repository_owner }}
|
|
run: |
|
|
PROJECT_ID=$(gh api graphql \
|
|
-f query='query($org:String!,$num:Int!){organization(login:$org){projectV2(number:$num){id}}}' \
|
|
-F org="$ORG" -F num="$PROJECT_NUMBER" \
|
|
--jq '.data.organization.projectV2.id')
|
|
|
|
[ -n "$PROJECT_ID" ] || { echo "::warning::Project not found — check PROJECT_NUMBER and token scope"; exit 0; }
|
|
|
|
ITEM_ID=$(gh api graphql \
|
|
-f query='mutation($project:ID!,$content:ID!){addProjectV2ItemById(input:{projectId:$project,contentId:$content}){item{id}}}' \
|
|
-f project="$PROJECT_ID" \
|
|
-f content="$NODE_ID" \
|
|
--jq '.data.addProjectV2ItemById.item.id')
|
|
|
|
if [ -n "$ITEM_ID" ]; then
|
|
echo "Added issue to project (item: $ITEM_ID)"
|
|
echo "item_id=$ITEM_ID" >> "$GITHUB_OUTPUT"
|
|
echo "project_id=$PROJECT_ID" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "::warning::Could not add issue to project"
|
|
fi
|
|
|
|
# ── Issue: set start date ──
|
|
- name: Set start date on issue
|
|
if: github.event_name == 'issues' && steps.classify.outputs.category == 'team' && steps.add_issue_to_project.outputs.item_id != ''
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
ORG: ${{ github.repository_owner }}
|
|
ITEM_ID: ${{ steps.add_issue_to_project.outputs.item_id }}
|
|
PROJECT_ID: ${{ steps.add_issue_to_project.outputs.project_id }}
|
|
run: |
|
|
TODAY=$(date -u +%Y-%m-%d)
|
|
|
|
FIELD_ID=$(gh api graphql \
|
|
-f query='query($project:ID!){node(id:$project){... on ProjectV2{fields(first:30){nodes{... on ProjectV2Field{id name}}}}}}' \
|
|
-f project="$PROJECT_ID" \
|
|
--jq '[.data.node.fields.nodes[] | select(.name | ascii_downcase == "start date")] | .[0].id // empty')
|
|
|
|
[ -n "$FIELD_ID" ] || { echo "::warning::Start date field not found in project"; exit 0; }
|
|
|
|
MUTATION_OUT=$(gh api graphql \
|
|
-f query='mutation($project:ID!,$item:ID!,$field:ID!,$date:Date!){updateProjectV2ItemFieldValue(input:{projectId:$project,itemId:$item,fieldId:$field,value:{date:$date}}){projectV2Item{id}}}' \
|
|
-f project="$PROJECT_ID" \
|
|
-f item="$ITEM_ID" \
|
|
-f field="$FIELD_ID" \
|
|
-f date="$TODAY" 2>&1) \
|
|
&& echo "Set start date to $TODAY" \
|
|
|| echo "::warning::Could not set start date: $MUTATION_OUT"
|
|
|
|
# ── Stranger: assign issue to Shrinath + Manas ──
|
|
- name: Assign stranger issue
|
|
if: github.event_name == 'issues' && steps.classify.outputs.category == 'stranger'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
NUMBER: ${{ github.event.issue.number }}
|
|
run: |
|
|
gh issue edit "$NUMBER" --add-assignee "simranquirky" \
|
|
&& echo "Assigned simranquirky to stranger issue #$NUMBER" \
|
|
|| echo "::warning::Could not assign to stranger issue #$NUMBER"
|
|
|
|
# ── Stranger: assign PR to Ashish + label as community (label skips bots) ──
|
|
- name: Assign and label stranger PR
|
|
if: github.event_name == 'pull_request_target' && steps.classify.outputs.category == 'stranger'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
NUMBER: ${{ github.event.pull_request.number }}
|
|
USER_TYPE: ${{ github.event.pull_request.user.type }}
|
|
run: |
|
|
gh pr edit "$NUMBER" --add-assignee "oasisk" \
|
|
&& echo "Assigned oasisk to stranger PR #$NUMBER" \
|
|
|| echo "::warning::Could not assign to stranger PR #$NUMBER"
|
|
if [ "$USER_TYPE" != "Bot" ]; then
|
|
gh pr edit "$NUMBER" --add-label "community" \
|
|
&& echo "Labeled stranger PR #$NUMBER as community" \
|
|
|| echo "::warning::Could not label stranger PR #$NUMBER"
|
|
fi
|
|
|
|
# ── Dependabot: label ready-for-ci to unlock gated CI, approve any held runs ──
|
|
- name: Enable CI for dependabot PR
|
|
if: github.event_name == 'pull_request_target' && github.event.pull_request.user.login == 'dependabot[bot]'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.ORG_ADMIN_TOKEN }}
|
|
GH_REPO: ${{ github.repository }}
|
|
NUMBER: ${{ github.event.pull_request.number }}
|
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
run: |
|
|
gh pr edit "$NUMBER" --add-label "ready-for-ci" \
|
|
&& echo "Labeled dependabot PR #$NUMBER with ready-for-ci" \
|
|
|| echo "::warning::Could not label dependabot PR #$NUMBER"
|
|
for id in $(gh api "repos/$GH_REPO/actions/runs?head_sha=$HEAD_SHA&status=action_required" --jq '.workflow_runs[].id'); do
|
|
gh api -X POST "repos/$GH_REPO/actions/runs/$id/approve" \
|
|
&& echo "Approved held run $id" \
|
|
|| echo "::warning::Could not approve run $id"
|
|
done
|