mirror of
https://github.com/certbot/certbot.git
synced 2026-08-04 12:21:51 +02:00
Create a new CI for Certbot on Windows using Azure Pipelines (#7377)
This PR defines pipelines that can be run on Azure Pipelines. Currently there are two: * `.azure-pipelines/main.yml` is the main one, executed on PRs for master, and pushes to master, * `.azure-pipelines/advanced.yml` add installer testing on top of the main pipeline, and is executed for `test-*` branches, release branches, and nightly run for master. These two pipelines covers all existing stuff done by AppVeyor currently, and so AppVeyor can be decommissioned once Azure Pipelines is operational. You can see working pipeline in my fork: * a PR for `master` (so using main pipeline): https://github.com/adferrand/certbot/pull/65 * a PR for `test-something` (so using advanced pipeline): https://github.com/adferrand/certbot/pull/66 * uploaded coverage from Azure Pipelines: https://codecov.io/gh/adferrand/certbot/commit/499aa2cbf25e1e0ab4c93ab64057db92dfec0fba/build Once this PR is merged, we need to enable Azure Pipelines for Certbot. Instructions are written in `azure-pipelines/INSTALL.md`. This document also references all access rights required to Azure Pipelines onto GitHub to make the CI process work. Future work for future PRs: * create a CD pipeline for the releases that will push the installer to GitHub releases * implement a solution to generate notification on IRC or Mattermost when a nightly build fails * Define pipelines * Update locations * Update nightly * Use x86 * Update nightly.yml for Azure Pipelines * Run script * Use script * Update install * Use local installation * Register warnings * Fix pywin32 loading * Clean context * Enable coverage publication * Consume codecov token * Document installation * Update tool to upload coverage * Prepare pipeline artifacts * Update artifact ignore * Protect against codecov failures * Add a comment about codecov * Add a comment on RW access asked by Azure * Add instructions * Rename pipeline file * Update instructions * Update .azure-pipelines/templates/tests-suite.yml Co-Authored-By: Brad Warren <bmw@users.noreply.github.com> * Update .azure-pipelines/INSTALL.md Co-Authored-By: Brad Warren <bmw@users.noreply.github.com> * Modified scheduled pipeline * Add comment * Remove dynamic version-based installer name
This commit is contained in:
committed by
Brad Warren
co-authored by
Brad Warren
parent
9da07590bd
commit
fcc398831b
@@ -0,0 +1,117 @@
|
||||
# Configuring Azure Pipelines with Certbot
|
||||
|
||||
Let's begin. All pipelines are defined in `.azure-pipelines`. Currently there are two:
|
||||
* `.azure-pipelines/main.yml` is the main one, executed on PRs for master, and pushes to master,
|
||||
* `.azure-pipelines/advanced.yml` add installer testing on top of the main pipeline, and is executed for `test-*` branches, release branches, and nightly run for master.
|
||||
|
||||
Several templates are defined in `.azure-pipelines/templates`. These YAML files aggregate common jobs configuration that can be reused in several pipelines.
|
||||
|
||||
Unlike Travis, where CodeCov is working without any action required, CodeCov supports Azure Pipelines
|
||||
using the coverage-bash utility (not python-coverage for now) only if you provide the Codecov repo token
|
||||
using the `CODECOV_TOKEN` environment variable. So `CODECOV_TOKEN` needs to be set as a secured
|
||||
environment variable to allow the main pipeline to publish coverage reports to CodeCov.
|
||||
|
||||
This INSTALL.md file explains how to configure Azure Pipelines with Certbot in order to execute the CI/CD logic defined in `.azure-pipelines` folder with it.
|
||||
During this installation step, warnings describing user access and legal comitments will be displayed like this:
|
||||
```
|
||||
!!! ACCESS REQUIRED !!!
|
||||
```
|
||||
|
||||
This document suppose that the Azure DevOps organization is named _certbot_, and the Azure DevOps project is also _certbot_.
|
||||
|
||||
## Useful links
|
||||
|
||||
* https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema
|
||||
* https://www.azuredevopslabs.com/labs/azuredevops/github-integration/
|
||||
* https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/python?view=azure-devops
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Having a GitHub account
|
||||
|
||||
Use your GitHub user for a normal GitHub account, or a user that has administrative rights to the GitHub organization if relevant.
|
||||
|
||||
### Having an Azure DevOps account
|
||||
- Go to https://dev.azure.com/, click "Start free with GitHub"
|
||||
- Login to GitHub
|
||||
|
||||
```
|
||||
!!! ACCESS REQUIRED !!!
|
||||
Personal user data (email + profile info, in read-only)
|
||||
```
|
||||
|
||||
- Microsoft will create a Live account using the email referenced for the GitHub account. This account is also linked to GitHub account (meaning you can log it using GitHub authentication)
|
||||
- Proceed with account registration (birth date, country), add details about name and email contact
|
||||
|
||||
```
|
||||
!!! ACCESS REQUIRED !!!
|
||||
Microsoft proposes to send commercial links to this mail
|
||||
Azure DevOps terms of service need to be accepted
|
||||
```
|
||||
|
||||
_Logged to Azure DevOps, account is ready._
|
||||
|
||||
### Installing Azure Pipelines to GitHub
|
||||
|
||||
- On GitHub, go to Marketplace
|
||||
- Select Azure Pipeline, and "Set up a plan"
|
||||
- Select Free, then "Install it for free"
|
||||
- Click "Complete order and begin installation"
|
||||
|
||||
```
|
||||
!!! ACCESS !!!
|
||||
Azure Pipeline needs RW on code, RO on metadata, RW on checks, commit statuses, deployments, issues, pull requests.
|
||||
RW access here is required to allow update of the pipelines YAML files from Azure DevOps interface, and to
|
||||
update the status of builds and PRs on GitHub side when Azure Pipelines are triggered.
|
||||
Note however that no admin access is defined here: this means that Azure Pipelines cannot do anything with
|
||||
protected branches, like master, and cannot modify the security context around this on GitHub.
|
||||
Access can be defined for all or only selected repositories, which is nice.
|
||||
```
|
||||
|
||||
- Redirected to Azure DevOps, select the account created in _Having an Azure DevOps account_ section.
|
||||
- Select the organization, and click "Create a new project" (let's name it the same than the targetted github repo)
|
||||
- The Visibility is public, to profit from 10 parallel jobs
|
||||
|
||||
```
|
||||
!!! ACCESS !!!
|
||||
Azure Pipelines needs access to the GitHub account (in term of beeing able to check it is valid), and the Resources shared between the GitHub account and Azure Pipelines.
|
||||
```
|
||||
|
||||
_Done. We can move to pipelines configuration._
|
||||
|
||||
## Import an existing pipelines from `.azure-pipelines` folder
|
||||
|
||||
- On Azure DevOps, go to your organization (eg. _certbot_) then your project (eg. _certbot_)
|
||||
- Click "Pipelines" tab
|
||||
- Click "New pipeline"
|
||||
- Where is your code?: select "__Use the classic editor__"
|
||||
|
||||
__Warning: Do not choose the GitHub option in Where is your code? section. Indeed, this option will trigger an OAuth
|
||||
grant permissions from Azure Pipelines to GitHub in order to setup a GitHub OAuth Application. The permissions asked
|
||||
then are way too large (admin level on almost everything), while the classic approach does not add any more
|
||||
permissions, and works perfectly well.__
|
||||
|
||||
- Select GitHub in "Select your repository section", choose certbot/certbot in Repository, master in default branch.
|
||||
- Click on YAML option for "Select a template"
|
||||
- Choose a name for the pipeline (eg. test-pipeline), and browse to the actual pipeline YAML definition in the
|
||||
"YAML file path" input (eg. `.azure-pipelines/test-pipeline.yml`)
|
||||
- Click "Save & queue", choose the master branch to build the first pipeline, and click "Save and run" button.
|
||||
|
||||
_Done. Pipeline is operational. Repeat to add more pipelines from existing YAML files in `.azure-pipelines`._
|
||||
|
||||
## Add a secret variable to a pipeline (like `CODECOV_TOKEN`)
|
||||
|
||||
__NB: Following steps suppose that you already setup the YAML pipeline file to
|
||||
consume the secret variable that these steps will create as an environment variable.
|
||||
For a variable named `CODECOV_TOKEN` consuming the variable `codecov_token`,
|
||||
in the YAML file this setup would take the form of the following:
|
||||
```
|
||||
steps:
|
||||
- script: ./do_something_that_consumes_CODECOV_TOKEN # Eg. `codecov -F windows`
|
||||
env:
|
||||
CODECOV_TOKEN: $(codecov_token)
|
||||
```
|
||||
|
||||
- On Azure DevOps, go to you organization, project, pipeline tab
|
||||
- Select the pipeline, click "Edit" button, then click "Variables" button
|
||||
- Set name (eg `codecov_token`), value, tick "Keep this value secret"
|
||||
@@ -0,0 +1,18 @@
|
||||
# Advanced pipeline for isolated checks and release purpose
|
||||
trigger:
|
||||
- test-*
|
||||
- '*.x'
|
||||
pr:
|
||||
- test-*
|
||||
- '*.x'
|
||||
# This pipeline is also nightly run on master
|
||||
schedules:
|
||||
- cron: "4 0 * * *"
|
||||
displayName: Nightly build
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
- template: templates/tests-suite.yml
|
||||
- template: templates/installer-tests.yml
|
||||
@@ -0,0 +1,11 @@
|
||||
trigger:
|
||||
# apache-parser-v2 is a temporary branch for doing work related to
|
||||
# rewriting the parser in the Apache plugin.
|
||||
- apache-parser-v2
|
||||
- master
|
||||
pr:
|
||||
- apache-parser-v2
|
||||
- master
|
||||
|
||||
jobs:
|
||||
- template: templates/tests-suite.yml
|
||||
@@ -0,0 +1,31 @@
|
||||
jobs:
|
||||
- job: installer
|
||||
pool:
|
||||
vmImage: vs2017-win2016
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: 3.7
|
||||
architecture: x86
|
||||
addToPath: true
|
||||
- script: python windows-installer/construct.py
|
||||
displayName: Build Certbot installer
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
sourceFolder: $(System.DefaultWorkingDirectory)/windows-installer/build/nsis
|
||||
contents: '*.exe'
|
||||
targetFolder: $(Build.ArtifactStagingDirectory)
|
||||
- task: PublishPipelineArtifact@1
|
||||
inputs:
|
||||
path: $(Build.ArtifactStagingDirectory)
|
||||
artifact: WindowsInstaller
|
||||
- script: $(Build.ArtifactStagingDirectory)\certbot-installer-win32.exe /S
|
||||
displayName: Install Certbot
|
||||
- script: |
|
||||
python -m venv venv
|
||||
venv\Scripts\python tools\pip_install.py -e certbot-ci
|
||||
displayName: Prepare Certbot-CI
|
||||
- script: |
|
||||
set PATH=%ProgramFiles(x86)%\Certbot\bin;%PATH%
|
||||
venv\Scripts\python -m pytest certbot-ci\certbot_integration_tests\certbot_tests -n 4
|
||||
displayName: Run integration tests
|
||||
@@ -0,0 +1,36 @@
|
||||
jobs:
|
||||
- job: test
|
||||
pool:
|
||||
vmImage: vs2017-win2016
|
||||
strategy:
|
||||
matrix:
|
||||
py35:
|
||||
PYTHON_VERSION: 3.5
|
||||
TOXENV: py35
|
||||
py37-cover:
|
||||
PYTHON_VERSION: 3.7
|
||||
TOXENV: py37-cover
|
||||
integration-certbot:
|
||||
PYTHON_VERSION: 3.7
|
||||
TOXENV: integration-certbot
|
||||
PYTEST_ADDOPTS: --numprocesses 4
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: $(PYTHON_VERSION)
|
||||
addToPath: true
|
||||
- script: python tools/pip_install.py -U tox coverage
|
||||
displayName: Install dependencies
|
||||
- script: python -m tox
|
||||
displayName: Run tox
|
||||
# We do not require codecov report upload to succeed. So to avoid to break the pipeline if
|
||||
# something goes wrong, each command is suffixed with a command that hides any non zero exit
|
||||
# codes and echoes an informative message instead.
|
||||
- bash: |
|
||||
curl -s https://codecov.io/bash -o codecov-bash || echo "Failed to download codecov-bash"
|
||||
chmod +x codecov-bash || echo "Failed to apply execute permissions on codecov-bash"
|
||||
./codecov-bash -F windows || echo "Codecov did not collect coverage reports"
|
||||
condition: eq(variables['TOXENV'], 'py37-cover')
|
||||
env:
|
||||
CODECOV_TOKEN: $(codecov_token)
|
||||
displayName: Publish coverage
|
||||
@@ -70,13 +70,39 @@ def _copy_assets(build_path, repo_path):
|
||||
def _generate_pynsist_config(repo_path, build_path):
|
||||
print('Generate pynsist configuration')
|
||||
|
||||
pywin32_paths_file = os.path.join(build_path, 'pywin32_paths.py')
|
||||
|
||||
# Pywin32 uses non-standard folders to hold its packages. We need to instruct pynsist bootstrap
|
||||
# explicitly to add them into sys.path. This is done with a custom "pywin32_paths.py" that is
|
||||
# referred in the pynsist configuration as an "extra_preamble".
|
||||
# Reference example: https://github.com/takluyver/pynsist/tree/master/examples/pywebview
|
||||
with open(pywin32_paths_file, 'w') as file_h:
|
||||
file_h.write('''\
|
||||
pkgdir = os.path.join(os.path.dirname(installdir), 'pkgs')
|
||||
|
||||
sys.path.extend([
|
||||
os.path.join(pkgdir, 'win32'),
|
||||
os.path.join(pkgdir, 'win32', 'lib'),
|
||||
])
|
||||
|
||||
# Preload pywintypes and pythoncom
|
||||
pwt = os.path.join(pkgdir, 'pywin32_system32', 'pywintypes{0}{1}.dll')
|
||||
pcom = os.path.join(pkgdir, 'pywin32_system32', 'pythoncom{0}{1}.dll')
|
||||
import warnings
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
import imp
|
||||
imp.load_dynamic('pywintypes', pwt)
|
||||
imp.load_dynamic('pythoncom', pcom)
|
||||
'''.format(PYTHON_VERSION[0], PYTHON_VERSION[1]))
|
||||
|
||||
installer_cfg_path = os.path.join(build_path, 'installer.cfg')
|
||||
|
||||
certbot_version = subprocess.check_output([sys.executable, '-c', 'import certbot; print(certbot.__version__)'],
|
||||
universal_newlines=True, cwd=repo_path).strip()
|
||||
|
||||
with open(os.path.join(installer_cfg_path), 'w') as file_h:
|
||||
file_h.write("""\
|
||||
with open(installer_cfg_path, 'w') as file_h:
|
||||
file_h.write('''\
|
||||
[Application]
|
||||
name=Certbot
|
||||
version={certbot_version}
|
||||
@@ -87,7 +113,7 @@ target=$INSTDIR\\run.bat
|
||||
[Build]
|
||||
directory=nsis
|
||||
nsi_template=template.nsi
|
||||
installer_name=certbot-{certbot_version}-installer-{installer_suffix}.exe
|
||||
installer_name=certbot-installer-{installer_suffix}.exe
|
||||
|
||||
[Python]
|
||||
version={python_version}
|
||||
@@ -101,7 +127,8 @@ files=run.bat
|
||||
|
||||
[Command certbot]
|
||||
entry_point=certbot.main:main
|
||||
""".format(certbot_version=certbot_version,
|
||||
extra_preamble=pywin32_paths.py
|
||||
'''.format(certbot_version=certbot_version,
|
||||
installer_suffix='win_amd64' if PYTHON_BITNESS == 64 else 'win32',
|
||||
python_bitness=PYTHON_BITNESS,
|
||||
python_version='.'.join([str(item) for item in PYTHON_VERSION])))
|
||||
|
||||
Reference in New Issue
Block a user