mirror of
https://github.com/certbot/certbot.git
synced 2026-06-03 22:08:07 -04:00
Add Signed Windows Installer Workflow (#9076)
* Add Code Signing action for Windows Installer * Clean up variable names and input * Amend and add to documentation per PR guidelines * Update tools/finish_release.py Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update tools/finish_release.py Amend typo Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Amend release script for better work flow - SCP commands to upload and download unsigned & signed installers from CSS * Collapse spaces * Update tools/finish_release.py Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Create new windows signer function * Update Windows Installer Script - Update change log - add new function for signing and document - @TODO Streammline SSH session * Remove Azure and Github release methods - Methods moved to CSS - Reduced to a ssh function that triggers the process on a CSS * Amend Chnagelog and Remove Unneeded Deps * Update tools/finish_release.py Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Add Verison Fetch Function - For the purpose of snap releases - Add back package to dev extras for function * Chaneg path in ssh command * Amend release script * Amend the ssh command for CSS * Update tools/finish_release.py Co-authored-by: Brad Warren <bmw@users.noreply.github.com> * Update script with proper path and subprocess call * Update ssh command * Correct typo in path * Fix typo in path * Update certbot/CHANGELOG.md Co-authored-by: ohemorange <ebportnoy@gmail.com> * Remove missed conflict text Co-authored-by: Brad Warren <bmw@users.noreply.github.com> Co-authored-by: ohemorange <ebportnoy@gmail.com>
This commit is contained in:
parent
dedbdea1d9
commit
6e1696ba32
4 changed files with 43 additions and 76 deletions
|
|
@ -17,6 +17,7 @@ Authors
|
|||
* [Alex Halderman](https://github.com/jhalderm)
|
||||
* [Alex Jordan](https://github.com/strugee)
|
||||
* [Alex Zorin](https://github.com/alexzorin)
|
||||
* [Alexis Hancock](https://github.com/zoracon)
|
||||
* [Amir Omidi](https://github.com/aaomidi)
|
||||
* [Amjad Mashaal](https://github.com/TheNavigat)
|
||||
* [amplifi](https://github.com/amplifi)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
|
|||
|
||||
### Added
|
||||
|
||||
*
|
||||
* Updated Windows installer to be signed and trusted in Windows
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
@ -28,6 +28,7 @@ More details about these changes can be found on our GitHub repo.
|
|||
|
||||
* Updated Apache/NGINX TLS configs to document contents are based on ssl-config.mozilla.org
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
* A change to order finalization has been made to the `acme` module and Certbot:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ install_requires = [
|
|||
dev_extras = [
|
||||
'azure-devops',
|
||||
'ipdb',
|
||||
'PyGithub',
|
||||
# poetry 1.2.0+ is required for it to pin pip, setuptools, and wheel. See
|
||||
# https://github.com/python-poetry/poetry/issues/1584.
|
||||
'poetry>=1.2.0a1',
|
||||
|
|
|
|||
|
|
@ -8,17 +8,13 @@ This currently includes:
|
|||
* Publishing the Windows installer in a GitHub release
|
||||
|
||||
Setup:
|
||||
- Create a github personal access token
|
||||
- https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token#creating-a-token
|
||||
- You'll need repo scope
|
||||
- Save the token to somewhere like ~/.ssh/githubpat.txt
|
||||
- Install the snapcraft command line tool and log in to a privileged account.
|
||||
- https://snapcraft.io/docs/installing-snapcraft
|
||||
- Use the command `snapcraft login` to log in.
|
||||
|
||||
Run:
|
||||
|
||||
python tools/finish_release.py ~/.ssh/githubpat.txt
|
||||
python tools/finish_release.py --css <URL of code signing server>
|
||||
|
||||
Testing:
|
||||
|
||||
|
|
@ -36,10 +32,10 @@ import re
|
|||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import getpass
|
||||
from azure.devops.connection import Connection
|
||||
from zipfile import ZipFile
|
||||
|
||||
from azure.devops.connection import Connection
|
||||
from github import Github
|
||||
import requests
|
||||
|
||||
# Path to the root directory of the Certbot repository containing this script
|
||||
|
|
@ -68,7 +64,7 @@ def parse_args(args):
|
|||
# Use the file's docstring for the help text and don't let argparse reformat it.
|
||||
parser = argparse.ArgumentParser(description=__doc__,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument('githubpat', help='path to your GitHub personal access token')
|
||||
parser.add_argument('--css', type=str, required=True, help='hostname of code signing server')
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
# We use 'store_false' and a destination related to the other type of
|
||||
# artifact to cause the flag being set to disable publishing of the other
|
||||
|
|
@ -80,63 +76,19 @@ def parse_args(args):
|
|||
help='Skip publishing other artifacts and only publish the Windows installer')
|
||||
return parser.parse_args(args)
|
||||
|
||||
|
||||
def publish_windows(css):
|
||||
"""SSH into CSS and trigger downloading Azure Pipeline assets, sign, and upload to Github
|
||||
|
||||
def download_azure_artifacts(tempdir):
|
||||
"""Download and unzip build artifacts from Azure pipelines.
|
||||
|
||||
:param str path: path to a temporary directory to save the files
|
||||
|
||||
:returns: released certbot version number as a prefix-free string
|
||||
:rtype: str
|
||||
:param str css: CSS host name
|
||||
|
||||
"""
|
||||
# Create a connection to the azure org
|
||||
organization_url = 'https://dev.azure.com/certbot'
|
||||
connection = Connection(base_url=organization_url)
|
||||
|
||||
# Find the build artifacts
|
||||
build_client = connection.clients.get_build_client()
|
||||
get_builds_response = build_client.get_builds('certbot', definitions='3')
|
||||
build_id = get_builds_response.value[0].id
|
||||
artifacts = build_client.get_artifacts('certbot', build_id)
|
||||
|
||||
# Save and unzip files
|
||||
for filename in ('windows-installer', 'changelog'):
|
||||
print("Downloading artifact %s" % filename)
|
||||
url = build_client.get_artifact('certbot', build_id, filename).resource.download_url
|
||||
r = requests.get(url)
|
||||
r.raise_for_status()
|
||||
with open(tempdir + '/' + filename + '.zip', 'wb') as f:
|
||||
f.write(r.content)
|
||||
print("Extracting %s" % filename)
|
||||
with ZipFile(tempdir + '/' + filename + '.zip', 'r') as zipObj:
|
||||
zipObj.extractall(tempdir)
|
||||
|
||||
version = build_client.get_build('certbot', build_id).source_branch.split('v')[1]
|
||||
return version
|
||||
|
||||
def create_github_release(github_access_token, tempdir, version):
|
||||
"""Use build artifacts to create a github release, including uploading additional assets
|
||||
|
||||
:param str github_access_token: string containing github access token
|
||||
:param str path: path to a temporary directory where azure artifacts are located
|
||||
:param str version: Certbot version number, e.g. 1.7.0
|
||||
|
||||
"""
|
||||
# Create release
|
||||
g = Github(github_access_token)
|
||||
repo = g.get_user('certbot').get_repo('certbot')
|
||||
release_notes = open(tempdir + '/changelog/release_notes.md', 'r').read()
|
||||
print("Creating git release")
|
||||
release= repo.create_git_release('v{0}'.format(version),
|
||||
'Certbot {0}'.format(version),
|
||||
release_notes,
|
||||
draft=True)
|
||||
|
||||
# Upload windows installer to release
|
||||
print("Uploading windows installer")
|
||||
release.upload_asset(tempdir + '/windows-installer/certbot-beta-installer-win_amd64.exe')
|
||||
release.update_release(release.title, release.body, draft=False)
|
||||
username = getpass.getuser()
|
||||
host = css
|
||||
command = "ssh -t {}@{} bash /opt/certbot-misc/css/venv.sh".format(username,host)
|
||||
|
||||
print("SSH into CSS to trigger signing and uploading of Windows installer...")
|
||||
subprocess.run(command, check=True, universal_newlines=True, shell=True)
|
||||
|
||||
|
||||
def assert_logged_into_snapcraft():
|
||||
|
|
@ -216,23 +168,37 @@ def promote_snaps(version):
|
|||
print(e.stdout)
|
||||
raise
|
||||
|
||||
def fetch_version_number():
|
||||
"""Retrieve version number for release from Azure Pipelines
|
||||
|
||||
:returns: version number
|
||||
|
||||
"""
|
||||
# Create a connection to the azure org
|
||||
organization_url = 'https://dev.azure.com/certbot'
|
||||
connection = Connection(base_url=organization_url)
|
||||
|
||||
# Find the build artifacts
|
||||
build_client = connection.clients.get_build_client()
|
||||
get_builds_response = build_client.get_builds('certbot', definitions='3')
|
||||
build_id = get_builds_response.value[0].id
|
||||
version = build_client.get_build('certbot', build_id).source_branch.split('v')[1]
|
||||
return version
|
||||
|
||||
def main(args):
|
||||
parsed_args = parse_args(args)
|
||||
|
||||
github_access_token_file = parsed_args.githubpat
|
||||
github_access_token = open(github_access_token_file, 'r').read().rstrip()
|
||||
css = parsed_args.css
|
||||
version = fetch_version_number()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tempdir:
|
||||
version = download_azure_artifacts(tempdir)
|
||||
# Once the GitHub release has been published, trying to publish it
|
||||
# again fails. Publishing the snaps can be done multiple times though
|
||||
# so we do that first to make it easier to run the script again later
|
||||
# if something goes wrong.
|
||||
if parsed_args.publish_snaps:
|
||||
promote_snaps(version)
|
||||
if parsed_args.publish_windows:
|
||||
create_github_release(github_access_token, tempdir, version)
|
||||
# Once the GitHub release has been published, trying to publish it
|
||||
# again fails. Publishing the snaps can be done multiple times though
|
||||
# so we do that first to make it easier to run the script again later
|
||||
# if something goes wrong.
|
||||
if parsed_args.publish_snaps:
|
||||
promote_snaps(version)
|
||||
if parsed_args.publish_windows:
|
||||
publish_windows(css)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
|
|
|||
Loading…
Reference in a new issue