Update ensure-twine role

Install twine into a venv and set appropriate environment
variables. Also added tests.

Based on commit adding `ensure-nox` (77b1b24) role.

Related-bug: #2095514
Change-Id: Ibb4e89f79879b4d0ae0294440c9c0b79fc57a7fa
This commit is contained in:
Brian Haley 2025-01-23 16:21:47 -05:00
parent 80e9153564
commit 84082ed982
5 changed files with 174 additions and 25 deletions

View File

@ -1,27 +1,42 @@
Ensure twine is installed.
This role is designed to run without permissions, so assumes a working
Python 3 ``pip`` environment (i.e. it will not install system
packages).
Look for ``twine``, and if not found, install it via ``pip`` into a
virtual environment for the current user.
**Role Variables**
.. zuul:rolevar:: twine_python
:default: python
.. zuul:rolevar:: ensure_twine_version
:default: ''
The python interpreter to use to install twine if it is not already
installed. Set it to "python3" to use python 3, for example.
Version specifier to select the version of Twine. The default is the
latest version.
.. zuul:rolevar:: ensure_twine_venv_path
:default: {{ ansible_user_dir }}/.local/twine
Directory for the Python venv where Twine will be installed.
.. zuul:rolevar:: ensure_twine_global_symlink
:default: False
Install a symlink to the twine executable into ``/usr/local/bin/twine``.
This can be useful when scripts need to be run that expect to find
Twine in a more standard location and plumbing through the value
of ``pypi_twine_executable`` would be onerous.
Setting this requires root access, so should only be done in
circumstances where root access is available.
**Output Variables**
.. zuul:rolevar:: twine_excutable
.. zuul:rolevar:: pypi_twine_executable
:default: twine
After running this role, ``twine_executable`` will be set as the path
After running this role, ``pypi_twine_executable`` will be set as the path
to a valid ``twine``.
At role runtime, look for an existing ``twine`` at this specific
path. Note the default (``twine``) effectively means to find tox in
path. Note the default (``twine``) effectively means to find twine in
the current ``$PATH``. For example, if your base image
pre-installs twine in an out-of-path environment, set this so the
role does not attempt to install the user version.

View File

@ -1,3 +1,5 @@
---
twine_python: python3
twine_executable: twine
ensure_twine_global_symlink: false
# version 6.1.0 is breaking test-release-openstack CI job
ensure_twine_version: ">1.12.0,!=6.1.0"
pypi_twine_executable: twine
ensure_twine_venv_path: "{{ ansible_user_dir }}/.local/twine"

View File

@ -1,22 +1,44 @@
- name: Check for twine install
- name: Install pip
include_role:
name: ensure-pip
- name: Check if twine is installed
shell: |
command -v {{ twine_executable }} ~/.local/bin/twine || exit 1
command -v {{ pypi_twine_executable }} {{ ensure_twine_venv_path }}/bin/twine || exit 1
args:
executable: /bin/bash
register: twine_preinstalled
failed_when: false
register: register_twine
- name: Set pypi_twine_executable
- name: Export preinstalled pypi_twine_executable
set_fact:
pypi_twine_executable: "{{ register_twine.stdout_lines[0] }}"
when: register_twine.rc == 0
pypi_twine_executable: "{{ twine_preinstalled.stdout_lines[0] }}"
cacheable: true
when: twine_preinstalled.rc == 0
- name: Ensure twine is installed
when: register_twine.rc != 0
- name: Install twine to local env
when: twine_preinstalled.rc != 0
block:
- name: Ensure twine is installed
command: "{{ twine_python }} -m pip install twine!=1.12.0,!=6.1.0 requests-toolbelt!=0.9.0 --user"
- name: Create local venv
command: "{{ ensure_pip_virtualenv_command }} {{ ensure_twine_venv_path }}"
- name: Set pypi_twine_executable
- name: Install twine to local venv
command: "{{ ensure_twine_venv_path }}/bin/pip install twine{{ ensure_twine_version }}"
- name: Export installed pypi_twine_executable path
set_fact:
pypi_twine_executable: ~/.local/bin/twine
pypi_twine_executable: "{{ ensure_twine_venv_path }}/bin/twine"
cacheable: true
- name: Output twine version
command: "{{ pypi_twine_executable }} --version"
- name: Make global symlink
when:
- ensure_twine_global_symlink
- pypi_twine_executable != '/usr/local/bin/twine'
file:
state: link
src: "{{ pypi_twine_executable }}"
dest: /usr/local/bin/twine
become: yes

View File

@ -0,0 +1,35 @@
- hosts: all
name: Test ensure-twine installs into user environment
tasks:
- name: Verify twine is not installed
command: "twine --version"
register: result
failed_when: result.rc == 0
- name: Run ensure-twine with twine not installed
include_role:
name: ensure-twine
- name: Verify pypi_twine_executable is set
assert:
that:
- pypi_twine_executable == ansible_user_dir + '/.local/twine/bin/twine'
- name: Verify twine is installed
command: "{{ pypi_twine_executable }} --version"
register: result
failed_when: result.rc != 0
- hosts: all
name: Test ensure-twine when pypi_twine_executable is set to an already installed twine
tasks:
- name: Create a virtualenv
command: '{{ ensure_pip_virtualenv_command }} {{ ansible_user_dir }}/twine-venv'
- name: Install twine to local venv
command: '{{ ansible_user_dir }}/twine-venv/bin/pip install twine'
- name: Run ensure-twine pointing to an already installed twine
include_role:
name: ensure-twine
vars:
pypi_twine_executable: "{{ ansible_user_dir }}/twine-venv/bin/twine"
- name: Verify pypi_twine_executable is set to the virtualenv twine
assert:
that:
- pypi_twine_executable == ansible_user_dir + '/twine-venv/bin/twine'

View File

@ -282,6 +282,75 @@
- name: ubuntu-noble
label: ubuntu-noble
- job:
name: zuul-jobs-test-ensure-twine
description: Test the ensure-twine role
files:
- roles/ensure-twine/.*
- test-playbooks/ensure-twine.yaml
run: test-playbooks/ensure-twine.yaml
tags: all-platforms
- job:
name: zuul-jobs-test-ensure-twine-centos-9-stream
description: Test the ensure-twine role on centos-9-stream
parent: zuul-jobs-test-ensure-twine
tags: auto-generated
nodeset:
nodes:
- name: centos-9-stream
label: centos-9-stream
- job:
name: zuul-jobs-test-ensure-twine-debian-bookworm
description: Test the ensure-twine role on debian-bookworm
parent: zuul-jobs-test-ensure-twine
tags: auto-generated
nodeset:
nodes:
- name: debian-bookworm
label: debian-bookworm
- job:
name: zuul-jobs-test-ensure-twine-debian-bullseye
description: Test the ensure-twine role on debian-bullseye
parent: zuul-jobs-test-ensure-twine
tags: auto-generated
nodeset:
nodes:
- name: debian-bullseye
label: debian-bullseye
- job:
name: zuul-jobs-test-ensure-twine-ubuntu-focal
description: Test the ensure-twine role on ubuntu-focal
parent: zuul-jobs-test-ensure-twine
tags: auto-generated
nodeset:
nodes:
- name: ubuntu-focal
label: ubuntu-focal
- job:
name: zuul-jobs-test-ensure-twine-ubuntu-jammy
description: Test the ensure-twine role on ubuntu-jammy
parent: zuul-jobs-test-ensure-twine
tags: auto-generated
nodeset:
nodes:
- name: ubuntu-jammy
label: ubuntu-jammy
- job:
name: zuul-jobs-test-ensure-twine-ubuntu-noble
description: Test the ensure-twine role on ubuntu-noble
parent: zuul-jobs-test-ensure-twine
tags: auto-generated
nodeset:
nodes:
- name: ubuntu-noble
label: ubuntu-noble
- job:
name: zuul-jobs-test-ensure-sphinx
description: Test the ensure-sphinx role
@ -570,6 +639,12 @@
- zuul-jobs-test-ensure-pyproject-build-ubuntu-focal
- zuul-jobs-test-ensure-pyproject-build-ubuntu-jammy
- zuul-jobs-test-ensure-pyproject-build-ubuntu-noble
- zuul-jobs-test-ensure-twine-centos-9-stream
- zuul-jobs-test-ensure-twine-debian-bookworm
- zuul-jobs-test-ensure-twine-debian-bullseye
- zuul-jobs-test-ensure-twine-ubuntu-focal
- zuul-jobs-test-ensure-twine-ubuntu-jammy
- zuul-jobs-test-ensure-twine-ubuntu-noble
- zuul-jobs-test-ensure-sphinx
- zuul-jobs-test-ensure-tox-centos-9-stream
- zuul-jobs-test-ensure-tox-debian-bookworm