From b8a0bdfbcd70b8b9b7cbeadfe9c293bc864c6729 Mon Sep 17 00:00:00 2001 From: Robert de Bock Date: Tue, 5 Jan 2021 15:47:21 +0100 Subject: [PATCH] Add 2 enterprise-grade pre-commit hooks. --- README.md | 11 ----- ansible.cfg | 1 - files/pre-commit-config.yaml | 8 +++- generate.yml | 31 +++----------- gitlab.yml | 71 ++++++++++++++++++++++++++++++++ indexer.sh | 31 ++++++++++++++ templates/README.md.j2 | 11 ++--- templates/galaxy.yml.j2 | 8 +--- templates/gitlab-ci.yml.j2 | 32 ++++++++++++++ templates/molecule-action.yml.j2 | 4 +- templates/requirements.txt.j2 | 10 +++++ templates/todo-action.yml.j2 | 18 ++++++++ templates/tox.ini.j2 | 6 +-- templates/travis.yml.j2 | 24 +++-------- vars/main.yml | 3 -- vars/vault.yml | 10 +++++ 16 files changed, 202 insertions(+), 77 deletions(-) create mode 100755 gitlab.yml create mode 100755 indexer.sh create mode 100644 templates/gitlab-ci.yml.j2 create mode 100644 templates/requirements.txt.j2 create mode 100644 templates/todo-action.yml.j2 create mode 100644 vars/vault.yml diff --git a/README.md b/README.md index aaa969d..7b6ba46 100644 --- a/README.md +++ b/README.md @@ -70,17 +70,6 @@ author: Robert de Bock (robert@meinit.nl) author_website: "https://robertdebock.nl/" ``` -## secure.yml - -This file contains a secret unique to you; te slack encryption token. You have to create this file yourself and it should contain: - -```yaml ---- -slack_token: "YOUR_SLACK_USERNAME:YOUR_SLACK_TOKEN" -``` - -See [Travis documentation](https://docs.travis-ci.com/user/notifications/#configuring-slack-notifications). - ## meta/version.yml This optional file can be placed when a role contains a version. diff --git a/ansible.cfg b/ansible.cfg index d8fe66c..0440d48 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,2 +1 @@ [defaults] -vault_password_file=vault_password_file.txt diff --git a/files/pre-commit-config.yaml b/files/pre-commit-config.yaml index b078340..056388e 100644 --- a/files/pre-commit-config.yaml +++ b/files/pre-commit-config.yaml @@ -1,7 +1,7 @@ --- repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.3.0 + rev: v3.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -18,3 +18,9 @@ repos: hooks: - id: ansible-lint pass_filenames: false + + - repo: https://github.com/robertdebock/pre-commit + rev: v1.1.2 + hooks: + - id: ansible_role_find_unused_variable + - id: ansible_role_find_empty_files diff --git a/generate.yml b/generate.yml index bc38a58..555e038 100755 --- a/generate.yml +++ b/generate.yml @@ -114,38 +114,12 @@ changed_when: no failed_when: no - - name: load secure.yml - include_vars: - file: secure.yml - name: secure - - - name: load .travis.yml - include_vars: - file: "{{ role_path }}/.travis.yml" - name: travis - - name: load github contributors uri: url: "https://api.github.com/repos/robertdebock/ansible-role-{{ role_name }}/contributors" register: github_contributors failed_when: no - - name: generate secure hash - command: travis encrypt --pro "{{ secure.slack_token }}" --no-interactive - register: travis_secure - when: - - (travis.notifications.slack.secure is defined and travis.notifications.slack.secure | length < 512) or - travis.notifications.slack.secure is not defined - - - name: overwrite travis.notifications.slack.secure - set_fact: - travis: - notifications: - slack: - secure: "{{ travis_secure.stdout | regex_replace('\"', '') }}" - when: - travis_secure.stdout is defined - - name: create .github directories file: path: "{{ role_path }}/{{ item }}" @@ -201,6 +175,11 @@ dest: .github/workflows/molecule.yml - source: galaxy.yml dest: .github/workflows/galaxy.yml + - source: todo-action.yml + dest: .github/workflows/todo.yml + - source: gitlab-ci.yml + dest: .gitlab-ci.yml + - source: requirements.txt loop_control: label: "{{ item.source }}" diff --git a/gitlab.yml b/gitlab.yml new file mode 100755 index 0000000..55d3660 --- /dev/null +++ b/gitlab.yml @@ -0,0 +1,71 @@ +#!/usr/bin/env ansible-playbook +--- +- name: configure GitLab repository + hosts: localhost + become: no + gather_facts: no + + vars: + namespace: robertdebock + + vars_files: + - vars/main.yml + - vars/vault.yml + + tasks: + - name: see if all veriables are set + assert: + that: + - namespace is defined + - role is defined + quiet: yes + + - name: urlencode path + set_fact: + encoded_path: "{{ namespace + '%2F' + role }}" + + - name: place variable + block: + - name: see if the variable is set already + uri: + url: "https://gitlab.com/api/v4/projects/{{ encoded_path }}/variables" + method: GET + body_format: json + headers: + PRIVATE-TOKEN: "{{ gitlab_private_token }}" + body: + key: "GALAXY_API_KEY" + register: check_variable + failed_when: + check_variable.json | length <= 0 + rescue: + - name: place variable + uri: + url: "https://gitlab.com/api/v4/projects/{{ encoded_path }}/variables" + method: POST + body_format: json + status_code: + - 201 + headers: + PRIVATE-TOKEN: "{{ gitlab_private_token }}" + body: + key: "GALAXY_API_KEY" + value: "{{ galaxy_api_key }}" + variable_type: env_var + protects: true + masked: true + + - name: create a new pipeline schedule + uri: + url: "https://gitlab.com/api/v4/projects/{{ encoded_path }}/pipeline_schedules" + method: POST + body_format: json + status_code: + - 201 + headers: + PRIVATE-TOKEN: "{{ gitlab_private_token }}" + body: + description: "Monthly test" + ref: master + cron: '{{ letter_minute_mapping[role[0]] }} {{ letter_hour_mapping[role[0]] }} {{ letter_day_mapping[role[0]] }} * *' + cron_timezone: UTC diff --git a/indexer.sh b/indexer.sh new file mode 100755 index 0000000..185d4e2 --- /dev/null +++ b/indexer.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +# A script to regenerate a list of roles and their CI status. + +# Where are the roles stored locally? +directory="/home/robertdb/Documents/github.com/robertdebock" + +# What is the pattern of the directory names? +pattern="ansible-role-" + +# Print the header of the table. +echo "|Role name|Travis|GitHub Action|GitLab CI|Version|" +echo "|---------|------|-------------|---------|-------|" + +# Loop over the found roles. +cd ${directory} ; ls -d "${pattern}"* | while read rolename ; do + + # Find the short name, i.e. "httpd" instead of "ansible-role-httpd" + shortrolename=$(echo "${rolename}" | sed "s/^${pattern}//") + + # Save the markdown per column in a variable, better readable loop. + galaxy="[${shortrolename}](https://galaxy.ansible.com/robertdebock/${shortrolename})" + travis="[![travis](https://api.travis-ci.com/robertdebock/${rolename}.svg?branch=master)](https://travis-ci.com/robertdebock/${rolename})" + github="[![github](https://github.com/robertdebock/${rolename}/workflows/Ansible%20Molecule/badge.svg)](https://github.com/robertdebock/${rolename}/actions)" + gitlab="[![gitlab](https://gitlab.com/robertdebock/${rolename}/badges/master/pipeline.svg)](https://gitlab.com/robertdebock/${rolename})" + version="[![version](https://img.shields.io/github/commits-since/robertdebock/${rolename}/latest.svg)](https://github.com/robertdebock/${rolename}/releases)" + + # Print the line of one role. + echo "|${galaxy}|${travis}|${github}|${gitlab}|${version}|" + +done diff --git a/templates/README.md.j2 b/templates/README.md.j2 index 9897c2a..97d9275 100644 --- a/templates/README.md.j2 +++ b/templates/README.md.j2 @@ -2,9 +2,9 @@ {{ meta.galaxy_info.description }} -|Travis|GitHub|Quality|Downloads|Version| -|------|------|-------|---------|-------| -|[![travis](https://travis-ci.com/{{ travis_namespace }}/ansible-role-{{ role_name }}.svg?branch=master)](https://travis-ci.com/{{ travis_namespace }}/ansible-role-{{ role_name }})|[![github](https://github.com/{{ github_namespace }}/ansible-role-{{ role_name }}/workflows/Ansible%20Molecule/badge.svg)](https://github.com/{{ github_namespace }}/ansible-role-{{ role_name }}/actions)|[![quality](https://img.shields.io/ansible/quality/{{ galaxy_id.stdout | default('unset') }})](https://galaxy.ansible.com/{{ github_namespace }}/{{ role_name }})|[![downloads](https://img.shields.io/ansible/role/d/{{ galaxy_id.stdout |default('unset') }})](https://galaxy.ansible.com/{{ github_namespace }}/{{ role_name }})|[![Version](https://img.shields.io/github/release/{{ github_namespace }}/ansible-role-{{ role_name }}.svg)](https://github.com/{{ github_namespace }}/ansible-role-{{ role_name }}/releases/)| +|Travis|GitHub|GitLab|Quality|Downloads|Version| +|------|------|------|-------|---------|-------| +|[![travis](https://travis-ci.com/{{ travis_namespace }}/ansible-role-{{ role_name }}.svg?branch=master)](https://travis-ci.com/{{ travis_namespace }}/ansible-role-{{ role_name }})|[![github](https://github.com/{{ github_namespace }}/ansible-role-{{ role_name }}/workflows/Ansible%20Molecule/badge.svg)](https://github.com/{{ github_namespace }}/ansible-role-{{ role_name }}/actions)|[![gitlab](https://gitlab.com/{{ github_namespace }}/ansible-role-{{ role_name }}/badges/master/pipeline.svg)](https://gitlab.com/{{ github_namespace }}/ansible-role-{{ role_name }})|[![quality](https://img.shields.io/ansible/quality/{{ galaxy_id.stdout | default('unset') }})](https://galaxy.ansible.com/{{ github_namespace }}/{{ role_name }})|[![downloads](https://img.shields.io/ansible/role/d/{{ galaxy_id.stdout |default('unset') }})](https://galaxy.ansible.com/{{ github_namespace }}/{{ role_name }})|[![Version](https://img.shields.io/github/release/{{ github_namespace }}/ansible-role-{{ role_name }}.svg)](https://github.com/{{ github_namespace }}/ansible-role-{{ role_name }}/releases/)| ## [Example Playbook](#example-playbook) @@ -30,12 +30,13 @@ These variables are set in `defaults/main.yml`: ## [Requirements](#requirements) -- Access to a repository containing packages, likely on the internet. -- A recent version of Ansible. (Tests run on the current, previous and next release of Ansible.) +- pip packages listed in [requirements.txt](https://github.com/{{ github_namespace }}/ansible-role-{{ role_name }}/blob/master/requirements.txt). {% if requirements is defined %} ## [Status of requirements](#status-of-requirements) +The following roles are used to prepare a system. You may choose to prepare your system in another way, I have tested these roles as well. + | Requirement | Travis | GitHub | |-------------|--------|--------| {% for requirement in requirements.roles %} diff --git a/templates/galaxy.yml.j2 b/templates/galaxy.yml.j2 index 084b2c3..1fb67de 100644 --- a/templates/galaxy.yml.j2 +++ b/templates/galaxy.yml.j2 @@ -4,12 +4,8 @@ name: Release to Ansible Galaxy on: - push: - tags: - - '*' - schedule: - - cron: '{{ letter_minute_mapping[role_name[0]] }} {{ letter_hour_mapping[role_name[0]] }} {{ letter_day_mapping[role_name[0]] }} * *' - + release: + types: [created, edited, published, released] jobs: release: runs-on: ubuntu-20.04 diff --git a/templates/gitlab-ci.yml.j2 b/templates/gitlab-ci.yml.j2 new file mode 100644 index 0000000..a7664fd --- /dev/null +++ b/templates/gitlab-ci.yml.j2 @@ -0,0 +1,32 @@ +--- +image: robertdebock/github-action-molecule:2.6.6 + +services: + - docker:dind + +variables: + DOCKER_HOST: "tcp://docker:2375" + PY_COLORS: 1 + +molecule: + script: + - image=${image} tag=${tag} molecule test + rules: + - if: $CI_COMMIT_TAG == null + retry: 2 + parallel: + matrix: +{% for platform in meta.galaxy_info.platforms %} +{% for version in platform.versions %} +{% for tag in distribution_version_mapping[platform.name][version] %} + - image: "{{ platform_image_mapping[platform.name] }}" + tag: "{{ tag }}" +{% endfor %} +{% endfor %} +{% endfor %} + +galaxy: + script: + - ansible-galaxy role import --api-key ${GALAXY_API_KEY} ${CI_PROJECT_NAMESPACE} ${CI_PROJECT_NAME} + rules: + - if: $CI_COMMIT_TAG != null diff --git a/templates/molecule-action.yml.j2 b/templates/molecule-action.yml.j2 index 3c1a708..d403a2c 100644 --- a/templates/molecule-action.yml.j2 +++ b/templates/molecule-action.yml.j2 @@ -21,7 +21,7 @@ jobs: path: {% raw %}"${{ github.repository }}"{% endraw %} - name: molecule - uses: robertdebock/molecule-action@2.6.3 + uses: robertdebock/molecule-action@2.6.8 with: command: lint test: @@ -51,7 +51,7 @@ jobs: - name: parse apparmor for mysql run: sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld - name: molecule - uses: robertdebock/molecule-action@2.6.3 + uses: robertdebock/molecule-action@2.6.8 with: image: {% raw %}${{ matrix.config.image }}{% endraw %} diff --git a/templates/requirements.txt.j2 b/templates/requirements.txt.j2 new file mode 100644 index 0000000..48b9d14 --- /dev/null +++ b/templates/requirements.txt.j2 @@ -0,0 +1,10 @@ +# These role have been tested with these PIP component. +# To install the required version yourself, use a command as: +# `python -m pip --user install -r requirements.txt` +# See the pip requirements file documentation for details: +# https://pip.pypa.io/en/stable/user_guide/#requirements-files +# +# Tests run on the previous and current (latest) version of Ansible. +ansible>={{ meta.galaxy_info.min_ansible_version }} +# Some Jinja2 filters are used that are available in the newer releases. +jinja2>=2.11.2 diff --git a/templates/todo-action.yml.j2 b/templates/todo-action.yml.j2 new file mode 100644 index 0000000..1bdbfac --- /dev/null +++ b/templates/todo-action.yml.j2 @@ -0,0 +1,18 @@ +--- +{{ ansible_managed | comment }} + +name: "TODO 2 Issue" + +on: + push: + +jobs: + build: + runs-on: "ubuntu-20.04" + steps: + - uses: "actions/checkout@master" + - name: "TODO to Issue" + uses: "alstr/todo-to-issue-action@v2.3" + id: "todo" + with: + TOKEN: ${% raw %}{{ secrets.GITHUB_TOKEN }}{% endraw %} diff --git a/templates/tox.ini.j2 b/templates/tox.ini.j2 index d6d58cf..7dbedb2 100644 --- a/templates/tox.ini.j2 +++ b/templates/tox.ini.j2 @@ -1,10 +1,10 @@ {{ ansible_managed | comment }} [tox] -minversion = 3.7 +minversion = 3.20 {% if tox_versions is defined %} -envlist = py{38}-ansible-{% raw %}{{% endraw %}{% for version in tox_versions %}{{ version }}{% if not loop.last %},{% endif %}{% endfor %}{% raw %}}{% endraw %} +envlist = py{39}-ansible-{% raw %}{{% endraw %}{% for version in tox_versions %}{{ version }}{% if not loop.last %},{% endif %}{% endfor %}{% raw %}}{% endraw %} {% else %} -envlist = py{38}-ansible-{previous,current} +envlist = py{39}-ansible-{previous,current} {% endif %} skipsdist = true diff --git a/templates/travis.yml.j2 b/templates/travis.yml.j2 index ec81dd1..981fedd 100644 --- a/templates/travis.yml.j2 +++ b/templates/travis.yml.j2 @@ -6,37 +6,23 @@ os: linux dist: xenial python: - - "3.8" + - "3.9" services: - docker -env: - global: - namespace="{{ docker_namespace }}" - jobs: -{% for platform in meta.galaxy_info.platforms %} -{% for version in platform.versions %} -{% for tag in distribution_version_mapping[platform.name][version] %} - - image="{{ platform_image_mapping[platform.name] }}" tag="{{ tag }}" -{% endfor %} -{% endfor %} -{% endfor %} - cache: - pip install: - pip install --upgrade pip - - pip install tox + - pip install yamllint + - pip install ansible-lint script: - - function retry { counter=0 ; until "$@" ; do exit=$? ; counter=$(($counter + 1)) ; if [ $counter -ge 3 ] ; then return $exit ; fi ; done ; return 0; } ; retry tox + - yamllint . + - ansible-lint notifications: webhooks: https://galaxy.ansible.com/api/v1/notifications/ - slack: - secure: "{{ travis.notifications.slack.secure }}" - on_success: change - template: "%{result}: %{repository_slug}@%{branch}, build <%{build_url}|#%{build_number}> (<%{compare_url}|%{commit}>)" email: false diff --git a/vars/main.yml b/vars/main.yml index 0ed53bb..ff38c77 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -81,13 +81,10 @@ distribution_version_mapping: all: - latest - bionic - - xenial focal: - latest bionic: - bionic - xenial: - - xenial letter_day_mapping: a: 1 diff --git a/vars/vault.yml b/vars/vault.yml new file mode 100644 index 0000000..f681e5d --- /dev/null +++ b/vars/vault.yml @@ -0,0 +1,10 @@ +$ANSIBLE_VAULT;1.1;AES256 +63333963376266386263383966303436353065346139656263333133346433333064633032663938 +3236306464376332383938356264333933633938626435330a373939643261356639373539656333 +31633035633131386363613233653436646338333537613665383337613461643161636332333332 +6135333135636334620a353963383037653830633136333930663439353665323064303234373666 +65313339393334333831316335353831343264373833373131613162646334323362636466326165 +34373062373331666234353338376339663939313463323437323166346432383130323939376437 +34623265396265326538663731306333323435646430373935633738653034323463373261313832 +35613036636566303036363131343762643665616638353837363439613430386533356663346538 +36306661346266653739623937653635323037633232623562396665646238373238