--- version: '3' vars: COLLECTION_DEPS: collection_dependencies MAIN_TASKS_PATH: tasks/main.yml META_PATH: meta/main.yml MOLECULE_RESULTS_PATH: molecule/.results PRE_SHARED_VAULT_KEY: YTtEnhPWtftHFcP3HneVmz6vX2qMqAwobTDAbvDwrdyunAaDCQ REQUIREMENTS_PATH: requirements.yml ROLE_NAME: '{{.GALAXY_NAMESPACE}}.{{.GALAXY_ROLE_NAME}}' SAMPLE_PROJECT: https://github.com/megabyte-labs/ansible-snapd VARIABLES_PATH: .variables.json tasks: build:none: log: start: Skipping build stage because Ansible project's do not require building cmds: - task: :donothing collection-dependencies: deps: - :install:software:jq - :install:software:yq env: COLLECTIONS: sh: jq --arg collections "$(yq eval -o=json '.collections' {{.REQUIREMENTS_PATH}})" '.{{.COLLECTION_DEPS}} = ($collections | fromjson) | .{{.COLLECTION_DEPS}}[] | "\"""' -r {{.VARIABLES_PATH}} | jq --raw-input --slurp 'split("\n") | .[0:((. | length) - 1)]' TMP: sh: mktemp log: error: Failed to generate documentation variable for collection dependencies start: Generating documentation variable for collection dependencies success: Generated documentation variable for collection dependencies cmds: - | jq --arg collections "$COLLECTIONS" '.{{.COLLECTION_DEPS}} = ($collections | fromjson)' '{{.VARIABLES_PATH}}' > "$TMP" mv "$TMP" '{{.VARIABLES_PATH}}' collection-dependencies:markdown: deps: - :install:software:jq vars: COLLECTION_LENGTH: sh: jq -r '.{{.COLLECTION_DEPS}} | length' '{{.VARIABLES_PATH}}' FILE_PATH: .autodoc/{{.COLLECTION_DEPS}}.md env: MULTIPLE_COLLECTION_TEXT: "### Galaxy Collections\n\nThis role is dependent on multiple Ansible Galaxy collections. The collections along with a links to their source are listed below.\n\n{{\"{{\"}}{{.COLLECTION_DEPS}}{{\"}}\"}}" SINGLE_COLLECTION_TEXT: "### Galaxy Collection\n\nThis role is dependent on the following Ansible Galaxy collection:\n\n{{\"{{\"}}{{.COLLECTION_DEPS}}{{\"}}\"}}" log: error: Failed to generate documentation partial for collection dependencies start: Generating documentation partial for collection dependencies success: Generated documentation partial for collection dependencies cmds: - mkdir -p '{{dir .FILE_PATH}}' - | {{if (eq .COLLECTION_LENGTH "0")}} echo '' > '{{.FILE_PATH}}' {{else if (eq .COLLECTION_LENGTH "1")}} echo "$SINGLE_COLLECTION_TEXT" > '{{.FILE_PATH}}' {{else}} echo "$MULTIPLE_COLLECTION_TEXT" > '{{.FILE_PATH}}' {{end}} sources: - '{{.FILE_PATH}}' - '{{.VARIABLES_PATH}}' galaxy:import: log: error: Error occurred while importing Ansible Galaxy role start: Triggering Ansible Galaxy import success: Successfully imported role on Ansible Galaxy cmds: - | GITHUB_ROLE_SLUG="$(jq -r '.blueprint.repository.github' package.json | sed 's/.*\///')" {{.PYTHON_HANDLE}} ansible-galaxy role import --token "$ANSIBLE_GALAXY_TOKEN" {{.GITHUB_ORG}} "$GITHUB_ROLE_SLUG" status: - '[ -z "$ANSIBLE_GALAXY_TOKEN" ]' galaxy:requirements: log: error: Error encountered while installing the Ansible Galaxy requirements specified in `requirements.yml` start: Installing the Ansible Galaxy requirements specified in `requirements.yml` success: Installed the Ansible Galaxy requirements specified in `requirements.yml` cmds: - | if [ -f ~/.netrc ]; then chmod 600 ~/.netrc fi - cmd: '{{.PYTHON_HANDLE}} ansible-galaxy install -r requirements.yml --ignore-errors' ignore_error: true sources: - requirements.yml init: cmds: - ansible-galaxy init --role-skeleton=/path/to/skeleton role_name keywords:sync: deps: - :install:npm:prettier - :install:software:jq - :install:software:yq summary: | # Sync Galaxy Tags with `package.json` Keywords This task syncs the Ansible Galaxy tags found in `meta/main.yml` with the keywords in the `package.json` file. The Ansible Galaxy tags are capped to a maximum of 20 tags. env: MERGED_TAGS: sh: jq -s --argjson galaxy "$(yq e -o=j '.galaxy_info.galaxy_tags' meta/main.yml)" '.[0].keywords + $galaxy | sort | unique' package.json MERGED_TAGS_LENGTH: sh: jq -s --argjson galaxy "$(yq e -o=j '.galaxy_info.galaxy_tags' meta/main.yml)" '.[0].keywords + $galaxy | sort | unique | length' package.json log: error: Error encountered while running the `package.json` / `meta/main.yml` synchronization logic start: Synchronizing the keywords in `package.json` and `meta/main.yml` success: Synchronized the keywords in `package.json` and `meta/main.yml` cmds: - | GALAXY_INFO="$(yq e -o=j meta/main.yml)" OPTIONAL_TAGS="$(jq '.keywords' .config/common-keywords.json)" TMP="$(mktemp)" RESULT="$MERGED_TAGS" if [ "$MERGED_TAGS_LENGTH" -gt 20 ]; then function updateList() { REMOVE_KEY="$(jq -n --argjson optional "$OPTIONAL_TAGS" '$optional['"$1"']')" RESULT="$(jq -n --argjson remove "$REMOVE_KEY" --argjson jq "$RESULT" '$jq | del(.[] | select(. == $remove))')" } LOOP_COUNT="$((MERGED_TAGS_LENGTH-20))" for i in $(seq "$LOOP_COUNT"); do updateList "$i" done fi jq -r --argjson result "$MERGED_TAGS" '.keywords = $result' package.json > "$TMP" mv "$TMP" package.json prettier --write package.json > /dev/null mkdir -p .cache/megabytelabs jq -n --argjson result "$RESULT" --argjson gi "$GALAXY_INFO" '$gi | .galaxy_info.galaxy_tags = $result' > .cache/megabytelabs/galaxy-meta.json yq eval -P .cache/megabytelabs/galaxy-meta.json > meta/main.yml - task: :fix:prettier vars: CLI_ARGS: meta/main.yml - task: :fix:yaml:dashes vars: CLI_ARGS: meta/main.yml mod-ansible-autodoc: todo: Add ansible-autodoc-fork to the includes of the package cmds: - | if [ -n "$CI" ]; then pip3 install ansible-autodoc-fork fi - task: mod-ansible-autodoc:generate - task: mod-ansible-autodoc:variables mod-ansible-autodoc:generate: deps: - :install:pipx:mod-ansible-autodoc - :install:software:jq env: ACTIONS_DESCRIPTION: sh: jq -r '.autodoc_actions_description' '{{.VARIABLES_PATH}}' # PATH: # sh: echo "$PATH:$(poetry env info | grep 'Python /' | sed 's/Python //')" TAGS_DESCRIPTION: sh: jq -r '.autodoc_tags_description' '{{.VARIABLES_PATH}}' TODO_DESCRIPTION: sh: jq -r '.autodoc_todo_description' '{{.VARIABLES_PATH}}' VARIABLES_DESCRIPTION: sh: jq -r '.autodoc_variables_description' '{{.VARIABLES_PATH}}' log: error: Error encountered while generating documentation partials with `mod-ansible-autodoc` start: Compiling `mod-ansible-autodoc` documentation from comments in the play *.yml files success: Successfully generated documentation partials with `mod-ansible-autodoc` cmds: - > {{.PYTHON_HANDLE}}mod-ansible-autodoc --actions-title '## Features' --actions-description "$ACTIONS_DESCRIPTION" --tags-title '### Tags' --tags-description "$TAGS_DESCRIPTION" --todo-title '### TODO' --todo-description "$TODO_DESCRIPTION" --variables-title '## Variables' --variables-description "$VARIABLES_DESCRIPTION" --variable-example-comment-prefix '#💬' - mkdir -p .autodoc - mv ansible_actions.md ansible_tags.md ansible_todo.md ansible_variables.json ansible_variables.md .autodoc sources: - '{{.VARIABLES_PATH}}' - defaults/**/*.yml - tasks/**/*.yml - vars/**/*.yml mod-ansible-autodoc:variables: deps: - :install:software:jq log: error: Failed to merge `.autodoc/ansible_variables.json` into `.variables.json` start: Merging `.autodoc/ansible_variables.json` into `.variables.json` success: Successfully merged `.autodoc/ansible_variables.json` into `.variables.json` cmds: - | ROLE_VARIABLES="$(jq -r '.role_variables' .autodoc/ansible_variables.json)" TMP="$(mktemp)" jq --arg vars "$ROLE_VARIABLES" '.role_variables = ($vars | fromjson)' '{{.VARIABLES_PATH}}' > "$TMP" mv "$TMP" '{{.VARIABLES_PATH}}' prepare: deps: - :ci:commit:config log: error: Failed to ensure GitLab and GitHub are in sync start: Preparing for Ansible Galaxy upload success: GitLab and GitHub are in sync cmds: - task: :git:remotes - git pull origin master - git push github master publish: cmds: - task: galaxy:import quickstart: deps: - :install:software:jq - :symlink:{{.REPOSITORY_SUBTYPE}} - task: :install:python:requirements vars: INSTALL_OPTIONS: --no-dev cmds: - git reset --hard HEAD - | if ! git pull origin master; then git config url."https://gitlab.com/".insteadOf git@gitlab.com: git config url."https://github.com/".insteadOf git@github.com: git pull origin master || true fi - task: quickstart:environment - task: quickstart:map - task: quickstart:demo quickstart:cli: deps: - :install:software:openssl summary: | # Ansible Quickstart CLI Use this task if you already know the inventory file you would like to run the `main.yml` playbook on. The unique feature is that this task will first run `playbooks/init.yml` (and skip any task tagged with `skip_on_init`), reboot, and then run the normal `main.yml`. This allows you to provision a single computer that serves both as the client and host of Ansible (since some software requires reboots). {{.QUICKSTART_VAULT_SECURITY}} vars: INVENTORY: '{{if .CLI_ARGS}}{{.CLI_ARGS}}{{else}}inventories/local.yml{{end}}' QUICKSTART_VAULT_SECURITY: | ## Ansible Vault Password Security To achieve automation wherever possible, we save your Ansible Vault password on disk during the installation process (i.e. to preserve the information inbetween reboots). To make it more secure, we employ the following measures: 1. The password is forcibly removed anytime the ansible-playbook command fails 2. It is passed in via the `ANSIBLE_VAULT_PASSWORD` variable to minimize the possibility of the password displaying in the terminal or getting added to the command history. 3. It is stored in `~/.VAULT_PASSWORD` so you can easily spot it if something goes wrong. env: ANSIBLE_CALLBACKS_ENABLED: 'junit, ansible.posix.profile_tasks, ansible.posix.timer, sentry' ANSIBLE_STDOUT_CALLBACK: community.general.yaml ANSIBLE_VAULT_PASSWORD_FILE: ~/.VAULT_PASSWORD JUNIT_FAIL_ON_CHANGE: true JUNIT_HIDE_TASK_ARGUMENTS: true JUNIT_OUTPUT_DIR: .results/junit QUICKSTART_PLAYBOOK_MATCH: | # Playbook Matching Inventory File Name A playbook with the same file name as the selected inventory was found in the `playbooks/` directory. When the file names match up, this "quick start" script will use the matching playbook file instead of the `main.yml` playbook found in the root of the repository. QUICKSTART_VAULT_SECURITY: '{{.QUICKSTART_VAULT_SECURITY}}' log: error: Error occurred while running the Ansible play start: Running the Ansible play locally success: Successfully ran the Ansible play locally cmds: - cmd: | if [ ! -f "$ANSIBLE_VAULT_PASSWORD_FILE" ]; then .config/log info 'Adding `~/ANSIBLE_PLAYBOOK_CONTINUE.sh` to run on reboot' echo "#!/usr/env/bin bash" > ~/ANSIBLE_PLAYBOOK_CONTINUE.sh echo "" > ~/ANSIBLE_PLAYBOOK_CONTINUE.sh echo "cd $PWD" >> ~/ANSIBLE_PLAYBOOK_CONTINUE.sh echo 'task ansible:quickstart:cli -- {{.INVENTORY}}' >> ~/ANSIBLE_PLAYBOOK_CONTINUE.sh if [ -z "$ANSIBLE_VAULT_PASSWORD" ]; then MD_TMP="$(mktemp)" echo "$QUICKSTART_VAULT_SECURITY" > "$MD_TMP" .config/log md "$MD_TMP" .config/log info 'Read about security measures above.' .config/log prompt 'What is your Ansible Vault password?' export ANSIBLE_VAULT_PASSWORD="$(.config/log password 'Enter Vault password (leave empty if there is not a password yet)..')" fi fi .config/log info 'Writing the `ANSIBLE_VAULT_PASSWORD` to temporary file in user home directory' echo "$ANSIBLE_VAULT_PASSWORD" > ~/.VAULT_PASSWORD INVENTORY="{{.INVENTORY}}" INVENTORY_SLUG="$(echo "$INVENTORY" | sed 's/inventories\/\(.*\).yml/\1/')" if [[ '{{.INVENTORY}}' == 'inventories/quickstart.yml' ]]; then if [ -f '/etc/qubes-rpc' ] && [[ "$(whoami)" == 'user' ]]; then .config/log info 'Assuming `ANSIBLE_USER` name to be `user` since this is Qubes' export ANSIBLE_USER="user" elif [ -z "$ANSIBLE_USER" ]; then WHOAMI="$(whoami)" .config/log prompt 'In the next step, select a user with `sudo` privileges' if ! .config/log confirm 'Run playbook with `'"${WHOAMI}"'`?'; then export ANSIBLE_USER="$(.config/log input 'Enter the username of the admin account you wish to use..')" else export ANSIBLE_USER="$WHOAMI" fi else .config/log info '`ANSIBLE_USER` is set to `'"$ANSIBLE_USER"'`' fi if [ -z "$ANSIBLE_PASSWORD" ]; then if sudo -n echo &> /dev/null; then .config/log info 'Assuming passwordless sudo since `sudo -n echo` was truthy' .config/log info 'Bypassing `ANSIBLE_PASSWORD` prompt' else .config/log prompt 'Enter the `sudo` password for your selected user (`'"$ANSIBLE_USER"'`)' export ANSIBLE_PASSWORD="$(.config/log password 'Enter password (or just press enter if there is none)..')" fi else .config/log info '`ANSIBLE_PASSWORD` is present as an environment variable.. bypassing password prompt' fi if [ -z "$MOLECULE_GROUP" ]; then if [ -f '/etc/qubes-rpc' ]; then .config/log info 'Machine is a Qubes dom0 environment' export MOLECULE_GROUP="qubes" else .config/log info 'Assuming machine to be macOS/Linux' export MOLECULE_GROUP="standard" fi fi fi if [ -f local/requirements.txt ]; then pip3 install -r local/requirements.txt else .config/log warn 'The `local/requirements.txt` file is missing' fi if [ -f "playbooks/${INVENTORY_SLUG}.yml" ]; then PLAY_TMP="$(mktemp)" && echo "$QUICKSTART_PLAYBOOK_MATCH" > "$PLAY_TMP" && .config/log md "$PLAY_TMP" {{.PYTHON_HANDLE}}ansible-playbook --skip-tags "dotfiles,mas" -vvv -i {{.INVENTORY}} "playbooks/${INVENTORY_SLUG}.yml" || EXIT_CODE="$?" else .config/log info 'Using the `main.yml` playbook because there is no playbook located in `'"playbooks/${INVENTORY_SLUG}.yml"'`' {{.PYTHON_HANDLE}}ansible-playbook --skip-tags "dotfiles,mas" -vvv -i {{.INVENTORY}} main.yml || EXIT_CODE="$?" fi #if [ -n "$EXIT_CODE" ]; then # .config/log error 'There was an error while running the playbook.' # .config/log warn 'Ensure there are no secrets in plain text (if you choose to upload the logs so our developers can fix this issue).' # .config/log confirm 'Upload the playbook log so the developers can debug?' # # sentry-cli #fi ignore_error: true - sleep 5 - .config/log info 'Ensuring the temporary vault password file is forcibly removed' - rm -f ~/.VAULT_PASSWORD - rm -f ~/ANSIBLE_PLAYBOOK_CONTINUE.sh quickstart:demo: cmds: - task: quickstart:cli status: - '[ -f files/inventory-map.json ]' quickstart:environment: cmds: - task: :ansible:playbook:environment:cli vars: CLI_ARGS: sh: echo "$ENV" status: - '[ -z "$ENV" ]' quickstart:map: deps: - :install:pipx:getmac - :install:software:gum - :install:software:jq summary: | # Quickstart Mapping This task is a helper task that attempts to automatically select the appropriate Ansible inventory based on the MAC address. If the mapping entry is not already saved, this task will guide the user through a series of prompts. {{.MAC_ADDRESS_EXPLANATION}} vars: INVENTORY_OPTIONS: sh: echo "\""$(find ./inventories/ -mindepth 1 -maxdepth 1 | sed 's/\.\/inventories\//inventories\//' | jq -R '[.]' | jq -s -c -r 'add | join("\" \"")')"\"" INVENTORY_OPTIONS_LENGTH: sh: find ./inventories/ -mindepth 1 -maxdepth 1 | sed 's/\.\/inventories\///' | jq -R '[.]' | jq -s -c -r 'add | length' MAC_ADDRESS_EXPLANATION: | ## Mapping MAC Addresses to Inventory Files In order to achieve a completely automated flow, we have the ability to define a map of MAC addresses and inventory files in the `files/` folder. You can get your MAC address by using the `getmac` program that this task installs or you can run the following on Linux: ``` cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address ``` On Windows, if you are provisioning with Docker (the default "Quick Start" method) and if you make sure you are running it on either a clean system or have no other Docker containers running, then the MAC address will be: ``` 02:42:ac:11:00:02 ``` If you wanted to run the Quick Start method on Windows, you could create a file in `files/inventory-map.json` that looks something like this: ``` { "02:42:ac:11:00:02": "inventories/workstation.yml" } ``` This configuration would instruct the script to automatically use the `inventories/workstation.yml` inventory. If your MAC address is missing, the script will open an interactive prompt and include the ability to save your MAC address to the file for later use. env: INVENTORY_EXPLANATION: | # Which Inventory Should I Use? A special / great starting point is the `quickstart.yml` inventory which allows you to pass your username and password through a prompt. It is intended to be used to provision one machine at a time from that machine. It is also intended to be used with the **Quick Start** links at the top of the README.md. It can be used to provision any of our supported operating systems. ## TLDR: Choose `quickstart.yml` MAC_ADDRESS_EXPLANATION: '{{.MAC_ADDRESS_EXPLANATION}}' cmds: - | PATH="$PATH:$HOME/.local/bin" # MAC_ADDRESS="$(cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address)" # Does not work on macOS MAC_ADDRESS="$(getmac)" TARGET_INV="$(jq --arg macAddress "$MAC_ADDRESS" -r '.[$macAddress]' files/inventory-map.json)" if [[ "$TARGET_INV" == '' ]]; then .config/log warn 'Initializing `files/inventory-map.json` since it appears to be an empty file' echo '{}' > files/inventory-map.json fi if [ "$TARGET_INV" != 'null' ] && [ "$TARGET_INV" != '' ]; then .config/log info "Provisioning with "'`'"$TARGET_INV"'`' task ansible:quickstart:cli -- "$TARGET_INV" else MD_TMP="$(mktemp)" echo "$MAC_ADDRESS_EXPLANATION" > "$MD_TMP" .config/log md "$MD_TMP" .config/log warn "MAC address missing from inventory-map.json ($MAC_ADDRESS). Details printed above." if [ '{{.INVENTORY_OPTIONS_LENGTH}}' != '0' ]; then .config/log prompt 'Given the information above, would you like to save your MAC address to the `files/inventory-map.json` file?' if .config/log confirm 'Save MAC address?'; then INV_TMP="$(mktemp)" && echo "$INVENTORY_EXPLANATION" > "$INV_TMP" && .config/log md "$INV_TMP" .config/log prompt 'Which inventory file would you like the associate the MAC address with?' INVENTORY_FILE="$(.config/log choose {{.INVENTORY_OPTIONS}})" TMP="$(mktemp)" .config/log info 'Generating new `files/inventory-map.json` file' jq --arg inventory "$INVENTORY_FILE" --arg macaddr "$MAC_ADDRESS" '.[$macaddr] = $inventory' files/inventory-map.json > "$TMP" mv "$TMP" files/inventory-map.json .config/log success "Successfully associated the selected inventory with this machine's MAC address (remember to git add / commit)" task ansible:quickstart:cli -- "$INVENTORY_FILE" else INV_TMP="$(mktemp)" && echo "$INVENTORY_EXPLANATION" > "$INV_TMP" && .config/log md "$INV_TMP" .config/log prompt 'Which inventory file would you like to use?' INVENTORY_FILE="$(.config/log choose {{.INVENTORY_OPTIONS}})" task ansible:quickstart:cli -- "$INVENTORY_FILE" fi else .config/log error 'There are no inventories defined in the `inventories/` folder.' .config/log info 'Try running `task environment` to link to sample environments' exit 1 fi fi status: - '[ ! -f files/inventory-map.json ]' sync:requirements: deps: - :install:software:jq - :install:software:yq log: error: Failed to synchronize role dependencies in `{{.META_PATH}}` to `{{.REQUIREMENTS_PATH}}` start: Ensuring role dependencies in `{{.META_PATH}}` are also listed in `{{.REQUIREMENTS_PATH}}` success: Successfully ensured role dependencies in `{{.META_PATH}}` are also listed in `{{.REQUIREMENTS_PATH}}` cmds: - | ROLES="$(yq eval '.roles' '{{.REQUIREMENTS_PATH}}')" yq eval -o=json '.dependencies' '{{.META_PATH}}' | jq -rc '.[] .role' | while read ROLE_NAME; do if [[ ! "$ROLES" =~ "$ROLE_NAME" ]]; then yq eval -i -P '.roles = .roles + {"name": "'"$ROLE_NAME"'"}' '{{.REQUIREMENTS_PATH}}' fi done - task: :fix:yaml:dashes vars: CLI_ARGS: '{{.REQUIREMENTS_PATH}}' update:galaxy-id: log: error: Failed to look up or inject the Ansible Galaxy project ID into `package.json` start: Adding Ansible Galaxy project ID to `package.json` (if available) success: Successfully ensured Ansible Galaxy project ID is in `package.json` (if the project is on Ansible Galaxy) cmds: - | TMP="$(mktemp)" PROJECT_ID="$(ansible-galaxy info '{{.ROLE_NAME}}' 2> /dev/null | grep -E 'id: [0-9]' | cut -d ' ' -f2)" if [ "$PROJECT_ID" ]; then jq --arg a "$PROJECT_ID" '.blueprint.ansible_galaxy_project_id = $a' package.json > "$TMP" mv "$TMP" package.json fi status: - jq -e 'has("blueprint.ansible_galaxy_project_id")' package.json update:variables: cmds: - task: :ansible:ansibler:ansibler - task: update:variables:descriptions update:variables:descriptions: deps: - :install:software:jq - :install:software:yq vars: ALT_PREFIX: This repository is the home of an [Ansible](https://www.ansible.com/) role that DESCRIPTION: sh: yq e '.galaxy_info.description' '{{.META_PATH}}' DESCRIPTION_LOWER: '{{lower (trunc 1 .DESCRIPTION)}}{{substr 1 (len .DESCRIPTION) .DESCRIPTION}}' SUBHEADER_PREFIX: An Ansible role that env: ALT: '{{.ALT_PREFIX}} {{.DESCRIPTION_LOWER}}' GALAXY_INFO: sh: yq e -o=json '.galaxy_info' '{{.META_PATH}}' SUBHEADER: '{{.SUBHEADER_PREFIX}} {{.DESCRIPTION_LOWER}}' TMP: sh: mktemp log: error: Failed to inject `.variables.json` with description variables start: Injecting description variables into `.variables.json` success: Successfully updated `.variables.json` with description variables cmds: - jq -S --arg alt "$ALT" --arg galaxyinfo "$GALAXY_INFO" --arg subheader "$SUBHEADER" '.alternative_description = $alt | .galaxy_info = ($galaxyinfo | fromjson) | .subheader_description = $subheader' '{{.VARIABLES_PATH}}' > "$TMP" - mv "$TMP" '{{.VARIABLES_PATH}}' sources: - '.common/variables.{{.REPOSITORY_SUBTYPE}}.json' - '{{.META_PATH}}' - package.json preconditions: - sh: type jq > /dev/null msg: jq is not installed. - sh: type yq > /dev/null msg: yq is not installed. - sh: 'test -f "{{.META_PATH}}"' msg: 'The `{{.META_PATH}}` file is missing. A properly populated `{{.META_PATH}}` is required. You can find an example of one at {{.SAMPLE_PROJECT}}.' - sh: 'test -f "{{.VARIABLES_PATH}}"' msg: 'The `{{.VARIABLES_PATH}}` file is missing!' update:variables:playbook: cmds: - task: :ansible:playbook:docs vault:lint:file: summary: | # Check for unencrypted Ansible Vault files This task is leveraged by `lint-staged` to ensure that any file that matches `**/*vault.yml` is encrypted with Ansible Vault. log: error: '`{{.CLI_ARGS}}` is not encrypted! All files matching `**/*vault.yml` must be encrypted by `ansible-vault`.' start: Checking if `{{.CLI_ARGS}}` is encrypted with `ansible-vault` success: Ensured `{{.CLI_ARGS}}` is encrypted cmds: - | head -1 '{{.CLI_ARGS}}' | grep --quiet '^\$ANSIBLE_VAULT;' || { if [ -s '{{.CLI_ARGS}}' ]; then exit 1 fi } verify: deps: - :install:software:poetry log: error: Failed to connect to Ansible Galaxy with provided token start: Verifying connection can be made to Ansible Galaxy success: Successfully connected to Ansible Galaxy cmds: - poetry update ansible - poetry run ansible-galaxy role setup --token "$ANSIBLE_GALAXY_TOKEN" null null null null --list