From 9b6fc117f93ce2f364a029afbd91cd23470d678a Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Tue, 19 Aug 2025 10:29:39 +0100 Subject: [PATCH 1/4] CI: Remove unused python_version vars from Ubuntu 22.04 jobs --- .github/workflows/tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 18411b35..d4a14b66 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,13 +29,10 @@ jobs: - tox_env: py27-m_ans-ans4 - tox_env: py36-m_ans-ans2.10 - python_version: '3.6' - tox_env: py36-m_ans-ans4 - python_version: '3.6' - tox_env: py27-m_mtg - tox_env: py36-m_mtg - python_version: '3.6' steps: - uses: actions/checkout@v4 From e3241912f727dbfde39bc1b95207ac96f4bd99d2 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Tue, 19 Aug 2025 12:08:42 +0100 Subject: [PATCH 2/4] CI: Factor out .ci/show_python_versions --- .ci/show_python_versions | 33 +++++++++++++++++ .github/workflows/tests.yml | 71 ++----------------------------------- 2 files changed, 36 insertions(+), 68 deletions(-) create mode 100755 .ci/show_python_versions diff --git a/.ci/show_python_versions b/.ci/show_python_versions new file mode 100755 index 00000000..ac219824 --- /dev/null +++ b/.ci/show_python_versions @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -o errexit -o nounset -o pipefail + +INDENT=" " +POSSIBLE_PYTHONS=( + python + python2 + python3 + /usr/bin/python + /usr/bin/python2 + /usr/bin/python3 + # GitHub macOS 12 images: python2.7 is installed, but not on $PATH + /Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 +) + +for p in "${POSSIBLE_PYTHONS[@]}"; do + echo "$p" + if [[ ${p:0:1} == "/" && -e $p ]]; then + : + elif type "$p" > /dev/null 2>&1; then + type "$p" 2>&1 | sed -e "s/^/${INDENT}type: /" + else + echo "${INDENT}Not present" + echo + continue + fi + + $p -c "import sys; print('${INDENT}version: %d.%d.%d' % sys.version_info[:3])" + # macOS builders lack a realpath command + $p -c "import os.path; print('${INDENT}realpath: %s' % os.path.realpath('$(type -p "$p")'))" + $p -c "import sys; print('${INDENT}sys.executable: %s' % sys.executable)" + echo +done diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d4a14b66..507802d8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -64,27 +64,7 @@ jobs: echo 1>&2 "Python interpreter $PYTHON not available" exit 1 fi - - name: Show Python versions - run: | - set -o errexit -o nounset -o pipefail - - # macOS builders lack a realpath command - type python && python -c"import os.path;print(os.path.realpath('$(type -p python)'))" && python --version - type python2 && python2 -c"import os.path;print(os.path.realpath('$(type -p python2)'))" && python2 --version - type python3 && python3 -c"import os.path;print(os.path.realpath('$(type -p python3)'))" && python3 --version - echo - - if [ -e /usr/bin/python ]; then - echo "/usr/bin/python: sys.executable: $(/usr/bin/python -c 'import sys; print(sys.executable)')" - fi - - if [ -e /usr/bin/python2 ]; then - echo "/usr/bin/python2: sys.executable: $(/usr/bin/python2 -c 'import sys; print(sys.executable)')" - fi - - if [ -e /usr/bin/python2.7 ]; then - echo "/usr/bin/python2.7: sys.executable: $(/usr/bin/python2.7 -c 'import sys; print(sys.executable)')" - fi + - run: .ci/show_python_versions - name: Install tooling run: | set -o errexit -o nounset -o pipefail @@ -186,27 +166,7 @@ jobs: sudo apt-get update sudo apt-get install -y sshpass virtualenv - - name: Show Python versions - run: | - set -o errexit -o nounset -o pipefail - - # macOS builders lack a realpath command - type python && python -c"import os.path;print(os.path.realpath('$(type -p python)'))" && python --version - type python2 && python2 -c"import os.path;print(os.path.realpath('$(type -p python2)'))" && python2 --version - type python3 && python3 -c"import os.path;print(os.path.realpath('$(type -p python3)'))" && python3 --version - echo - - if [ -e /usr/bin/python ]; then - echo "/usr/bin/python: sys.executable: $(/usr/bin/python -c 'import sys; print(sys.executable)')" - fi - - if [ -e /usr/bin/python2 ]; then - echo "/usr/bin/python2: sys.executable: $(/usr/bin/python2 -c 'import sys; print(sys.executable)')" - fi - - if [ -e /usr/bin/python2.7 ]; then - echo "/usr/bin/python2.7: sys.executable: $(/usr/bin/python2.7 -c 'import sys; print(sys.executable)')" - fi + - run: .ci/show_python_versions - name: Install tooling run: | set -o errexit -o nounset -o pipefail @@ -262,32 +222,7 @@ jobs: with: python-version: ${{ matrix.python_version }} if: ${{ matrix.python_version }} - - name: Show Python versions - run: | - set -o errexit -o nounset -o pipefail - - # macOS builders lack a realpath command - type python && python -c"import os.path;print(os.path.realpath('$(type -p python)'))" && python --version - type python2 && python2 -c"import os.path;print(os.path.realpath('$(type -p python2)'))" && python2 --version - type python3 && python3 -c"import os.path;print(os.path.realpath('$(type -p python3)'))" && python3 --version - echo - - if [ -e /usr/bin/python ]; then - echo "/usr/bin/python: sys.executable: $(/usr/bin/python -c 'import sys; print(sys.executable)')" - fi - - if [ -e /usr/bin/python2 ]; then - echo "/usr/bin/python2: sys.executable: $(/usr/bin/python2 -c 'import sys; print(sys.executable)')" - fi - - if [ -e /usr/bin/python2.7 ]; then - echo "/usr/bin/python2.7: sys.executable: $(/usr/bin/python2.7 -c 'import sys; print(sys.executable)')" - fi - - if [ -e /Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 ]; then - # GitHub macOS 12 images: python2.7 is installed, but not on $PATH - echo "/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7: sys.executable: $(/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 -c 'import sys; print(sys.executable)')" - fi + - run: .ci/show_python_versions - run: .ci/install_sshpass ${{ matrix.sshpass_version }} if: ${{ matrix.sshpass_version }} - name: Install tooling From 9e3377c0a8ec1867bf4ec02c152072203e3ef3c1 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Tue, 19 Aug 2025 12:43:24 +0100 Subject: [PATCH 3/4] CI: Combine build deps & tooling steps --- .ci/bash_functions | 13 +++++ .github/workflows/tests.yml | 103 ++++++++---------------------------- docs/changelog.rst | 2 + 3 files changed, 38 insertions(+), 80 deletions(-) create mode 100644 .ci/bash_functions diff --git a/.ci/bash_functions b/.ci/bash_functions new file mode 100644 index 00000000..1f9020d7 --- /dev/null +++ b/.ci/bash_functions @@ -0,0 +1,13 @@ +# shellcheck shell=bash + +# Tox environment name -> Python executable name (e.g. py312-m_mtg -> python3.12) +toxenv-python() { + local pattern='^py([23])([0-9]{1,2}).*' + if [[ $1 =~ $pattern ]]; then + echo "python${BASH_REMATCH[1]}.${BASH_REMATCH[2]}" + return + else + echo "${FUNCNAME[0]}: $1: environment name not recognised" >&2 + return 1 + fi +} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 507802d8..c9640ac2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,70 +41,38 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Install build deps + - run: .ci/show_python_versions + - name: Install deps + id: install-deps run: | set -o errexit -o nounset -o pipefail - - PYTHON=$(python -c 'import re; print(re.sub(r"^py([23])([0-9]{1,2}).*", r"python\1.\2", "${{ matrix.tox_env }}"))') - - if [[ -z $PYTHON ]]; then - echo 1>&2 "Python interpreter could not be determined" - exit 1 - fi + source .ci/bash_functions + PYTHON="$(toxenv-python '${{ matrix.tox_env }}')" sudo apt-get update if [[ $PYTHON == "python2.7" ]]; then sudo apt install -y python2-dev sshpass virtualenv - elif [[ $PYTHON == "python3.6" ]]; then - sudo apt install -y gcc-10 make libbz2-dev liblzma-dev libreadline-dev libsqlite3-dev libssl-dev sshpass virtualenv zlib1g-dev - curl --fail --silent --show-error --location https://pyenv.run | bash - CC=gcc-10 ~/.pyenv/bin/pyenv install --force 3.6 - else - echo 1>&2 "Python interpreter $PYTHON not available" - exit 1 - fi - - run: .ci/show_python_versions - - name: Install tooling - run: | - set -o errexit -o nounset -o pipefail - - # Tox environment name (e.g. py312-m_mtg) -> Python executable name (e.g. python3.12) - PYTHON=$(python -c 'import re; print(re.sub(r"^py([23])([0-9]{1,2}).*", r"python\1.\2", "${{ matrix.tox_env }}"))') - - if [[ -z $PYTHON ]]; then - echo 1>&2 "Python interpreter could not be determined" - exit 1 - fi - - if [[ $PYTHON == "python2.7" ]]; then curl "https://bootstrap.pypa.io/pip/2.7/get-pip.py" --output "get-pip.py" "$PYTHON" get-pip.py --user --no-python-version-warning # Avoid Python 2.x pip masking system pip rm -f ~/.local/bin/{easy_install,pip,wheel} elif [[ $PYTHON == "python3.6" ]]; then + sudo apt install -y gcc-10 make libbz2-dev liblzma-dev libreadline-dev libsqlite3-dev libssl-dev sshpass virtualenv zlib1g-dev + curl --fail --silent --show-error --location https://pyenv.run | bash + CC=gcc-10 ~/.pyenv/bin/pyenv install --force 3.6 PYTHON="$HOME/.pyenv/versions/3.6.15/bin/python3.6" fi "$PYTHON" -m pip install -r "tests/requirements-tox.txt" + echo "python=$PYTHON" >> $GITHUB_OUTPUT - name: Run tests env: GITHUB_ACTOR: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -o errexit -o nounset -o pipefail - - # Tox environment name (e.g. py312-m_mtg) -> Python executable name (e.g. python3.12) - PYTHON=$(python -c 'import re; print(re.sub(r"^py([23])([0-9]{1,2}).*", r"python\1.\2", "${{ matrix.tox_env }}"))') - - if [[ -z $PYTHON ]]; then - echo 1>&2 "Python interpreter could not be determined" - exit 1 - fi - - if [[ $PYTHON == "python3.6" ]]; then - PYTHON="$HOME/.pyenv/versions/3.6.15/bin/python3.6" - fi + PYTHON="${{ steps.install-deps.outputs.python }}" "$PYTHON" -m tox -e "${{ matrix.tox_env }}" @@ -160,40 +128,26 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Install build deps + - run: .ci/show_python_versions + - name: Install deps + id: install-deps run: | set -o errexit -o nounset -o pipefail + source .ci/bash_functions + PYTHON="$(toxenv-python '${{ matrix.tox_env }}')" sudo apt-get update sudo apt-get install -y sshpass virtualenv - - run: .ci/show_python_versions - - name: Install tooling - run: | - set -o errexit -o nounset -o pipefail - - # Tox environment name (e.g. py312-m_mtg) -> Python executable name (e.g. python3.12) - PYTHON=$(python -c 'import re; print(re.sub(r"^py([23])([0-9]{1,2}).*", r"python\1.\2", "${{ matrix.tox_env }}"))') - - if [[ -z $PYTHON ]]; then - echo 1>&2 "Python interpreter could not be determined" - exit 1 - fi "$PYTHON" -m pip install -r "tests/requirements-tox.txt" + echo "python=$PYTHON" >> $GITHUB_OUTPUT - name: Run tests env: GITHUB_ACTOR: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -o errexit -o nounset -o pipefail - - # Tox environment name (e.g. py312-m_mtg) -> Python executable name (e.g. python3.12) - PYTHON=$(python -c 'import re; print(re.sub(r"^py([23])([0-9]{1,2}).*", r"python\1.\2", "${{ matrix.tox_env }}"))') - - if [[ -z $PYTHON ]]; then - echo 1>&2 "Python interpreter could not be determined" - exit 1 - fi + PYTHON="${{ steps.install-deps.outputs.python }}" "$PYTHON" -m tox -e "${{ matrix.tox_env }}" @@ -225,33 +179,22 @@ jobs: - run: .ci/show_python_versions - run: .ci/install_sshpass ${{ matrix.sshpass_version }} if: ${{ matrix.sshpass_version }} - - name: Install tooling + - name: Install deps + id: install-deps run: | set -o errexit -o nounset -o pipefail - - # Tox environment name (e.g. py312-m_mtg) -> Python executable name (e.g. python3.12) - PYTHON=$(python -c 'import re; print(re.sub(r"^py([23])([0-9]{1,2}).*", r"python\1.\2", "${{ matrix.tox_env }}"))') - - if [[ -z $PYTHON ]]; then - echo 1>&2 "Python interpreter could not be determined" - exit 1 - fi + source .ci/bash_functions + PYTHON="$(toxenv-python '${{ matrix.tox_env }}')" "$PYTHON" -m pip install -r "tests/requirements-tox.txt" + echo "python=$PYTHON" >> $GITHUB_OUTPUT - name: Run tests env: GITHUB_ACTOR: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -o errexit -o nounset -o pipefail - - # Tox environment name (e.g. py312-m_mtg) -> Python executable name (e.g. python3.12) - PYTHON=$(python -c 'import re; print(re.sub(r"^py([23])([0-9]{1,2}).*", r"python\1.\2", "${{ matrix.tox_env }}"))') - - if [[ -z $PYTHON ]]; then - echo 1>&2 "Python interpreter could not be determined" - exit 1 - fi + PYTHON="${{ steps.install-deps.outputs.python }}" "$PYTHON" -m tox -e "${{ matrix.tox_env }}" diff --git a/docs/changelog.rst b/docs/changelog.rst index 84f0d77b..b0a3f562 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -21,6 +21,8 @@ To avail of fixes in an unreleased version, please download a ZIP file In progress (unreleased) ------------------------ +* :gh:issue:`1329` CI: Refactor and de-duplicate Github Actions workflow + v0.3.26 (2025-08-04) -------------------- From 618eccc0f3219134cf45f0fedfe51ded8009d3f1 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Tue, 19 Aug 2025 13:40:26 +0100 Subject: [PATCH 4/4] CI: Set macOS failed logins limit of mitogen test users to 1000 refs #1315 --- docs/changelog.rst | 1 + tests/image_prep/_user_accounts.yml | 7 ++++++- .../image_prep/roles/user_policies/defaults/main.yml | 2 ++ tests/image_prep/roles/user_policies/tasks/main.yml | 11 +++++++++++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/image_prep/roles/user_policies/defaults/main.yml create mode 100644 tests/image_prep/roles/user_policies/tasks/main.yml diff --git a/docs/changelog.rst b/docs/changelog.rst index b0a3f562..7c36f987 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -22,6 +22,7 @@ In progress (unreleased) ------------------------ * :gh:issue:`1329` CI: Refactor and de-duplicate Github Actions workflow +* :gh:issue:`1315` CI: macOS: Increase failed logins limit of test users v0.3.26 (2025-08-04) diff --git a/tests/image_prep/_user_accounts.yml b/tests/image_prep/_user_accounts.yml index bee89084..225d4a53 100644 --- a/tests/image_prep/_user_accounts.yml +++ b/tests/image_prep/_user_accounts.yml @@ -50,7 +50,10 @@ mitogen_test_groups: - name: mitogen__group - name: mitogen__sudo_nopw - tasks: + + user_policies_max_failed_logins: 1000 + user_policies_users: "{{ all_users }}" + pre_tasks: - name: Disable non-localhost SSH for Mitogen users when: false blockinfile: @@ -180,3 +183,5 @@ validate: '/usr/sbin/visudo -cf %s' when: - ansible_virtualization_type != "docker" + roles: + - role: user_policies diff --git a/tests/image_prep/roles/user_policies/defaults/main.yml b/tests/image_prep/roles/user_policies/defaults/main.yml new file mode 100644 index 00000000..f80df944 --- /dev/null +++ b/tests/image_prep/roles/user_policies/defaults/main.yml @@ -0,0 +1,2 @@ +user_policies_max_failed_logins: 10 +user_policies_users: [] diff --git a/tests/image_prep/roles/user_policies/tasks/main.yml b/tests/image_prep/roles/user_policies/tasks/main.yml new file mode 100644 index 00000000..89fff6bc --- /dev/null +++ b/tests/image_prep/roles/user_policies/tasks/main.yml @@ -0,0 +1,11 @@ +- name: Set login attempts (macOS) + vars: + max_failed_logins: "{{ item.policies.max_failed_logins | default(user_policies_max_failed_logins) }}" + command: > + pwpolicy + -u '{{ item.name }}' + -setpolicy 'maxFailedLoginAttempts={{ max_failed_logins }}' + with_items: "{{ user_policies_users }}" + when: + - ansible_system == 'Darwin' + changed_when: true