mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 13:27:57 +00:00
Add changelog generation (#761)
* WIP Release notes generation and templates * WIP Add new sections to the template * WIP renaming and wip * Fix runtime template * Add doc, NO_CACHE and tweaking of the templates * Renaming cl into cumulus to make room for the polkadot and substrate * Fetch data from Substrate and Polkadot * WIP convert bash script to ruby * Convert to Ruby * Fix host function delection * Extract priority to a macro * Fix misc changes * Draft release workflow * Fix runtime dir * Add ENV to ignore runtimes * Install tooling separately * WIP troubleshooting - remove sudo * Minor formatting fixes * Fix workflow * Add missing dep * Linting * Fix changelog script * Add missing tera install * Use absolute paths * Fix path + cleanup * Fix changelog generation * Add missing pre-release ENV * Fix rust version ENV * Fix release notes path * Fix output * Fix runtime_dir for cumulus * Fix ENV substitutions * Fix styling * Debugging * Styling * Fix call to fetch the runtime version * Cleanup and doc * Delete sample .env * Update scripts/changelog/templates/change.md.tera Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Change XCM emoji marker for a ✉️ Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
This commit is contained in:
+207
@@ -0,0 +1,207 @@
|
||||
name: Publish draft release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ref1:
|
||||
description: The 'from' tag to use for the diff
|
||||
default: statemine-v5.0.0
|
||||
required: true
|
||||
ref2:
|
||||
description: The 'to' tag to use for the diff
|
||||
default: HEAD
|
||||
required: true
|
||||
pre_release:
|
||||
description: For pre-releases
|
||||
default: "true"
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
get-rust-versions:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: paritytech/ci-linux:production
|
||||
outputs:
|
||||
rustc-stable: ${{ steps.get-rust-versions.outputs.stable }}
|
||||
rustc-nightly: ${{ steps.get-rust-versions.outputs.nightly }}
|
||||
steps:
|
||||
- id: get-rust-versions
|
||||
run: |
|
||||
echo "::set-output name=stable::$(rustc +stable --version)"
|
||||
echo "::set-output name=nightly::$(rustc +nightly --version)"
|
||||
|
||||
build-runtimes:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
runtime: ["shell", "statemine", "statemint", "westmint", "rococo"]
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Cache target dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: "${{ github.workspace }}/runtime/${{ matrix.runtime }}/target"
|
||||
key: srtool-target-${{ matrix.runtime }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
srtool-target-${{ matrix.runtime }}-
|
||||
srtool-target-
|
||||
|
||||
- name: Build ${{ matrix.runtime }} runtime
|
||||
id: srtool_build
|
||||
uses: chevdor/srtool-actions@v0.3.0
|
||||
with:
|
||||
image: paritytech/srtool
|
||||
chain: ${{ matrix.runtime }}
|
||||
runtime_dir: polkadot-parachains/${{ matrix.runtime }}
|
||||
|
||||
- name: Store srtool digest to disk
|
||||
run: |
|
||||
echo '${{ steps.srtool_build.outputs.json }}' | \
|
||||
jq > ${{ matrix.runtime }}_srtool_output.json
|
||||
|
||||
- name: Upload ${{ matrix.runtime }} srtool json
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.runtime }}-srtool-json
|
||||
path: ${{ matrix.runtime }}_srtool_output.json
|
||||
|
||||
- name: Upload ${{ matrix.runtime }} runtime
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.runtime }}-runtime
|
||||
path: |
|
||||
${{ steps.srtool_build.outputs.wasm_compressed }}
|
||||
|
||||
publish-draft-release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: ["get-rust-versions", "build-runtimes"]
|
||||
outputs:
|
||||
release_url: ${{ steps.create-release.outputs.html_url }}
|
||||
asset_upload_url: ${{ steps.create-release.outputs.upload_url }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
path: cumulus
|
||||
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 3.0.0
|
||||
|
||||
- name: Download srtool json output
|
||||
uses: actions/download-artifact@v2
|
||||
|
||||
- name: Prepare tooling
|
||||
run: |
|
||||
cd cumulus/scripts/changelog
|
||||
gem install bundler changelogerator
|
||||
bundle install
|
||||
changelogerator --help
|
||||
|
||||
URL=https://github.com/chevdor/tera-cli/releases/download/v0.2.1/tera-cli_linux_amd64.deb
|
||||
wget $URL -O tera.deb
|
||||
sudo dpkg -i tera.deb
|
||||
tera --version
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
RUSTC_STABLE: ${{ needs.get-rust-versions.outputs.rustc-stable }}
|
||||
RUSTC_NIGHTLY: ${{ needs.get-rust-versions.outputs.rustc-nightly }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NO_CACHE: 1
|
||||
DEBUG: 1
|
||||
SHELL_DIGEST: ${{ github.workspace}}/shell-srtool-json/shell_srtool_output.json
|
||||
WESTMINT_DIGEST: ${{ github.workspace}}/westmint-srtool-json/westmint_srtool_output.json
|
||||
STATEMINE_DIGEST: ${{ github.workspace}}/statemine-srtool-json/statemine_srtool_output.json
|
||||
STATEMINT_DIGEST: ${{ github.workspace}}/statemint-srtool-json/statemint_srtool_output.json
|
||||
ROCOCO_DIGEST: ${{ github.workspace}}/rococo-srtool-json/rococo_srtool_output.json
|
||||
REF1: ${{ github.event.inputs.ref1 }}
|
||||
REF2: ${{ github.event.inputs.ref2 }}
|
||||
PRE_RELEASE: ${{ github.event.inputs.pre_release }}
|
||||
HIDE_SRTOOL_ROCOCO: false
|
||||
HIDE_SRTOOL_SHELL: false
|
||||
run: |
|
||||
find ${{env.GITHUB_WORKSPACE}} -type f -name "*_srtool_output.json"
|
||||
ls -al $SHELL_DIGEST
|
||||
ls -al $WESTMINT_DIGEST
|
||||
ls -al $STATEMINE_DIGEST
|
||||
ls -al $STATEMINT_DIGEST
|
||||
ls -al $ROCOCO_DIGEST
|
||||
|
||||
echo "The diff will be computed from $REF1 to $REF2"
|
||||
cd cumulus/scripts/changelog
|
||||
./bin/changelog $REF1 $REF2 release-notes.md
|
||||
ls -al release-notes.md
|
||||
|
||||
- name: Create draft release
|
||||
id: create-release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: parachains-${{ github.ref }}
|
||||
release_name: Parachains ${{ github.ref }}
|
||||
body_path: ./cumulus/scripts/changelog/release-notes.md
|
||||
draft: true
|
||||
|
||||
publish-runtimes:
|
||||
runs-on: ubuntu-latest
|
||||
needs: ["publish-draft-release"]
|
||||
env:
|
||||
RUNTIME_DIR: polkadot-parachains
|
||||
strategy:
|
||||
matrix:
|
||||
runtime: ["shell", "statemine", "statemint", "westmint", "rococo"]
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 3.0.0
|
||||
|
||||
- name: Get runtime version for ${{ matrix.runtime }}
|
||||
id: get-runtime-ver
|
||||
run: |
|
||||
echo "require './scripts/github/runtime-version.rb'" > script.rb
|
||||
echo "puts get_runtime(runtime: \"${{ matrix.runtime }}\", runtime_dir: \"$RUNTIME_DIR\")" >> script.rb
|
||||
|
||||
echo "Current folder: $PWD"
|
||||
ls "$RUNTIME_DIR/${{ matrix.runtime }}"
|
||||
runtime_ver=$(ruby script.rb)
|
||||
echo "Found version: >$runtime_ver<"
|
||||
echo "::set-output name=runtime_ver::$runtime_ver"
|
||||
|
||||
- name: Upload compressed ${{ matrix.runtime }} wasm
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.publish-draft-release.outputs.asset_upload_url }}
|
||||
asset_path: "${{ matrix.runtime }}-runtime/${{ matrix.runtime }}_runtime.compact.compressed.wasm"
|
||||
asset_name: ${{ matrix.runtime }}_runtime-v${{ steps.get-runtime-ver.outputs.runtime_ver }}.compact.compressed.wasm
|
||||
asset_content_type: application/wasm
|
||||
|
||||
post_to_matrix:
|
||||
runs-on: ubuntu-latest
|
||||
needs: publish-draft-release
|
||||
steps:
|
||||
- name: Internal polkadot channel
|
||||
uses: s3krit/matrix-message-action@v0.0.3
|
||||
with:
|
||||
room_id: ${{ secrets.INTERNAL_POLKADOT_MATRIX_ROOM_ID }}
|
||||
access_token: ${{ secrets.MATRIX_ACCESS_TOKEN }}
|
||||
message: |
|
||||
**New draft for ${{ github.repository }}**: ${{ github.ref }}<br/>
|
||||
|
||||
Draft release created: [draft](${{ needs.publish-draft-release.outputs.release_url }})
|
||||
|
||||
NOTE: The link above will no longer be valid if the draft is edited. You can then use the following link:
|
||||
[${{ github.server_url }}/${{ github.repository }}/releases](${{ github.server_url }}/${{ github.repository }}/releases)
|
||||
server: "matrix.parity.io"
|
||||
@@ -1 +1,4 @@
|
||||
changelog.md
|
||||
*.json
|
||||
release*.md
|
||||
.env
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
||||
|
||||
gem 'octokit', '~> 4'
|
||||
|
||||
gem 'git_diff_parser', '~> 3'
|
||||
|
||||
gem 'toml', '~> 0.3.0'
|
||||
|
||||
gem 'rake', group: :dev
|
||||
|
||||
gem 'optparse', '~> 0.1.1'
|
||||
|
||||
gem 'logger', '~> 1.4'
|
||||
|
||||
gem 'test-unit', group: :dev
|
||||
|
||||
gem 'rubocop', group: :dev, require: false
|
||||
@@ -0,0 +1,79 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
ast (2.4.2)
|
||||
faraday (1.8.0)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-httpclient (~> 1.0.1)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.1)
|
||||
faraday-patron (~> 1.0)
|
||||
faraday-rack (~> 1.0)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-em_http (1.0.0)
|
||||
faraday-em_synchrony (1.0.0)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-httpclient (1.0.1)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http_persistent (1.2.0)
|
||||
faraday-patron (1.0.0)
|
||||
faraday-rack (1.0.0)
|
||||
git_diff_parser (3.2.0)
|
||||
logger (1.4.4)
|
||||
multipart-post (2.1.1)
|
||||
octokit (4.21.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
optparse (0.1.1)
|
||||
parallel (1.21.0)
|
||||
parser (3.0.2.0)
|
||||
ast (~> 2.4.1)
|
||||
parslet (2.0.0)
|
||||
power_assert (2.0.1)
|
||||
public_suffix (4.0.6)
|
||||
rainbow (3.0.0)
|
||||
rake (13.0.6)
|
||||
regexp_parser (2.1.1)
|
||||
rexml (3.2.5)
|
||||
rubocop (1.23.0)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.0.0.0)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml
|
||||
rubocop-ast (>= 1.12.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.13.0)
|
||||
parser (>= 3.0.1.1)
|
||||
ruby-progressbar (1.11.0)
|
||||
ruby2_keywords (0.0.5)
|
||||
sawyer (0.8.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (> 0.8, < 2.0)
|
||||
test-unit (3.5.1)
|
||||
power_assert
|
||||
toml (0.3.0)
|
||||
parslet (>= 1.8.0, < 3.0.0)
|
||||
unicode-display_width (2.1.0)
|
||||
|
||||
PLATFORMS
|
||||
x86_64-darwin-20
|
||||
|
||||
DEPENDENCIES
|
||||
git_diff_parser (~> 3)
|
||||
logger (~> 1.4)
|
||||
octokit (~> 4)
|
||||
optparse (~> 0.1.1)
|
||||
rake
|
||||
rubocop
|
||||
test-unit
|
||||
toml (~> 0.3.0)
|
||||
|
||||
BUNDLED WITH
|
||||
2.2.22
|
||||
@@ -1,13 +1,71 @@
|
||||
# Changelog
|
||||
|
||||
Currently, the changelog is built locally.
|
||||
Run:
|
||||
Currently, the changelog is built locally. It will be moved to CI once labels stabilize.
|
||||
|
||||
For now, a bit of preparation is required before you can run the script:
|
||||
- fetch the srtool digests
|
||||
- store them under the `digests` folder as `<chain>-srtool-digest.json`
|
||||
- ensure the `.env` file is up to date with correct information
|
||||
|
||||
The content of the release notes is generated from the template files under the `scripts/changelog/templates` folder. For readability and maintenance, the template is split into several small snippets.
|
||||
|
||||
Run:
|
||||
```
|
||||
./changelog.sh <ref_since>
|
||||
./bin/changelog <ref_since> [<ref_until>=HEAD]
|
||||
```
|
||||
|
||||
For instance:
|
||||
```
|
||||
./changelog.sh statemine_v4
|
||||
./bin/changelog statemine-v5.0.0
|
||||
```
|
||||
|
||||
A file called `release-notes.md` will be generated and can be used for the release.
|
||||
|
||||
## ENV
|
||||
|
||||
You may use the following ENV for testing:
|
||||
|
||||
```
|
||||
RUSTC_STABLE="rustc 1.56.1 (59eed8a2a 2021-11-01)"
|
||||
RUSTC_NIGHTLY="rustc 1.57.0-nightly (51e514c0f 2021-09-12)"
|
||||
PRE_RELEASE=true
|
||||
HIDE_SRTOOL_ROCOCO=true
|
||||
HIDE_SRTOOL_SHELL=true
|
||||
REF1=statemine-v5.0.0
|
||||
REF2=HEAD
|
||||
DEBUG=1
|
||||
NO_CACHE=1
|
||||
```
|
||||
## Considered labels
|
||||
|
||||
The following list will likely evolve over time and it will be hard to keep it in sync.
|
||||
In any case, if you want to find all the labels that are used, search for `meta` in the templates.
|
||||
Currently, the considered labels are:
|
||||
|
||||
- Priority: C<N> labels
|
||||
- Audit: D<N> labels
|
||||
- E4 => new host function
|
||||
- B0 => silent, not showing up
|
||||
- B1-releasenotes (misc unless other labels)
|
||||
- B5-client (client changes)
|
||||
- B7-runtimenoteworthy (runtime changes)
|
||||
- T6-XCM
|
||||
|
||||
Note that labels with the same letter are mutually exclusive.
|
||||
A PR should not have both `B0` and `B5`, or both `C1` and `C9`. In case of conflicts, the template will
|
||||
decide which label will be considered.
|
||||
|
||||
## Dev and debuggin
|
||||
|
||||
### Hot Reload
|
||||
|
||||
The following command allows **Hot Reload**:
|
||||
```
|
||||
fswatch templates -e ".*\.md$" | xargs -n1 -I{} ./bin/changelog statemine-v5.0.0
|
||||
```
|
||||
### Caching
|
||||
|
||||
By default, if the changelog data from Github is already present, the calls to the Github API will be skipped
|
||||
and the local version of the data will be used. This is much faster.
|
||||
If you know that some labels have changed in Github, you probably want to refresh the data.
|
||||
You can then either delete manually the `cumulus.json` file or `export NO_CACHE=1` to force refreshing the data.
|
||||
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# frozen_string_literal: true
|
||||
|
||||
# call for instance as:
|
||||
# ./bin/changelog statemine-v5.0.0
|
||||
#
|
||||
# You may set the ENV NO_CACHE to force fetching from Github
|
||||
# You should also ensure you set the ENV: GITHUB_TOKEN
|
||||
|
||||
require_relative '../lib/changelog'
|
||||
require 'logger'
|
||||
|
||||
logger = Logger.new($stdout)
|
||||
logger.level = Logger::DEBUG
|
||||
logger.debug('Starting')
|
||||
|
||||
owner = 'paritytech'
|
||||
repo = 'cumulus'
|
||||
ref1 = ARGV[0]
|
||||
ref2 = ARGV[1] || 'HEAD'
|
||||
output = ARGV[2] || 'release-notes.md'
|
||||
|
||||
ENV['REF1'] = ref1
|
||||
ENV['REF2'] = ref2
|
||||
|
||||
gh_cumulus = SubRef.new(format('%<owner>s/%<repo>s', { owner: owner, repo: repo }))
|
||||
|
||||
polkadot_ref1 = gh_cumulus.get_dependency_reference(ref1, 'polkadot-client')
|
||||
polkadot_ref2 = gh_cumulus.get_dependency_reference(ref2, 'polkadot-client')
|
||||
|
||||
substrate_ref1 = gh_cumulus.get_dependency_reference(ref1, 'sp-io')
|
||||
substrate_ref2 = gh_cumulus.get_dependency_reference(ref2, 'sp-io')
|
||||
|
||||
logger.debug("Polkadot from: #{polkadot_ref1}")
|
||||
logger.debug("Polkadot to: #{polkadot_ref2}")
|
||||
|
||||
logger.debug("Substrate from: #{substrate_ref1}")
|
||||
logger.debug("Substrate to: #{substrate_ref2}")
|
||||
|
||||
cumulus_data = 'cumulus.json'
|
||||
substrate_data = 'substrate.json'
|
||||
polkadot_data = 'polkadot.json'
|
||||
|
||||
logger.debug("Using CUMULUS: #{cumulus_data}")
|
||||
logger.debug("Using SUBSTRATE: #{substrate_data}")
|
||||
logger.debug("Using POLKADOT: #{polkadot_data}")
|
||||
|
||||
logger.warn('NO_CACHE set') if ENV['NO_CACHE']
|
||||
|
||||
# This is acting as cache so we don't spend time querying while testing
|
||||
if ENV['NO_CACHE'] || !File.file?(cumulus_data)
|
||||
logger.debug(format('Fetching data for Cumulus into %s', cumulus_data))
|
||||
cmd = format('changelogerator %<owner>s/%<repo>s -f %<from>s -t %<to>s > %<output>s',
|
||||
{ owner: owner, repo: repo, from: ref1, to: ref2, output: cumulus_data })
|
||||
system(cmd)
|
||||
else
|
||||
logger.debug("Re-using:#{cumulus_data}")
|
||||
end
|
||||
|
||||
if ENV['NO_CACHE'] || !File.file?(polkadot_data)
|
||||
logger.debug(format('Fetching data for Polkadot into %s', polkadot_data))
|
||||
cmd = format('changelogerator %<owner>s/%<repo>s -f %<from>s -t %<to>s > %<output>s',
|
||||
{ owner: owner, repo: 'polkadot', from: polkadot_ref1, to: polkadot_ref2, output: polkadot_data })
|
||||
system(cmd)
|
||||
else
|
||||
logger.debug("Re-using:#{polkadot_data}")
|
||||
end
|
||||
|
||||
if ENV['NO_CACHE'] || !File.file?(substrate_data)
|
||||
logger.debug(format('Fetching data for Substrate into %s', substrate_data))
|
||||
cmd = format('changelogerator %<owner>s/%<repo>s -f %<from>s -t %<to>s > %<output>s',
|
||||
{ owner: owner, repo: 'substrate', from: substrate_ref1, to: substrate_ref2, output: substrate_data })
|
||||
system(cmd)
|
||||
else
|
||||
logger.debug("Re-using:#{substrate_data}")
|
||||
end
|
||||
|
||||
SHELL_DIGEST = ENV['SHELL_DIGEST'] || 'digests/shell-srtool-digest.json'
|
||||
WESTMINT_DIGEST = ENV['WESTMINT_DIGEST'] || 'digests/westmint-srtool-digest.json'
|
||||
STATEMINE_DIGEST = ENV['STATEMINE_DIGEST'] || 'digests/statemine-srtool-digest.json'
|
||||
STATEMINT_DIGEST = ENV['STATEMINT_DIGEST'] || 'digests/rococo-srtool-digest.json'
|
||||
ROCOCO_DIGEST = ENV['ROCOCO_DIGEST'] || 'digests/rococo-srtool-digest.json'
|
||||
|
||||
# Here we compose all the pieces together into one
|
||||
# single big json file.
|
||||
cmd = format('jq \
|
||||
--slurpfile cumulus %s \
|
||||
--slurpfile substrate %s \
|
||||
--slurpfile polkadot %s \
|
||||
--slurpfile srtool_shell %s \
|
||||
--slurpfile srtool_westmint %s \
|
||||
--slurpfile srtool_statemine %s \
|
||||
--slurpfile srtool_statemint %s \
|
||||
--slurpfile srtool_rococo %s \
|
||||
-n \'{
|
||||
cumulus: $cumulus[0],
|
||||
substrate: $substrate[0],
|
||||
polkadot: $polkadot[0],
|
||||
srtool: [
|
||||
{ name: "rococo", data: $srtool_rococo[0] },
|
||||
{ name: "shell", data: $srtool_shell[0] },
|
||||
{ name: "westmint", data: $srtool_westmint[0] },
|
||||
{ name: "statemint", data: $srtool_statemint[0] },
|
||||
{ name: "statemine", data: $srtool_statemine[0] }
|
||||
] }\' > context.json', cumulus_data, substrate_data, polkadot_data,
|
||||
SHELL_DIGEST,
|
||||
WESTMINT_DIGEST,
|
||||
STATEMINE_DIGEST,
|
||||
STATEMINT_DIGEST,
|
||||
ROCOCO_DIGEST)
|
||||
system(cmd)
|
||||
|
||||
cmd = format('tera --env --env-key env --include-path templates \
|
||||
--template templates/template.md.tera context.json > %s', output)
|
||||
system(cmd)
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
REF1=$1
|
||||
|
||||
JSON=$(git log $REF1..HEAD \
|
||||
--pretty=format:'{ "commit": "%H", "short_sha": "%h", "author": "%an", "date": "%ad", "message": "%s"},' \
|
||||
$@ | \
|
||||
perl -pe 'BEGIN{print "{ \"since\": \"'${REF1}'\", \"commits\": ["}; END{print "]}"}' | \
|
||||
perl -pe 's/},]/}]/')
|
||||
|
||||
echo $JSON | tera --template templates/changelog.md --stdin | tee
|
||||
@@ -0,0 +1 @@
|
||||
*.json
|
||||
@@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# A Class to find Substrate references
|
||||
class SubRef
|
||||
require 'octokit'
|
||||
require 'toml'
|
||||
|
||||
attr_reader :client, :repository
|
||||
|
||||
def initialize(github_repo)
|
||||
@client = Octokit::Client.new(
|
||||
access_token: ENV['GITHUB_TOKEN']
|
||||
)
|
||||
@repository = @client.repository(github_repo)
|
||||
end
|
||||
|
||||
# This function checks the Cargo.lock of a given
|
||||
# Rust project, for a given package, and fetches
|
||||
# the dependency git ref.
|
||||
def get_dependency_reference(ref, package)
|
||||
cargo = TOML::Parser.new(
|
||||
Base64.decode64(
|
||||
@client.contents(
|
||||
@repository.full_name,
|
||||
path: 'Cargo.lock',
|
||||
query: { ref: ref.to_s }
|
||||
).content
|
||||
)
|
||||
).parsed
|
||||
cargo['package'].find { |p| p['name'] == package }['source'].split('#').last
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
{# This macro shows ONE change #}
|
||||
{%- macro change(c, cml="[C]", dot="[P]", sub="[S]") -%}
|
||||
|
||||
{%- if c.meta.C and c.meta.C.value >= 7 -%}
|
||||
{%- set prio = " ‼️ HIGH" -%}
|
||||
{%- elif c.meta.C and c.meta.C.value >= 5 -%}
|
||||
{%- set prio = " ❗️ Medium" -%}
|
||||
{%- elif c.meta.C and c.meta.C.value >= 3 -%}
|
||||
{%- set prio = " Low" -%}
|
||||
{%- else -%}
|
||||
{%- set prio = "" -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- set audit = "" -%}
|
||||
{#
|
||||
{%- if c.meta.D and c.meta.D.value == 1 -%}
|
||||
{%- set audit = "✅ audited " -%}
|
||||
{%- elif c.meta.D and c.meta.D.value == 2 -%}
|
||||
{%- set audit = "✅ trivial " -%}
|
||||
{%- elif c.meta.D and c.meta.D.value == 3 -%}
|
||||
{%- set audit = "✅ trivial " -%}
|
||||
{%- elif c.meta.D and c.meta.D.value == 5 -%}
|
||||
{%- set audit = "⏳ pending non-critical audit " -%}
|
||||
{%- else -%}
|
||||
{%- set audit = "" -%}
|
||||
{%- endif -%}
|
||||
#}
|
||||
|
||||
{%- if c.html_url is containing("polkadot") -%}
|
||||
{%- set repo = dot -%}
|
||||
{%- elif c.html_url is containing("cumulus") -%}
|
||||
{%- set repo = cml -%}
|
||||
{%- elif c.html_url is containing("substrate") -%}
|
||||
{%- set repo = sub -%}
|
||||
{%- else -%}
|
||||
{%- set repo = " " -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- if c.meta.T and c.meta.T.value == 6 -%}
|
||||
{%- set xcm = " [✉️ XCM]" -%}
|
||||
{%- else -%}
|
||||
{%- set xcm = "" -%}
|
||||
{%- endif -%}
|
||||
{{- repo }} {{ audit }}[`#{{c.number}}`]({{c.html_url}}) {{- prio }} - {{ c.title | capitalize | truncate(length=60, end="…") }}{{xcm }}
|
||||
{%- endmacro change -%}
|
||||
@@ -0,0 +1,14 @@
|
||||
{# This include generates the section showing the changes #}
|
||||
## Changes
|
||||
|
||||
### Legend
|
||||
|
||||
- {{ CML }} Cumulus
|
||||
- {{ DOT }} Polkadot
|
||||
- {{ SUB }} Substrate
|
||||
|
||||
{% include "changes_client.md.tera" %}
|
||||
|
||||
{% include "changes_runtime.md.tera" %}
|
||||
|
||||
{% include "changes_misc.md.tera" %}
|
||||
@@ -0,0 +1,17 @@
|
||||
{% import "change.md.tera" as m_c -%}
|
||||
### Client
|
||||
|
||||
{#- The changes are sorted by merge date #}
|
||||
{%- for pr in changes | sort(attribute="merged_at") %}
|
||||
|
||||
{%- if pr.meta.B %}
|
||||
{%- if pr.meta.B.value == 0 %}
|
||||
{#- We skip silent ones -#}
|
||||
{%- else -%}
|
||||
|
||||
{%- if pr.meta.B.value == 5 and not pr.title is containing("ompanion") %}
|
||||
- {{ m_c::change(c=pr) }}
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,39 @@
|
||||
{%- import "change.md.tera" as m_c -%}
|
||||
|
||||
{%- set_global misc_count = 0 -%}
|
||||
{#- First pass to count #}
|
||||
{%- for pr in changes -%}
|
||||
{%- if pr.meta.B %}
|
||||
{%- if pr.meta.B.value == 0 -%}
|
||||
{#- We skip silent ones -#}
|
||||
{%- else -%}
|
||||
{%- if pr.meta.B and pr.meta.B.value != 5 and pr.meta.B.value != 7 or pr.meta.C or not pr.meta.B %}
|
||||
{%- set_global misc_count = misc_count + 1 -%}
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
|
||||
### Misc
|
||||
|
||||
{% if misc_count > 10 %}
|
||||
There are {{ misc_count }} other misc. changes. You can expand the list below to view them all.
|
||||
<details><summary>{{ misc_count }} misc. changes</summary>
|
||||
{% endif -%}
|
||||
|
||||
{#- The changes are sorted by merge date #}
|
||||
{%- for pr in changes | sort(attribute="merged_at") %}
|
||||
{%- if pr.meta.B and not pr.title is containing("ompanion") %}
|
||||
{%- if pr.meta.B.value == 0 %}
|
||||
{#- We skip silent ones -#}
|
||||
{%- else -%}
|
||||
{%- if pr.meta.B and pr.meta.B.value != 5 and pr.meta.B.value != 7 or pr.meta.C or not pr.meta.B %}
|
||||
- {{ m_c::change(c=pr) }}
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
|
||||
{% if misc_count > 10 %}
|
||||
</details>
|
||||
{% endif -%}
|
||||
@@ -0,0 +1,19 @@
|
||||
{%- import "change.md.tera" as m_c -%}
|
||||
|
||||
### Runtime
|
||||
|
||||
{#- The changes are sorted by merge date -#}
|
||||
{% for pr in changes | sort(attribute="merged_at") -%}
|
||||
|
||||
{%- if pr.meta.B -%}
|
||||
{%- if pr.meta.B.value == 0 -%}
|
||||
{#- We skip silent ones -#}
|
||||
{%- else -%}
|
||||
|
||||
{%- if pr.meta.B.value == 7 and not pr.title is containing("ompanion") %}
|
||||
- {{ m_c::change(c=pr) }}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
|
||||
{%- endif -%}
|
||||
{%- endfor %}
|
||||
@@ -0,0 +1,6 @@
|
||||
## Rust compiler versions
|
||||
|
||||
This release was tested against the following versions of `rustc`. Other versions may work.
|
||||
|
||||
- Rust Stable: `{{ env.RUSTC_STABLE }}`
|
||||
- Rust Nightly: `{{ env.RUSTC_NIGHTLY }}`
|
||||
@@ -0,0 +1,10 @@
|
||||
{%- set to_ignore = changes | filter(attribute="meta.B.value", value=0) %}
|
||||
|
||||
<!--
|
||||
## Debug
|
||||
|
||||
changes:
|
||||
- total: {{ changes | length }}
|
||||
- silent: {{ to_ignore | length }}
|
||||
- remaining: {{ changes | length - to_ignore | length }}
|
||||
-->
|
||||
@@ -0,0 +1,10 @@
|
||||
<!--
|
||||
## Docker images
|
||||
|
||||
The docker image for this release can be found in [Docker hub](https://hub.docker.com/r/parity/polkadot-collator/tags?page=1&ordering=last_updated).
|
||||
|
||||
You may also pull it with:
|
||||
```
|
||||
docker pull parity/polkadot-collator:latest
|
||||
```
|
||||
-->
|
||||
@@ -0,0 +1,37 @@
|
||||
{% import "priority.md.tera" as m_p -%}
|
||||
## Global Priority
|
||||
|
||||
{%- set cumulus_prio = 0 -%}
|
||||
{%- set polkadot_prio = 0 -%}
|
||||
{%- set substrate_prio = 0 -%}
|
||||
|
||||
{# We fetch the various priorities #}
|
||||
{%- if cumulus.meta.C -%}
|
||||
{%- set cumulus_prio = cumulus.meta.C.max -%}
|
||||
{%- endif -%}
|
||||
{%- if polkadot.meta.C -%}
|
||||
{%- set polkadot_prio = polkadot.meta.C.max -%}
|
||||
{%- endif -%}
|
||||
{%- if substrate.meta.C -%}
|
||||
{%- set substrate_prio = substrate.meta.C.max -%}
|
||||
{%- endif -%}
|
||||
|
||||
{# We compute the global priority #}
|
||||
{%- set global_prio = cumulus_prio -%}
|
||||
{%- if polkadot_prio > global_prio -%}
|
||||
{% set global_prio = polkadot_prio -%}
|
||||
{%- endif -%}
|
||||
{%- if substrate_prio > global_prio -%}
|
||||
{%- set global_prio = substrate_prio -%}
|
||||
{%- endif -%}
|
||||
|
||||
{# We show the result #}
|
||||
{{ m_p::priority(p=global_prio) }}
|
||||
|
||||
<!--
|
||||
- Cumulus: {{ cumulus_prio }}
|
||||
- Polkadot: {{ polkadot_prio }}
|
||||
- Substrate: {{ substrate_prio }}
|
||||
-->
|
||||
|
||||
{# todo: show high prio list here #}
|
||||
@@ -0,0 +1,30 @@
|
||||
{%- import "change.md.tera" as m_c -%}
|
||||
{%- set_global host_fn_count = 0 -%}
|
||||
|
||||
## Host functions
|
||||
|
||||
{% for pr in changes | sort(attribute="merged_at") -%}
|
||||
|
||||
{%- if pr.meta.B and pr.meta.B.value == 0 -%}
|
||||
{#- We skip silent ones -#}
|
||||
{%- else -%}
|
||||
{%- if pr.meta.E and pr.meta.E.value == 4 -%}
|
||||
{%- set_global host_fn_count = host_fn_count + 1 -%}
|
||||
- {{ m_c::change(c=pr) }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{%- endfor -%}
|
||||
|
||||
<!-- {{ host_fn_count }} host functions were detected -->
|
||||
|
||||
{% if host_fn_count == 0 -%}
|
||||
ℹ️ This release does not contain any new host functions.
|
||||
{% elif host_fn_count == 1 -%}
|
||||
⚠️ The runtimes in this release contain one new **host function**.
|
||||
|
||||
⚠️ It is critical that you update your client before the chain switches to the new runtimes.
|
||||
{%- else -%}
|
||||
⚠️ The runtimes in this release contain {{ host_fn_count }} new **host function{{ host_fn_count | pluralize }}**.
|
||||
|
||||
⚠️ It is critical that you update your client before the chain switches to the new runtimes.
|
||||
{%- endif %}
|
||||
@@ -0,0 +1,14 @@
|
||||
{%- import "change.md.tera" as m_c %}
|
||||
|
||||
## Migrations
|
||||
|
||||
{% for pr in changes | sort(attribute="merged_at") -%}
|
||||
|
||||
{%- if pr.meta.B and pr.meta.B.value == 0 %}
|
||||
{#- We skip silent ones -#}
|
||||
{%- else -%}
|
||||
{%- if pr.meta.E and pr.meta.E.value == 1 -%}
|
||||
- {{ m_c::change(c=pr) }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endfor -%}
|
||||
@@ -0,0 +1,9 @@
|
||||
{%- if env.PRE_RELEASE == "true" -%}
|
||||
-----
|
||||
⚠️ Howdy! Beware, this is a **pre-release**
|
||||
|
||||
-----
|
||||
|
||||
{%- else -%}
|
||||
<!-- NOT a pre-release-->
|
||||
{%- endif %}
|
||||
@@ -0,0 +1,21 @@
|
||||
{# This macro convert a priority level into readable output #}
|
||||
{%- macro priority(p) -%}
|
||||
|
||||
{%- if p >= 7 -%}
|
||||
{%- set prio = "‼️ HIGH" -%}
|
||||
{%- set text = "This is a **high priority** release and you must upgrade as as soon as possible" -%}
|
||||
{%- elif p >= 5 -%}
|
||||
{%- set prio = "❗️ Medium" -%}
|
||||
{%- set text = "This is a medium priority release and you should upgrade in a timely manner" -%}
|
||||
{%- elif p >= 3 -%}
|
||||
{%- set prio = "Low" -%}
|
||||
{%- set text = "This is a low priority release and you may upgrade at your convenience" -%}
|
||||
{%- endif %}
|
||||
|
||||
{%- if prio %}
|
||||
{{prio}}: {{text}}
|
||||
{%- else -%}
|
||||
<!-- No relevant Priority label as been detected -->
|
||||
{% endif %}
|
||||
|
||||
{%- endmacro priority -%}
|
||||
@@ -0,0 +1,27 @@
|
||||
{# This macro shows one runtime #}
|
||||
{%- macro runtime(runtime) -%}
|
||||
|
||||
### {{ runtime.name | capitalize }}
|
||||
|
||||
{%- if runtime.data.runtimes.compressed.subwasm.compression.compressed %}
|
||||
{%- set compressed = "Yes" %}
|
||||
{%- else %}
|
||||
{%- set compressed = "No" %}
|
||||
{%- endif %}
|
||||
|
||||
{%- set comp_ratio = 100 - (runtime.data.runtimes.compressed.subwasm.compression.size_compressed / runtime.data.runtimes.compressed.subwasm.compression.size_decompressed *100) %}
|
||||
<!-- commit : {{ runtime.data.commit }} -->
|
||||
<!-- tag : {{ runtime.data.tag }} -->
|
||||
<!-- branch : {{ runtime.data.branch }} -->
|
||||
<!-- pkg : {{ runtime.data.pkg }} -->
|
||||
```
|
||||
🏋️ Runtime Size: {{ runtime.data.runtimes.compressed.subwasm.size | filesizeformat }} ({{ runtime.data.runtimes.compressed.subwasm.size }} bytes)
|
||||
🔥 Core Version: {{ runtime.data.runtimes.compressed.subwasm.core_version }}
|
||||
🗜 Compressed: {{ compressed }}: {{ comp_ratio | round(method="ceil", precision=2) }}%
|
||||
🎁 Metadata version: {{ runtime.data.runtimes.compressed.subwasm.metadata_version }}
|
||||
🗳️ system.setCode hash: {{ runtime.data.runtimes.compressed.subwasm.proposal_hash }}
|
||||
🗳️ authorizeUpgrade hash: {{ runtime.data.runtimes.compressed.subwasm.parachain_authorize_upgrade_hash }}
|
||||
#️⃣ Blake2-256 hash: {{ runtime.data.runtimes.compressed.subwasm.blake2_256 }}
|
||||
📦 IPFS: {{ runtime.data.runtimes.compressed.subwasm.ipfs_hash }}
|
||||
```
|
||||
{%- endmacro runtime %}
|
||||
@@ -0,0 +1,17 @@
|
||||
{# This include shows the list and details of the runtimes #}
|
||||
{%- import "runtime.md.tera" as m_r -%}
|
||||
|
||||
## Runtimes
|
||||
|
||||
{% set rtm = srtool[0] -%}
|
||||
|
||||
The information about the runtimes included in this release can be found below.
|
||||
The runtimes have been built using [{{ rtm.data.gen }}](https://github.com/paritytech/srtool) and `{{ rtm.data.rustc }}`.
|
||||
|
||||
{%- for runtime in srtool | sort(attribute="name") %}
|
||||
{%- set HIDE_VAR = "HIDE_SRTOOL_" ~ runtime.name | upper %}
|
||||
{%- if not env is containing(HIDE_VAR) %}
|
||||
|
||||
{{ m_r::runtime(runtime=runtime) }}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
@@ -0,0 +1,28 @@
|
||||
{# This is the entry point of the template -#}
|
||||
<!-- repository: {{ cumulus.repository.name }} -->
|
||||
This release contains the changes from `{{ env.REF1 }}` to `{{ env.REF2 }}`.
|
||||
|
||||
{%- set changes = cumulus.changes | concat(with=substrate.changes) -%}
|
||||
{%- set changes = changes | concat(with=polkadot.changes) -%}
|
||||
{%- include "debug.md.tera" -%}
|
||||
|
||||
{%- set CML = "[C]" -%}
|
||||
{%- set DOT = "[P]" -%}
|
||||
{%- set SUB = "[S]" -%}
|
||||
|
||||
{# header warning and important notices -#}
|
||||
{% include "pre_release.md.tera" -%}
|
||||
|
||||
{% include "global_priority.md.tera" -%}
|
||||
|
||||
{% include "host_functions.md.tera" -%}
|
||||
|
||||
{% include "compiler.md.tera" -%}
|
||||
|
||||
{% include "migrations.md.tera" -%}
|
||||
|
||||
{% include "runtimes.md.tera" -%}
|
||||
|
||||
{% include "changes.md.tera" -%}
|
||||
|
||||
{% include "docker_image.md.tera" -%}
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../lib/changelog'
|
||||
require 'test/unit'
|
||||
|
||||
class TestChangelog < Test::Unit::TestCase
|
||||
def test_get_dep_ref_polkadot
|
||||
c = SubRef.new('paritytech/polkadot')
|
||||
ref = '13c2695'
|
||||
package = 'sc-cli'
|
||||
result = c.get_dependency_reference(ref, package)
|
||||
assert_equal('7db0768a85dc36a3f2a44d042b32f3715c00a90d', result)
|
||||
end
|
||||
|
||||
def test_get_dep_ref_invalid_ref
|
||||
c = SubRef.new('paritytech/polkadot')
|
||||
ref = '9999999'
|
||||
package = 'sc-cli'
|
||||
assert_raise do
|
||||
c.get_dependency_reference(ref, package)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Gets the runtime version for a given runtime from the filesystem.
|
||||
# Optionally accepts a path that is the root of the project which defaults to
|
||||
# the current working directory
|
||||
def get_runtime(runtime: nil, path: '.', runtime_dir: 'runtime')
|
||||
File.open(path + "/#{runtime_dir}/#{runtime}/src/lib.rs") do |f|
|
||||
f.find { |l| l =~ /spec_version/ }.match(/[0-9]+/)[0]
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user