From 37a877257c310a4b2cc392f0c5720097897062a4 Mon Sep 17 00:00:00 2001 From: Oleh Fedorenko Date: Thu, 30 Nov 2023 15:35:30 +0000 Subject: [PATCH] Add rel-eng --- .gitignore | 1 + README.md | 3 + rel-eng/gem_release.ipynb | 457 ++++++++++++++++++++++++++++++++++++++ release_notes.md | 1 + 4 files changed, 462 insertions(+) create mode 100644 rel-eng/gem_release.ipynb create mode 100644 release_notes.md diff --git a/.gitignore b/.gitignore index 601058c7b..8fed39c29 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ Gemfile.lock node_modules/ package-lock.json coverage/ +.ruby-version diff --git a/README.md b/README.md index 26ab54aef..78108763f 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,8 @@ Auto correct can be executed directly too: ## Release Process +### Please refer to the [rel-eng notebook](rel-eng/gem_release.ipynb) + ### Pull Translations from Transifex As part of the release process, localization must be synced from Transifex. See the [wiki](http://projects.theforeman.org/projects/foreman/wiki/How_to_Create_a_Plugin#Pulling-translations-from-Transifex) for more information. @@ -69,6 +71,7 @@ As part of the release process, localization must be synced from Transifex. See The [community-templates](https://github.com/theforeman/community-templates.git) repo is the source for our job templates. Prior to release, use the script/sync_templates.sh script to pull in any changes. +### Release changes are available in [release notes](release_notes.md) ## Copyright diff --git a/rel-eng/gem_release.ipynb b/rel-eng/gem_release.ipynb new file mode 100644 index 000000000..0972da5fd --- /dev/null +++ b/rel-eng/gem_release.ipynb @@ -0,0 +1,457 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Release of foreman_remote_execution gem\n", + "\n", + "### Prerequisites\n", + "- Python 3\n", + "\n", + "If you use Visual Studio Code, you should be all set.\n", + "- Jupyter: pip install jupyter\n", + "\n", + "### Requirements\n", + "- push access to https://github.com/theforeman/foreman_remote_execution\n", + "- push access to rubygems.org for foreman_remote_execution\n", + "- sudo yum install python3-slugify asciidoc\n", + "- install Transifex client: curl -o- https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash\n", + "- ensure neither the `git push` or `gem push` don't require interractive auth. If you can't use api key or ssh key to auth skip these steps and run them from the shell manually \n", + "- to push translations you need an account on Transifex (https://docs.transifex.com/client/client-configuration#~/-transifexrc)\n", + "\n", + "### Release process\n", + "Beware of the security risks envolved - access to jupyter notebook means unrestricted access to the shell as the user who runs the Jupyter.\n", + "- If you use Visual Studio Code, simply open this file and proceed with the steps\n", + "- If you don't use Visual Studio Code, run the server:\n", + " - jupyter notebook rel-eng/gem_release.ipynb (within virtual machine, use jupyter notebook --ip 0.0.0.0 rel-eng/gem_release.ipynb)\n", + "- Follow the steps with `+` or `+,`\n", + "- If anything fails, fix it and re-run the step if applicable\n", + "\n", + "### Release settings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%cd ..\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Update the following notebook settings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "NEW_VERSION = '12.0.0'\n", + "LAST_VERSION = '11.1.1'\n", + "NEXT_FUTURE_VERSION = '12.1.0'\n", + "MAJOR_RELEASE = True # Change to False if you're releasing z version for X.Y.z\n", + "STABLE_BRANCH = '12.0.z'\n", + "GIT_REMOTE_UPSTREAM = 'upstream'\n", + "WORK_BRANCH = 'master' if MAJOR_RELEASE else STABLE_BRANCH\n", + "CHERRY_PICKS = [] # Comma-separated strings of hashes of commits needed for CP\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ensure the repo is up to date" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! git checkout {WORK_BRANCH}\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! git fetch {GIT_REMOTE_UPSTREAM}\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! git rebase {GIT_REMOTE_UPSTREAM}/{WORK_BRANCH}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Cherry picks for minor release" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if not MAJOR_RELEASE:\n", + " for cp in CHERRY_PICKS:\n", + " ! git cherry-pick -x {cp}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Update release related stuff" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! sed -i 's/VERSION = .*/VERSION = \"{NEW_VERSION}\".freeze/' lib/foreman_remote_execution/version.rb\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Parse git changelog\n", + "from IPython.display import Markdown as md\n", + "from subprocess import check_output\n", + "from shlex import split\n", + "import re\n", + "\n", + "def format_log_entry(entry):\n", + " issues = re.findall(r'[^(]#([0-9]+)', entry)\n", + " entry = re.sub(r'([fF]ixes|[rR]efs)[^-]*-\\s*(.*)', r'\\2', entry)\n", + " entry = '* ' + entry.capitalize()\n", + " entry = re.sub(r'\\(#([0-9]+)\\)', r'([PR #\\1](https://github.com/theforeman/foreman_remote_execution/pull/\\1))', entry)\n", + " for i in issues:\n", + " referenced_issues.append(i)\n", + " entry = entry + ', [#%s](http://projects.theforeman.org/issues/%s)' % (i, i)\n", + " return entry\n", + "\n", + "def skip(entry):\n", + " if re.match(r'Merge pull', entry) or \\\n", + " re.match(r'^i18n', entry) or \\\n", + " re.match(r'^Bump version to', entry):\n", + " return True\n", + " else:\n", + " return False\n", + "referenced_issues = []\n", + "git_log_cmd = 'git log --pretty=format:\"%%s\" v%s..HEAD' % LAST_VERSION\n", + "log = check_output(split(git_log_cmd)).decode('utf8').split('\\n')\n", + "change_log = [format_log_entry(e) for e in log if not skip(e)]\n", + "md('\\n'.join(change_log))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Write release notes\n", + "from datetime import datetime\n", + "import fileinput\n", + "import sys\n", + "\n", + "fh = fileinput.input('release_notes.md', inplace=True)\n", + "for line in fh:\n", + " print(line.rstrip())\n", + " if re.match(r'========', line):\n", + " print('### %s (%s)' % (NEW_VERSION, datetime.today().strftime('%Y-%m-%d')))\n", + " for entry in change_log:\n", + " print(entry)\n", + " print('')\n", + "fh.close()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Manual step: Update deps in the gemspec if neccessary" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check what is going to be commited" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "! git add -u\n", + "! git status\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "! git diff --cached\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Commit changes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "! git commit -m \"Bump version to {NEW_VERSION}\"\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Update translations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if MAJOR_RELEASE:\n", + " ! make -C locale/ tx-update\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if MAJOR_RELEASE:\n", + " %cd ../foreman\n", + " ! bundle install\n", + " ! bundle exec rake plugin:gettext[foreman_remote_execution]\n", + " ! bundle exec rake plugin:po_to_json[foreman_remote_execution]\n", + " %cd ../foreman_remote_execution\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if MAJOR_RELEASE:\n", + " ! make -C locale/ mo-files\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Tag new version" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! git tag v{NEW_VERSION}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Prepare stable branch for major release" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if MAJOR_RELEASE:\n", + " ! git checkout -b {STABLE_BRANCH}\n", + " ! git push {GIT_REMOTE_UPSTREAM} {STABLE_BRANCH}\n", + " ! git checkout {WORK_BRANCH}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Build the gem" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! bundle exec rake build\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! gem push pkg/foreman_remote_execution-{NEW_VERSION}.gem\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### PUSH the changes upstream If everything is correct" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! git push {GIT_REMOTE_UPSTREAM} {WORK_BRANCH}\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! git push --tags {GIT_REMOTE_UPSTREAM} {WORK_BRANCH}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Now the new release is in upstream repo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Some manual steps follow to improve the UX\n", + "\n", + "#### New relase on GitHub\n", + "\n", + "Copy the following changelog lines to the description in form on link below\n", + "The release title is the new version." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print('\\n')\n", + "print('\\n'.join(change_log))\n", + "print('\\n\\nhttps://github.com/theforeman/foreman_remote_execution/releases/new?tag=v%s' % NEW_VERSION)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import Markdown as md\n", + "\n", + "md('### Create new foreman_remote_execution release in Redmine \\n' + \\\n", + " 'https://projects.theforeman.org/projects/foreman_remote_execution/versions/new\\n\\n' + \\\n", + " 'Set name to foreman_remote_execution-%s' % (NEXT_FUTURE_VERSION if MAJOR_RELEASE else NEW_VERSION))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if not MAJOR_RELEASE:\n", + " print('Set fixed in versions to %s in following issues:' % NEW_VERSION)\n", + " for i in referenced_issues:\n", + " print('- https://projects.theforeman.org/issues/%s' % i)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Congratulations\n", + "\n", + "Release is public now. Please, don't forget to do packaging (https://github.com/theforeman/foreman-packaging)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.9.16" + }, + "vscode": { + "interpreter": { + "hash": "e55666fbbf217aa3df372b978577f47b6009e2f78e2ec76a584f49cd54a1e62c" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/release_notes.md b/release_notes.md new file mode 100644 index 000000000..dbbd9c502 --- /dev/null +++ b/release_notes.md @@ -0,0 +1 @@ +========