Matrix Docker Ansible eploy
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

167 Zeilen
5.8 KiB

  1. # SPDX-FileCopyrightText: 2026 Slavi Pantaleev
  2. #
  3. # SPDX-License-Identifier: AGPL-3.0-or-later
  4. ---
  5. name: Molecule
  6. # Unlike the MASH role repositories, where one repository holds one role, every
  7. # role here lives in the same repository. Running every scenario on every push
  8. # would be unaffordable, so a first job works out which roles the push actually
  9. # touched and the matrix is built from that. A push that changes documentation,
  10. # or a role with no scenario yet, runs nothing at all.
  11. on: # yamllint disable-line rule:truthy
  12. push:
  13. paths:
  14. - "roles/custom/**"
  15. - "molecule-shared/**"
  16. - ".github/workflows/molecule.yml"
  17. pull_request:
  18. paths:
  19. - "roles/custom/**"
  20. - "molecule-shared/**"
  21. - ".github/workflows/molecule.yml"
  22. workflow_dispatch:
  23. inputs:
  24. role:
  25. description: "Single role to test (directory name under roles/custom), or empty for all roles that have a scenario"
  26. required: false
  27. type: string
  28. permissions:
  29. contents: read
  30. jobs:
  31. detect:
  32. name: Work out which roles to test
  33. runs-on: ubuntu-latest
  34. # Same rule as the MASH repositories: a pull request from a branch of this
  35. # repository would otherwise run everything twice, once for the push and
  36. # once for the pull request.
  37. if: >-
  38. github.event_name != 'pull_request'
  39. || github.event.pull_request.head.repo.full_name != github.repository
  40. outputs:
  41. roles: ${{ steps.detect.outputs.roles }}
  42. steps:
  43. - name: Check out
  44. uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
  45. with:
  46. fetch-depth: 0
  47. - name: Detect roles with a Molecule scenario that this change touches
  48. id: detect
  49. env:
  50. EVENT_NAME: ${{ github.event_name }}
  51. BASE_SHA: ${{ github.event.pull_request.base.sha }}
  52. BEFORE_SHA: ${{ github.event.before }}
  53. DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
  54. INPUT_ROLE: ${{ inputs.role }}
  55. run: |
  56. set -euo pipefail
  57. have_scenario() {
  58. [ -f "roles/custom/$1/molecule/default/molecule.yml" ]
  59. }
  60. # An explicit request through workflow_dispatch wins over detection.
  61. if [ -n "${INPUT_ROLE}" ]; then
  62. if have_scenario "${INPUT_ROLE}"; then
  63. printf 'roles=["%s"]\n' "${INPUT_ROLE}" >> "$GITHUB_OUTPUT"
  64. else
  65. echo "No scenario at roles/custom/${INPUT_ROLE}/molecule/default" >&2
  66. exit 1
  67. fi
  68. exit 0
  69. fi
  70. # New branches have an all-zero before SHA. Compare them with their
  71. # common ancestor with the default branch, so the first Renovate push
  72. # tests only the roles it changes. The same fallback handles a force
  73. # push whose previous commit is no longer available locally.
  74. # Manual runs without a role, and pushes with no usable comparison,
  75. # still consider every scenario.
  76. base=""
  77. case "${EVENT_NAME}" in
  78. pull_request) base="${BASE_SHA}" ;;
  79. push)
  80. if [ -n "${BEFORE_SHA}" ] && [ "${BEFORE_SHA}" != "0000000000000000000000000000000000000000" ] \
  81. && git cat-file -e "${BEFORE_SHA}^{commit}" 2>/dev/null; then
  82. base="${BEFORE_SHA}"
  83. elif [ -n "${DEFAULT_BRANCH}" ] && [ "${GITHUB_REF}" != "refs/heads/${DEFAULT_BRANCH}" ]; then
  84. base="$(git merge-base HEAD "refs/remotes/origin/${DEFAULT_BRANCH}" || true)"
  85. fi
  86. ;;
  87. esac
  88. # molecule-shared/ is used by every scenario, so a change there means
  89. # every role has to run, not just the ones whose own files moved.
  90. shared_changed=""
  91. if [ -n "${base}" ]; then
  92. shared_changed="$(git diff --name-only "${base}" HEAD -- 'molecule-shared/*' '.github/workflows/molecule.yml' || true)"
  93. fi
  94. if [ -n "${base}" ] && [ -z "${shared_changed}" ]; then
  95. changed="$(git diff --name-only "${base}" HEAD -- 'roles/custom/*' || true)"
  96. candidates="$(printf '%s\n' "${changed}" | awk -F/ 'NF>2 {print $3}' | sort -u)"
  97. echo "Changed roles: ${candidates:-none}"
  98. else
  99. if [ -n "${shared_changed}" ]; then
  100. echo "Shared Molecule files changed; considering every role"
  101. fi
  102. candidates="$(find roles/custom -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort)"
  103. fi
  104. selected=""
  105. for role in ${candidates}; do
  106. if have_scenario "${role}"; then
  107. selected="${selected} ${role}"
  108. fi
  109. done
  110. if [ -z "${selected}" ]; then
  111. echo "Nothing to test"
  112. echo 'roles=[]' >> "$GITHUB_OUTPUT"
  113. exit 0
  114. fi
  115. echo "Testing:${selected}"
  116. json="$(printf '%s\n' ${selected} | jq -R . | jq -c -s .)"
  117. echo "roles=${json}" >> "$GITHUB_OUTPUT"
  118. molecule:
  119. name: "Molecule: ${{ matrix.role }}"
  120. runs-on: ubuntu-latest
  121. needs: detect
  122. if: needs.detect.outputs.roles != '[]'
  123. strategy:
  124. matrix:
  125. role: ${{ fromJson(needs.detect.outputs.roles) }}
  126. fail-fast: false
  127. env:
  128. MOLECULE_DISTRO: ubuntu2604
  129. PY_COLORS: "1"
  130. ANSIBLE_FORCE_COLOR: "1"
  131. steps:
  132. - name: Check out
  133. uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
  134. - name: Set up Python
  135. uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
  136. with:
  137. python-version: "3.x"
  138. - name: Install test dependencies
  139. run: python3 -m pip install -r molecule-shared/requirements.txt
  140. - name: Run Molecule
  141. working-directory: roles/custom/${{ matrix.role }}
  142. run: molecule test --scenario-name default