Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ on:
description: "[Kibana integration only] Source EUI PR number that triggered the run"
required: false
type: string
kibana_nightly:
description: "[Kibana integration only] Whether this is a scheduled nightly run"
default: false
type: boolean
concurrency:
group: ${{ inputs.kibana_nightly && 'kibana-nightly' || format('release-{0}', github.run_id) }}
cancel-in-progress: false
queue: max
Comment on lines +54 to +57

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concurrency also supports queue: max as per (source):

To allow more than one pending job or workflow run to wait in the same concurrency group, use the optional queue property. The queue property accepts the following values:

single (default): At most one job or workflow run can be pending in the concurrency group. When a new job or workflow run is queued, any existing pending job or workflow run in the same group is canceled and replaced.
max: Up to 100 jobs or workflow runs can be pending in the concurrency group. When the queue is full, any additional jobs or workflow runs are canceled.

The reason we're using it is because we have 3 separately dispatched workflows, so we want a FIFO queue and not a single workflow.

?

permissions:
id-token: write # Required for OIDC
contents: read
Expand Down Expand Up @@ -169,14 +177,37 @@ jobs:
PR_TITLE: ${{ inputs.kibana_pr_title }}
PR_BODY: ${{ inputs.kibana_pr_body }}
SOURCE_PR_NUMBER: ${{ inputs.kibana_source_pr_number }}
NIGHTLY: ${{ inputs.kibana_nightly }}
EUI_REF: ${{ inputs.release_ref }}
# language=bash
run: |
set -euo pipefail
dependencies="$(jq -c . .release/published_packages.json)"
eui_version=''
eui_last_release=''

if [[ "$NIGHTLY" == "true" ]]; then
eui_version="$(
jq -r '.[] | select(.name == "@elastic/eui") | .version' \
.release/published_packages.json
)"
if [[ -z "$eui_version" ]]; then
echo "::error::The snapshot did not publish @elastic/eui"
exit 1
fi

last_release="$(git describe --tags --abbrev=0 --match 'v[0-9]*' --exclude '*-*' "$EUI_REF")"
eui_last_release="$last_release"
fi

args=(
-f "dependencies=$dependencies"
-f "pr_title=$PR_TITLE"
-f "pr_body=$PR_BODY"
-f "nightly=$NIGHTLY"
-f "eui_ref=$EUI_REF"
-f "eui_last_release=$eui_last_release"
-f "eui_version=$eui_version"
)
if [[ -n "${SOURCE_PR_NUMBER:-}" ]]; then
args+=( -f "source_pr_number=$SOURCE_PR_NUMBER" )
Expand Down
19 changes: 17 additions & 2 deletions .github/workflows/update_kibana_dependencies.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
name: Update Kibana dependencies

on:
schedule:
# 03:05 UTC, Monday-Friday
# "High load times include the start of every hour. If the load is sufficiently high enough,
# some queued jobs may be dropped. To decrease the chance of delay, schedule your workflow
# to run at a different time of the hour."
# Source: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#schedule
- cron: '5 3 * * 1-5'
pull_request_target:
types: [labeled]
workflow_dispatch:
Expand All @@ -26,7 +33,9 @@ jobs:
trigger_release:
name: Trigger snapshot release
runs-on: ubuntu-latest
if: ${{ github.event_name != 'pull_request_target' || github.event.label.name == 'ci:regression-integration-test-kibana' }}
if: >-
(github.event_name != 'pull_request_target' || github.event.label.name == 'ci:regression-integration-test-kibana') &&
(github.event_name != 'schedule' || github.repository == 'elastic/eui')
permissions:
actions: write
contents: read
Expand All @@ -35,7 +44,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
EVENT_NAME: ${{ github.event_name }}
RELEASE_REF: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || inputs.release_ref }}
RELEASE_REF: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || inputs.release_ref || github.sha }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_URL: ${{ github.event.pull_request.html_url }}
INPUT_PR_TITLE: ${{ inputs.pr_title }}
Expand All @@ -57,11 +66,17 @@ jobs:
"-f" "kibana_pr_body=This PR was created programmatically to run regression integration tests of EUI changes from $PR_URL"
"-f" "kibana_source_pr_number=$PR_NUMBER"
)
elif [[ "$EVENT_NAME" == "schedule" ]]; then
workflow_args+=(
"-f" "kibana_pr_title=[DO NOT MERGE][EUI] Nightly Build"
"-f" "kibana_nightly=true"
)
else
workflow_args+=(
"-f" "kibana_pr_title=$INPUT_PR_TITLE"
"-f" "kibana_pr_body=$INPUT_PR_BODY"
)
fi

# This job has no checkout, so gh cannot infer the repository.
gh workflow run release.yml --repo "$GITHUB_REPOSITORY" "${workflow_args[@]}"
184 changes: 171 additions & 13 deletions .github/workflows/update_kibana_dependencies__open_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ on:
source_pr_number:
description: Source PR number that triggered this workflow
type: number
nightly:
description: Whether this is the scheduled nightly run
type: boolean
default: false
eui_ref:
description: EUI ref used to publish the snapshot
type: string
required: true
eui_last_release:
description: Latest stable EUI release reachable from the snapshot
type: string
eui_version:
description: Published @elastic/eui snapshot version
type: string
concurrency:
group: ${{ inputs.nightly && 'kibana-nightly' || format('open-kibana-pr-{0}', github.run_id) }}
cancel-in-progress: false
queue: max
Comment thread
weronikaolejniczak marked this conversation as resolved.
permissions:
contents: read
id-token: write
Expand All @@ -36,6 +54,12 @@ jobs:
outputs:
pr_url: ${{ steps.open_pr.outputs.pr_url }}
steps:
- name: Checkout EUI snapshot
if: ${{ inputs.nightly }}
uses: actions/checkout@v6
with:
ref: ${{ inputs.eui_ref }}
persist-credentials: false
- name: Fetch GitHub token
id: ephemeral_token
uses: elastic/ci-gh-actions/fetch-github-token@v1.5.3
Expand All @@ -50,6 +74,10 @@ jobs:
PR_TITLE: ${{ inputs.pr_title }}
PR_BODY: ${{ inputs.pr_body }}
PR_DRAFT: ${{ inputs.pr_draft }}
NIGHTLY: ${{ inputs.nightly }}
EUI_REF: ${{ inputs.eui_ref }}
EUI_LAST_RELEASE: ${{ inputs.eui_last_release }}
EUI_VERSION: ${{ inputs.eui_version }}
# language=bash
run: |
set -euo pipefail
Expand All @@ -60,6 +88,61 @@ jobs:
base_repo='elastic/kibana'
head_repo='elastic/eui-kibana'

if [[ "$NIGHTLY" == "true" && ( -z "$EUI_REF" || -z "$EUI_LAST_RELEASE" || -z "$EUI_VERSION" ) ]]; then
echo "::error::Nightly runs require eui_ref, eui_last_release, and eui_version"
exit 1
fi

if [[ "$NIGHTLY" == "true" ]]; then
compare_url="https://github.com/elastic/eui/compare/$EUI_LAST_RELEASE...$EUI_REF"
changelog_entries=''
while IFS= read -r changelog_file; do
changelog_number="$(basename "$changelog_file" .md)"
changelog_url="https://github.com/elastic/eui/blob/$EUI_REF/$changelog_file"
if [[ -n "$changelog_entries" ]]; then
changelog_entries+=$'\n\n'
fi
changelog_entries+="### [#$changelog_number]($changelog_url)"$'\n\n'
changelog_entries+="$(< "$changelog_file")"
done < <(
find packages/eui/changelogs/upcoming -maxdepth 1 -type f \
-name '*.md' ! -name '_template.md' | sort
Comment thread
weronikaolejniczak marked this conversation as resolved.
Outdated
)

PR_BODY="$(
printf '%s\n' \
'This draft PR validates the latest EUI snapshot from `main` in Kibana.' \
'' \
"- **npm snapshot:** [\`@elastic/eui@$EUI_VERSION\`](https://www.npmjs.com/package/@elastic/eui/v/$EUI_VERSION)" \
"- **Changes since $EUI_LAST_RELEASE:** [$EUI_LAST_RELEASE...${EUI_REF:0:12}]($compare_url)" \
"- **EUI commit:** [\`${EUI_REF:0:12}\`](https://github.com/elastic/eui/commit/$EUI_REF)" \
'' \
'<details>' \
'<summary>Upcoming @elastic/eui changelog entries</summary>' \
'' \
"${changelog_entries:-_No upcoming changelog entries._}" \
'' \
'</details>'
)"

# Reuse the open PR for the fixed nightly branch.
existing_pr_url="$(gh api "repos/$base_repo/pulls?state=open&head=elastic:$PR_HEAD" --jq '.[0].html_url // ""')"
if [[ -n "$existing_pr_url" ]]; then
gh pr edit "$existing_pr_url" --title "$PR_TITLE" --body "${PR_BODY:-}"
if [[ "$(gh pr view "$existing_pr_url" --json isDraft --jq .isDraft)" != "true" ]]; then
gh pr ready "$existing_pr_url" --undo
fi

echo "pr_url=$existing_pr_url" >> "$GITHUB_OUTPUT"
{
echo "### Pull request updated"
echo ""
echo "$existing_pr_url"
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
fi

base_repo_id="$(gh api "repos/$base_repo" --jq .node_id)"
head_repo_id="$(gh api "repos/$head_repo" --jq .node_id)"

Expand Down Expand Up @@ -159,6 +242,7 @@ jobs:
needs: [open_pr, post_open_pr]
outputs:
pending: ${{ steps.check_status.outputs.pending }}
buildkite_url: ${{ steps.check_status.outputs.buildkite_url }}
steps:
# Token cannot be reused in this job because it's short-lived
- name: Fetch GitHub token
Expand All @@ -174,12 +258,26 @@ jobs:
PR_URL: ${{ needs.open_pr.outputs.pr_url }}
# language=bash
run: |
status_json="$(gh pr checks "$PR_URL" --required --json name,link,bucket)"
all_num="$(echo $status_json | jq length)"
pending_json="$(echo $status_json | jq 'map(select(.bucket == "pending"))')"
pending_num="$(echo $pending_json | jq length)"
fail_json="$(echo $status_json | jq 'map(select(.bucket | test("fail|cancel")))')"
fail_num="$(echo $fail_json | jq length)"
all_status_json="$(gh pr checks "$PR_URL" --json name,link,bucket || true)"
if jq -e 'type == "array"' > /dev/null <<< "$all_status_json"; then
buildkite_url="$(
jq -r '[.[] | select((.link // "") | contains("buildkite.com"))][0].link // empty' \
<<< "$all_status_json"
)"
echo "buildkite_url=$buildkite_url" >> "$GITHUB_OUTPUT"
else
echo "::warning::Could not retrieve the Buildkite URL"
fi

status_json="$(gh pr checks "$PR_URL" --required --json name,link,bucket || true)"
if ! jq -e 'type == "array" and length > 0' > /dev/null <<< "$status_json"; then
echo "::error::No required CI checks were returned"
exit 1
fi

all_num="$(jq length <<< "$status_json")"
pending_num="$(jq '[.[] | select(.bucket == "pending")] | length' <<< "$status_json")"
fail_num="$(jq '[.[] | select(.bucket | test("fail|cancel"))] | length' <<< "$status_json")"

if [[ "$fail_num" -gt 0 ]]; then
echo "Some CI checks failed. Please check the logs for details."
Expand All @@ -202,6 +300,8 @@ jobs:
environment: delayed-2h
needs: [open_pr, check_ci_status_1]
if: ${{ needs.check_ci_status_1.outputs.pending == 'true' }}
outputs:
buildkite_url: ${{ steps.check_status.outputs.buildkite_url }}
steps:
# Token cannot be reused in this job because it's short-lived
- name: Fetch GitHub token
Expand All @@ -211,17 +311,32 @@ jobs:
vault-instance: ci-prod
vault-role: token-policy-6becee3e5a43
- name: Check status
id: check_status
env:
GH_TOKEN: ${{ steps.ephemeral_token.outputs.token }}
PR_URL: ${{ needs.open_pr.outputs.pr_url }}
# language=bash
run: |
status_json="$(gh pr checks "$PR_URL" --required --json name,link,bucket)"
all_num="$(echo $status_json | jq length)"
pending_json="$(echo $status_json | jq 'map(select(.bucket == "pending"))')"
pending_num="$(echo $pending_json | jq length)"
fail_json="$(echo $status_json | jq 'map(select(.bucket | test("fail|cancel")))')"
fail_num="$(echo $fail_json | jq length)"
all_status_json="$(gh pr checks "$PR_URL" --json name,link,bucket || true)"
if jq -e 'type == "array"' > /dev/null <<< "$all_status_json"; then
buildkite_url="$(
jq -r '[.[] | select((.link // "") | contains("buildkite.com"))][0].link // empty' \
<<< "$all_status_json"
)"
echo "buildkite_url=$buildkite_url" >> "$GITHUB_OUTPUT"
else
echo "::warning::Could not retrieve the Buildkite URL"
fi

status_json="$(gh pr checks "$PR_URL" --required --json name,link,bucket || true)"
if ! jq -e 'type == "array" and length > 0' > /dev/null <<< "$status_json"; then
echo "::error::No required CI checks were returned"
exit 1
fi

all_num="$(jq length <<< "$status_json")"
pending_num="$(jq '[.[] | select(.bucket == "pending")] | length' <<< "$status_json")"
fail_num="$(jq '[.[] | select(.bucket | test("fail|cancel"))] | length' <<< "$status_json")"

if [[ "$fail_num" -gt 0 ]]; then
echo "Some CI checks failed. Please check the logs for details."
Expand All @@ -243,14 +358,15 @@ jobs:
needs: [open_pr, check_ci_status_1, check_ci_status_2]
if: |
always() &&
inputs.source_pr_number &&
(inputs.source_pr_number || inputs.nightly) &&
(
(needs.check_ci_status_1.result == 'success' && needs.check_ci_status_2.result == 'skipped') ||
(needs.check_ci_status_1.result == 'failure' && needs.check_ci_status_2.result == 'skipped') ||
(needs.check_ci_status_2.result != 'skipped')
)
steps:
- name: Checkout repository
if: ${{ inputs.source_pr_number }}
uses: actions/checkout@v6
- name: Compose comment body
id: compose_comment_body
Expand All @@ -259,6 +375,10 @@ jobs:
PR_HEAD: ${{ inputs.pr_head }}
CHECK_1_RESULT: ${{ needs.check_ci_status_1.result }}
CHECK_2_RESULT: ${{ needs.check_ci_status_2.result }}
NIGHTLY: ${{ inputs.nightly }}
EUI_REF: ${{ inputs.eui_ref }}
EUI_LAST_RELEASE: ${{ inputs.eui_last_release }}
BUILDKITE_URL: ${{ needs.check_ci_status_2.result != 'skipped' && needs.check_ci_status_2.outputs.buildkite_url || needs.check_ci_status_1.outputs.buildkite_url }}
# language=bash
run: |
if [[ "$CHECK_2_RESULT" == "skipped" && "$CHECK_1_RESULT" != "success" ]] || [[ "$CHECK_2_RESULT" != "success" && "$CHECK_2_RESULT" != "skipped" ]]; then
Expand All @@ -283,11 +403,49 @@ jobs:
fi
echo 'COMMENT_DELIMITER'
} >> "$GITHUB_OUTPUT"

if [[ "$NIGHTLY" == "true" ]]; then
if [[ -n "$details" ]]; then
slack_status=':red_circle: EUI nightly did not pass Kibana CI'
else
slack_status=':large_green_circle: EUI nightly passed Kibana CI'
fi

compare_url="https://github.com/elastic/eui/compare/$EUI_LAST_RELEASE...$EUI_REF"
slack_text="$slack_status"$'\n'"<$KIBANA_PR_URL|Kibana PR>"
if [[ -n "$BUILDKITE_URL" ]]; then
slack_text+=" · <$BUILDKITE_URL|Buildkite>"
else
slack_text+=' · Buildkite link unavailable'
fi
slack_text+=" · <$compare_url|EUI main diff>"

{
echo 'slack_text<<SLACK_DELIMITER'
echo "$slack_text"
echo 'SLACK_DELIMITER'
} >> "$GITHUB_OUTPUT"
fi
- name: Add a comment
if: ${{ inputs.source_pr_number }}
uses: ./.github/actions/pr_bot_comment
with:
gh_token: ${{ github.token }}
pr_number: ${{ inputs.source_pr_number }}
marker: 'kibana-regression-integration-test'
comment_author: 'github-actions[bot]'
comment_body: ${{ steps.compose_comment_body.outputs.comment_body }}
- name: Notify Slack
if: ${{ inputs.nightly }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.KIBANA_NIGHTLY_SLACK_WEBHOOK }}
SLACK_TEXT: ${{ steps.compose_comment_body.outputs.slack_text }}
# language=bash
run: |
set -euo pipefail
if [[ -z "${SLACK_WEBHOOK_URL:-}" ]]; then
echo "::error::KIBANA_NIGHTLY_SLACK_WEBHOOK is not set"
exit 1
fi
payload="$(jq -n --arg text "$SLACK_TEXT" '{ text: $text }')"
curl -fsSL -X POST -H 'Content-type: application/json' --data "$payload" "$SLACK_WEBHOOK_URL"
Loading