Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor changesets release preview workflow #13094

Merged
merged 14 commits into from
May 8, 2024
5 changes: 5 additions & 0 deletions .changeset/many-comics-begin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

Refactor changesets release preview workflow #internal
67 changes: 67 additions & 0 deletions .github/workflows/changesets-preview-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#
# This action creates or updates a Release Preview PR that shows which changes are going to be part of the next release.
#

name: Release Preview - Changeset

on:
push:
branches:
- develop

jobs:
changesets-release-preview:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2

- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: change
with:
token: ${{ secrets.GITHUB_TOKEN }}
filters: |
core-changeset:
- '.changeset/**'

- name: Setup pnpm
uses: pnpm/action-setup@a3252b78c470c02df07e9d59298aecedc3ccdd6d # v3.0.0
if: steps.change.outputs.core-changeset == 'true'
with:
version: ^8.0.0

- name: Setup node
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
if: steps.change.outputs.core-changeset == 'true'
with:
node-version: 20
cache: pnpm
cache-dependency-path: ./pnpm-lock.yaml

- name: Generate new changelog
if: steps.change.outputs.core-changeset == 'true'
id: changelog
run: pnpm install && ./tools/ci/format_changelog
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Create release preview PR
if: steps.change.outputs.core-changeset == 'true'
uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
with:
git-token: ${{ secrets.GITHUB_TOKEN }}
add-paths: |
.changeset/**
CHANGELOG.md
commit-message: "changeset: release preview"
committer: app-token-issuer-releng[bot] <app-token-issuer-releng[bot]@users.noreply.github.com>
branch: changesets/release-preview
title: "[DO NOT MERGE] Changeset Release Preview - v${{ steps.changelog.outputs.version }}"
body: ${{ steps.changelog.outputs.pr_body }}
draft: true
labels: |
release-preview
do-not-merge
74 changes: 0 additions & 74 deletions .github/workflows/cicd-changesets.yml

This file was deleted.

162 changes: 162 additions & 0 deletions tools/ci/format_changelog
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/usr/bin/env bash

chainchad marked this conversation as resolved.
Show resolved Hide resolved
create_changesets_json() {
echo "[[]]" > changesets.json
}

create_tags_json() {
json="{}"
for tag in "${tags_list[@]}"; do
tag=${tag:1}
json=$(jq --arg k "$tag" '.[$k] = []' <<< "$json")
done
echo "$json" > tags.json
}

append_changeset_content() {
if [[ $1 != "" ]]; then
jq --argjson idx "$changesets_index" --arg str "$1" \
'.[$idx] += [$str]' changesets.json > tmp.json && mv tmp.json changesets.json
fi
}

append_changelog_content() {
for tag in "${tags_list[@]}"; do
tag=${tag:1}
array_length=$(jq -r --arg key "$tag" '.[$key] | length' tags.json)
if [[ $array_length -eq 0 ]]; then
continue
fi
changesets=$(jq -r --arg key "$tag" '.[$key] | join("\n\n")' tags.json)
read -d '' changelog_content <<EOF
${changelog_content}

## ${tag}

${changesets}
EOF
done
}

set_pr_body() {
# GitHub Issues/PRs messages have a max size limit on the message body payload.
# This is the error: `body is too long (maximum is 65536 characters)`.
max_pr_desc_char_length=65000
read -d '' pr_header <<EOF
This PR is a preview of the changes that will be included in the next release. Please do not merge this PR.
---
EOF
if [[ ${#changelog_content} -gt $max_pr_desc_char_length ]]; then
read -d '' pr_body <<EOF
${pr_header}
The changelog content is too long for the PR description. Please view the full changelog in the [CHANGELOG.md](https://github.com/smartcontractkit/chainlink/blob/changesets/release-preview/CHANGELOG.md)
EOF
else
read -d '' pr_body <<EOF
${pr_header}
${changelog_content}
EOF
fi
# for multi-line output
echo "pr_body<<EOF" >> $GITHUB_OUTPUT
echo "${pr_body}" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
}

set_new_changelog_content() {
read -d '' new_changelog <<EOF
${changelog_content}
${current_changelog}
EOF

echo "$new_changelog" > CHANGELOG.md
}

# checks for tags in each changeset entry and append to tags.json
match_tags() {
changesets_with_index=$(jq -r 'to_entries | .[] | "\(.key) \(.value | join(" "))"' changesets.json)

echo "$changesets_with_index" | while IFS= read -r line; do
index="${line%% *}"
changeset_content="${line#* }"
changeset_formatted=$(jq -r --argjson idx "$index" '.[$idx] | join("\n")' changesets.json)
found_tag=""
for tag in "${tags_list[@]}"; do
if [[ "$changeset_content" =~ $tag ]]; then
found_tag=${tag:1}
jq --arg key "$found_tag" --arg val "$changeset_formatted" \
'.[$key] += [$val]' tags.json > tmp.json && mv tmp.json tags.json
fi
done
if [[ $found_tag == "" ]] && [[ ! -z $changeset_content ]]; then
found_tag="untagged"
jq --arg key "$found_tag" --arg val "$changeset_formatted" \
'.[$key] += [$val]' tags.json > tmp.json && mv tmp.json tags.json
fi
done
}

cleanup() {
rm -f CHANGELOG.md.tmp
rm -f changesets.json
rm -f tags.json
}

### SCRIPT STARTS HERE ###
cp CHANGELOG.md CHANGELOG.md.tmp
tail -n +2 CHANGELOG.md > CHANGELOG.md.tmp
momentmaker marked this conversation as resolved.
Show resolved Hide resolved

pnpm changeset version

version=$(jq -r '.version' package.json)
echo "version=$version" >> $GITHUB_OUTPUT

read -d '' changelog_content <<EOF
# Changelog Chainlink Core

## ${version} - PREVIEW

EOF

current_changelog=$(cat CHANGELOG.md.tmp)
is_current_version=false
checking_current_changeset=false
changesets_index=0
tags_list=( "#nops" "#added" "#changed" "#removed" "#updated" "#deprecation_notice" "#breaking_change" "#db_update" "#wip" "#bugfix" "#internal" "#untagged")

create_changesets_json
create_tags_json

while IFS= read -r line; do
# break when hits the next version
if [[ $line == "## "* ]] && [[ $is_current_version = true ]]; then
break
fi

# look for the latest version
if [[ $line == "## "* ]]; then
is_current_version=true
fi

if [[ $is_current_version = true ]]; then
# saving each changeset to changeset.json
# check for start of changeset entry as it could be multi-lined entry
if [[ $line == "- ["* ]] && [[ $checking_current_changeset = true ]]; then
checking_current_changeset=false
changesets_index=$((changesets_index+1))
append_changeset_content "$line"
elif [[ $line == "- ["* ]] && [[ $checking_current_changeset = false ]]; then
checking_current_changeset=true
changesets_index=$((changesets_index+1))
append_changeset_content "$line"
momentmaker marked this conversation as resolved.
Show resolved Hide resolved
elif [[ $line != "##"* ]]; then
append_changeset_content "$line"
fi
fi
done < CHANGELOG.md

match_tags
append_changelog_content
set_pr_body
set_new_changelog_content
cleanup
Loading