Skip to content

Commit

Permalink
feat(governance-tools): Script that adds entry for new release to CHA…
Browse files Browse the repository at this point in the history
…NGELOG after a proposal was successfully executed. (#3367)

# References

[👈 Previous PR][prev]

[prev]: #3332
  • Loading branch information
daniel-wong-dfinity-org authored Jan 9, 2025
1 parent 760e1f7 commit 5c6dc53
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 8 deletions.
8 changes: 2 additions & 6 deletions rs/nns/governance/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ unreleased_changelog.md file. In general though, the entries you see here were
moved from there.


# TEMPLATE: Proposal $ID
INSERT NEW RELEASES HERE

http://dashboard.internetcomputer.org/proposal/$ID

## Added

* Flying feature was added to widgets. This feature was discussed and/or
proposed at $FORUM_THREAD_URL and $MOTION_PROPOSAL_URL.
END
5 changes: 3 additions & 2 deletions rs/nns/governance/unreleased_changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ because this new function has no user-visible behavior change yet. Wait until it
is active (e.g. the feature flag is flipped to "enable") before adding an entry
to this file.

TODO: Automate moving content from unreleased_changelog.md to CHANGELOG.md.


# How to Write a Good Entry

The intended audience here is people who vote (with their neurons) in NNS, not
necessarily engineers who develop this canister.

If there is a motion proposal and/or forum thread where a feature (or bug fix)
was proposed, link to it.


# The Origin of This Process

Expand Down
149 changes: 149 additions & 0 deletions testnet/tools/nns-tools/add-release-to-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/usr/bin/env bash
set -Eeuo pipefail

NNS_TOOLS_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
source "$NNS_TOOLS_DIR/lib/include.sh"

help() {
print_green "
Usage: $0 <PROPOSAL_ID>
PROPOSAL_ID: The ID of a recently executed Governance backend canister upgrade proposal.
Moves the pending new changelog entry from unreleased_changelog.md to CHANGELOG.md.
The commit that the proposal is baded on MUST be currently check out.
Otherwise, this script will do nothing, and terminate with a nonzero exit
status.
" >&2
exit 1
}

PROPOSAL_ID="${1}"

cd "$(repo_root)"
PWD="$(pwd)"

# Fetch the proposal.
print_purple "Fetching proposal ${PROPOSAL_ID}..." >&2
PROPOSAL_INFO=$(
__dfx --quiet \
canister call \
--ic \
--candid rs/nns/governance/canister/governance.did \
$(nns_canister_id governance) \
get_proposal_info "(${PROPOSAL_ID})" \
| idl2json
)
# Unwrap.
LEN=$(echo "${PROPOSAL_INFO}" | jq '. | length')
if [[ "${LEN}" -ne 1 ]]; then
print_red "Unexpected result from the get_proposal_info method:" >&2
print_red "Should have one element, but has ${LEN}" >&2
exit 1
fi
PROPOSAL_INFO=$(echo "${PROPOSAL_INFO}" | jq '.[0]')

# Assert was executed.
EXECUTED_TIMESTAMP_SECONDS=$(echo "${PROPOSAL_INFO}" | jq '.executed_timestamp_seconds | tonumber')
if [[ "${EXECUTED_TIMESTAMP_SECONDS}" -eq 0 ]]; then
print_red "Proposal ${PROPOSAL_ID} exists, but was not successfully executed." >&2
exit 1
fi
SECONDS_AGO=$(($(date +%s) - "${EXECUTED_TIMESTAMP_SECONDS}"))
EXECUTED_ON=$(
date --utc \
--date=@"${EXECUTED_TIMESTAMP_SECONDS}" \
--iso-8601
)
print_purple "Proposal ${PROPOSAL_ID} was executed ${SECONDS_AGO} seconds ago." >&2

# Extract which canister was upgraded, and to what commit.
TITLE=$(echo "${PROPOSAL_INFO}" | jq -r '.proposal[0].summary' | head -n 1)
CANISTER_NAME=$(
echo "${TITLE}" \
| sed 's/# Upgrade the //' | sed 's/ Canister to Commit .*//' \
| tr '[:upper:]' '[:lower:]'
)
DESTINATION_COMMIT_ID=$(echo "${TITLE}" | sed 's/# Upgrade the .* Canister to Commit //')

# Fail if the proposal's commit is not checked out.
if [[ $(git rev-parse HEAD) != $DESTINATION_COMMIT_ID* ]]; then
echo >&2
print_red "You currently have $(git rev-parse HEAD)" >&2
print_red "checked out, but this command only supports being run when" >&2
print_red "the proposal's commit (${DESTINATION_COMMIT_ID}) is checked out." >&2
exit 1
fi

# cd to the canister's primary code path.
CANISTER_CODE_PATH=$(
get_nns_canister_code_location "${CANISTER_NAME}" \
| sed "s^${PWD}^.^g" \
| cut -d' ' -f1
)
cd "${CANISTER_CODE_PATH}"

# Assert that there is a CHANGELOG.md file.
if [[ ! -e CHANGELOG.md ]]; then
echo >&2
print_red "${CANISTER_NAME} has no CHANGELOG.md file." >&2
exit 1
fi
# TODO: Also verify that unreleased_changelog.md exists.
# TODO: Verify that there are no uncommited changes in this dir, the canister's primary code path.

# Construct new entry for CHANGELOG.md
#
# Python is used to filter out empty sections.
# Python is used because I cannot figure out how to do that using mac sed.
NEW_FEATURES_AND_FIXES=$(
sed '1,/^# Next Upgrade Proposal$/d' \
unreleased_changelog.md \
| python3 -c 'import sys, re; s = sys.stdin.read(); print(re.sub(r"## [\w ]+\n+(?=##|\Z)", "", s).strip())'
)
if [[ -z "${NEW_FEATURES_AND_FIXES}" ]]; then
echo >&2
print_red "The ${CANISTER_NAME} canister has no information in its unreleased_changelog.md." >&2
exit 1
fi
NEW_ENTRY="# ${EXECUTED_ON}: Proposal ${PROPOSAL_ID}
http://dashboard.internetcomputer.org/proposals/${PROPOSAL_ID}
${NEW_FEATURES_AND_FIXES}
"

CHANGELOG_INTRODUCTION=$(sed -n '/^INSERT NEW RELEASES HERE$/q;p' CHANGELOG.md)
CHANGELOG_EARLIER_RELEASES=$(sed '1,/^INSERT NEW RELEASES HERE$/d' CHANGELOG.md)

# Insert new entry into CHANGELOG.md.
echo -n "${CHANGELOG_INTRODUCTION}
INSERT NEW RELEASES HERE
${NEW_ENTRY}${CHANGELOG_EARLIER_RELEASES}
" \
>CHANGELOG.md

UNRELEASED_CHANGELOG_INTRODUCTION=$(sed -n '/^# Next Upgrade Proposal$/q;p' unreleased_changelog.md)
echo -n "${UNRELEASED_CHANGELOG_INTRODUCTION}
# Next Upgrade Proposal
## Added
## Changed
## Deprecated
## Removed
## Fixed
## Security
""" \
>unreleased_changelog.md

0 comments on commit 5c6dc53

Please sign in to comment.