CI: Auto Releases in prod

This commit is contained in:
Max Kainov 2024-08-16 11:11:11 +02:00
parent ee51891f50
commit 5ff4d990e1
4 changed files with 54 additions and 57 deletions

View File

@ -19,13 +19,11 @@ on:
jobs:
AutoReleaseInfo:
runs-on: [self-hosted, style-checker-aarch64]
runs-on: [self-hosted, release-maker]
outputs:
data: ${{ steps.info.outputs.AUTO_RELEASE_PARAMS }}
dry_run: ${{ steps.info.outputs.DRY_RUN }}
steps:
- name: Debug Info
uses: ./.github/actions/debug
- name: Set envs
run: |
cat >> "$GITHUB_ENV" << 'EOF'
@ -36,6 +34,10 @@ jobs:
echo "DRY_RUN=true" >> "$GITHUB_ENV"
- name: Check out repository code
uses: ClickHouse/checkout@v1
with:
fetch-depth: 0 # full history needed
- name: Debug Info
uses: ./.github/actions/debug
- name: Prepare Info
id: info
run: |
@ -46,12 +48,7 @@ jobs:
echo "::endgroup::"
{
echo 'AUTO_RELEASE_PARAMS<<EOF'
cat /tmp/autorelease_info.json
echo 'EOF'
} >> "$GITHUB_ENV"
{
echo 'AUTO_RELEASE_PARAMS<<EOF'
cat /tmp/autorelease_info.json
cat /tmp/autorelease_params.json
echo 'EOF'
} >> "$GITHUB_OUTPUT"
echo "DRY_RUN=true" >> "$GITHUB_OUTPUT"
@ -62,48 +59,29 @@ jobs:
- name: Clean up
uses: ./.github/actions/clean
Release_0:
Releases:
needs: AutoReleaseInfo
name: Release ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[0].release_branch }}
if: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[0] && fromJson(needs.AutoReleaseInfo.outputs.data).releases[0].ready }}
strategy:
matrix:
release_params: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases }}
max-parallel: 1
name: Release ${{ matrix.release_params.release_branch }}
uses: ./.github/workflows/create_release.yml
with:
ref: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[0].commit_sha }}
ref: ${{ matrix.release_params.commit_sha }}
type: patch
dry-run: ${{ needs.AutoReleaseInfo.outputs.dry_run }}
#
# Release_1:
# needs: [AutoReleaseInfo, Release_0]
# name: Release ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[1].release_branch }}
# if: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[1] && fromJson(needs.AutoReleaseInfo.outputs.data).releases[1].ready }}
# uses: ./.github/workflows/create_release.yml
# with:
# ref: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[1].commit_sha }}
# type: patch
# dry-run: ${{ env.DRY_RUN }}
#
# Release_2:
# needs: [AutoReleaseInfo, Release_1]
# name: Release ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[2].release_branch }}
# if: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[0] && fromJson(needs.AutoReleaseInfo.outputs.data).releases[2].ready }}
# uses: ./.github/workflow/create_release.yml
# with:
# ref: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[0].commit_sha }}
# type: patch
# dry-run: ${{ env.DRY_RUN }}
#
# Release_3:
# needs: [AutoReleaseInfo, Release_2]
# name: Release ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[3].release_branch }}
# if: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[3] && fromJson(needs.AutoReleaseInfo.outputs.data).releases[3].ready }}
# uses: ./.github/workflow/create_release.yml
# with:
# ref: ${{ fromJson(needs.AutoReleaseInfo.outputs.data).releases[3].commit_sha }}
# type: patch
# dry-run: ${{ env.DRY_RUN }}
dry-run: ${{ fromJson(needs.AutoReleaseInfo.outputs.dry_run) }}
secrets:
ROBOT_CLICKHOUSE_COMMIT_TOKEN: ${{ secrets.ROBOT_CLICKHOUSE_COMMIT_TOKEN }}
# - name: Post Slack Message
# if: ${{ !cancelled() }}
# run: |
# cd "$GITHUB_WORKSPACE/tests/ci"
# python3 auto_release.py --post-auto-release-complete --wf-status ${{ job.status }}
PostSlackMessage:
needs: [AutoReleaseInfo]
runs-on: [self-hosted, release-maker]
if: ${{ !cancelled() }}
steps:
- name: Check out repository code
uses: ClickHouse/checkout@v1
- name: Post
run: |
cd "$GITHUB_WORKSPACE/tests/ci"
python3 auto_release.py --post-auto-release-complete --wf-status ${{ job.status }}

View File

@ -47,6 +47,8 @@ concurrency:
required: false
default: false
type: boolean
secrets:
ROBOT_CLICKHOUSE_COMMIT_TOKEN:
jobs:
CreateRelease:

View File

@ -1,4 +1,5 @@
import argparse
import copy
import dataclasses
import json
import os
@ -46,6 +47,7 @@ def parse_args():
MAX_NUMBER_OF_COMMITS_TO_CONSIDER_FOR_RELEASE = 5
AUTORELEASE_INFO_FILE = "/tmp/autorelease_info.json"
AUTORELEASE_MATRIX_PARAMS = "/tmp/autorelease_params.json"
@dataclasses.dataclass
@ -74,6 +76,12 @@ class AutoReleaseInfo:
with open(AUTORELEASE_INFO_FILE, "w", encoding="utf-8") as f:
print(json.dumps(dataclasses.asdict(self), indent=2), file=f)
# dump file for GH action matrix that is similar to the file above but with dropped not ready release branches
params = copy.deepcopy(self)
params.releases = [release for release in params.releases if release.ready]
with open(AUTORELEASE_MATRIX_PARAMS, "w", encoding="utf-8") as f:
print(json.dumps(params, indent=2), file=f)
@staticmethod
def from_file() -> "AutoReleaseInfo":
with open(AUTORELEASE_INFO_FILE, "r", encoding="utf-8") as json_file:
@ -136,6 +144,7 @@ def _prepare(token):
commit_ci_status = CI.GH.get_commit_status_by_name(
token=token,
commit_sha=commit,
# handle old name for old releases
status_name=(CI.JobNames.BUILD_CHECK, "ClickHouse build check"),
)
commit_sha = commit

View File

@ -102,21 +102,29 @@ class GH:
assert len(commit_sha) == 40
assert Utils.is_hex(commit_sha)
assert not Utils.is_hex(token)
url = f"https://api.github.com/repos/{Envs.GITHUB_REPOSITORY}/commits/{commit_sha}/statuses?per_page={200}"
url = f"https://api.github.com/repos/{Envs.GITHUB_REPOSITORY}/commits/{commit_sha}/statuses"
headers = {
"Authorization": f"token {token}",
"Accept": "application/vnd.github.v3+json",
}
response = requests.get(url, headers=headers, timeout=5)
if isinstance(status_name, str):
status_name = (status_name,)
if response.status_code == 200:
assert "next" not in response.links, "Response truncated"
statuses = response.json()
for status in statuses:
if status["context"] in status_name:
return status["state"] # type: ignore
while url:
response = requests.get(url, headers=headers, timeout=5)
if response.status_code == 200:
statuses = response.json()
for status in statuses:
if status["context"] in status_name:
return status["state"]
# Check if there is a next page
url = response.links.get("next", {}).get("url")
else:
break
return ""
@staticmethod