
Une collection en production se teste sur plusieurs versions d’ansible-core et de Python pour garantir la compatibilité descendante. Le pattern 2026 : GitHub Actions avec une matrice ansible-core × python, exécutant ansible-test sanity --docker + ansible-test units + ansible-lint --strict dans un Docker conforme. Avec SHA pinning des actions, permissions: {} au global, persist-credentials: false sur checkout.
Cette page fournit les deux pipelines équivalents (GitHub Actions + GitLab CI), durcis selon les pratiques 2026 (zizmor compliant), prêts à copier-coller dans votre repo de collection.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Workflow GitHub Actions complet pour collection Ansible.
- Matrice
ansible-core stable-2.18 × stable-2.19 × devel × Python 3.11 × 3.12. ansible-test sanity --dockerdans la CI.ansible-test units --dockersur les modules Python.ansible-lint --strict --profile production.- SHA pinning des actions (zizmor compliant).
- Équivalent GitLab CI avec
parallel:matrix.
Prérequis
Section intitulée « Prérequis »- Avoir une collection custom (cf Créer une collection).
- Compte GitHub ou GitLab.
Workflow GitHub Actions complet
Section intitulée « Workflow GitHub Actions complet »name: Ansible teston: push: branches: [main] pull_request:
permissions: {} # ← global = aucune
jobs: sanity: name: sanity (${{ matrix.ansible }} / py${{ matrix.python }}) runs-on: ubuntu-24.04 permissions: contents: read strategy: fail-fast: false # ← continue même si une combo échoue matrix: ansible: - stable-2.18 - stable-2.19 - devel python: - "3.11" - "3.12" steps: - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.2.2 with: path: ansible_collections/student/webapp persist-credentials: false # ← bloque token Git
- name: Setup Python uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: "${{ matrix.python }}"
- name: Install ansible-core ${{ matrix.ansible }} run: | pip install "https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz"
- name: ansible-test sanity --docker working-directory: ansible_collections/student/webapp run: | ansible-test sanity --docker default -v --color
units: name: units (${{ matrix.ansible }} / py${{ matrix.python }}) runs-on: ubuntu-24.04 permissions: contents: read strategy: fail-fast: false matrix: ansible: [stable-2.18, devel] python: ["3.11", "3.12"] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.2.2 with: path: ansible_collections/student/webapp persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: "${{ matrix.python }}"
- run: | pip install "https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz"
- name: ansible-test units --docker working-directory: ansible_collections/student/webapp run: | ansible-test units --docker default -v --color --python ${{ matrix.python }}
lint: name: ansible-lint runs-on: ubuntu-24.04 permissions: contents: read steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 with: path: ansible_collections/student/webapp persist-credentials: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 with: { python-version: "3.12" }
- run: pip install ansible-lint==25.5.0 ansible-core==2.18.1
- name: ansible-lint --strict --profile production working-directory: ansible_collections/student/webapp run: ansible-lint --strict --profile productionBonnes pratiques 2026 visibles
Section intitulée « Bonnes pratiques 2026 visibles »| Pattern | Pourquoi |
|---|---|
permissions: {} au workflow | Aucune permission par défaut sur le GITHUB_TOKEN. Élargies par job au strict nécessaire. |
persist-credentials: false | Bloque l’usage du token Git après checkout (évite l’exfiltration via une étape compromise). |
uses: <owner>/<repo>@<SHA40> | Protège contre tag mutation attacks (un attaquant qui repush v4.2.2). |
fail-fast: false | Continue même si une combo échoue → on voit lesquelles passent. |
path: ansible_collections/student/webapp | Ansible-test exige cette arborescence pour fonctionner. |
Pipeline GitLab CI équivalent
Section intitulée « Pipeline GitLab CI équivalent »stages: - lint - sanity - units
variables: ANSIBLE_VERSIONS: "stable-2.18 stable-2.19 devel" PYTHON_VERSIONS: "3.11 3.12"
.collection_setup: &collection_setup before_script: - pip install "https://github.com/ansible/ansible/archive/${ANSIBLE_VERSION}.tar.gz" - mkdir -p ansible_collections/student/webapp - shopt -s extglob && cp -r !(ansible_collections) ansible_collections/student/webapp/ - cd ansible_collections/student/webapp
ansible-lint: stage: lint image: python:3.12 script: - pip install ansible-lint==25.5.0 ansible-core==2.18.1 - ansible-lint --strict --profile production
sanity: stage: sanity image: python:${PYTHON_VERSION} parallel: matrix: - PYTHON_VERSION: ["3.11", "3.12"] ANSIBLE_VERSION: ["stable-2.18", "stable-2.19", "devel"] <<: *collection_setup script: - ansible-test sanity --docker default -v --color
units: stage: units image: python:${PYTHON_VERSION} parallel: matrix: - PYTHON_VERSION: ["3.11", "3.12"] ANSIBLE_VERSION: ["stable-2.18", "devel"] <<: *collection_setup script: - ansible-test units --docker default -v --color --python ${PYTHON_VERSION}🔍 Observation : parallel:matrix GitLab CI donne le même effet que la matrice GitHub Actions. <<: *collection_setup factorise le before_script partagé. Résultat fonctionnellement équivalent.
Linter le workflow avec zizmor
Section intitulée « Linter le workflow avec zizmor »zizmor .github/workflows/ansible-test.ymlDétecte automatiquement :
- Actions non pinnées par SHA.
permissions:trop larges.- Variables d’env exposées sans escape.
- Absence de
persist-credentials: false. - Templates
${{ ... }}injectables.
🔍 Observation : zizmor est l’outil de référence 2026 pour auditer les workflows GitHub. À ajouter en pre-commit hook pour bloquer les régressions de sécurité supply-chain.
Pour aller plus loin — coverage
Section intitulée « Pour aller plus loin — coverage »- name: ansible-test units --coverage run: | ansible-test units --docker default --coverage ansible-test coverage html ansible-test coverage --requirements xmlCombiner avec coverage --coverage-check pour bloquer la CI si la couverture chute sous un seuil :
ansible-test coverage check --requirements xml || exit 1Lab pratique
Section intitulée « Lab pratique »Le lab collections/ci-tests (labs/collections/ci-tests/) fournit le workflow GitHub Actions et le .gitlab-ci.yml complets avec 10 tests pytest structurels (SHA pinning, permissions, persist-credentials, matrice ≥2 versions).
À retenir
Section intitulée « À retenir »- Matrice ansible-core × Python = 4-6 combinaisons typiques en CI.
- SHA pinning des actions GitHub (40 caractères hex), zizmor compliant.
permissions: {}au global,persist-credentials: falsesur checkout.ansible-test sanity --docker default= validation FQCN + doc + types.ansible-test units --docker= pytest sur les modules Python.ansible-lint --strict --profile production= qualité maximale.- Zizmor lint des workflows en pre-commit hook.