diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ea646a9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,235 @@ +--- +name: "CI" +on: # yamllint disable-line rule:truthy rule:comments + - "push" + - "pull_request" + +env: + PLUGIN_NAME: "nautobot-bgp-models" + +jobs: + black: + runs-on: "ubuntu-20.04" + env: + INVOKE_NAUTOBOT_BGP_MODELS_LOCAL: "True" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v2" + - name: "Linting: black" + run: "poetry run invoke black" + bandit: + runs-on: "ubuntu-20.04" + env: + INVOKE_NAUTOBOT_BGP_MODELS_LOCAL: "True" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v2" + - name: "Linting: bandit" + run: "poetry run invoke bandit" + pydocstyle: + runs-on: "ubuntu-20.04" + env: + INVOKE_NAUTOBOT_BGP_MODELS_LOCAL: "True" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v2" + - name: "Linting: pydocstyle" + run: "poetry run invoke pydocstyle" + flake8: + runs-on: "ubuntu-20.04" + env: + INVOKE_NAUTOBOT_BGP_MODELS_LOCAL: "True" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v2" + - name: "Linting: flake8" + run: "poetry run invoke flake8" + yamllint: + runs-on: "ubuntu-20.04" + env: + INVOKE_NAUTOBOT_BGP_MODELS_LOCAL: "True" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v2" + - name: "Linting: yamllint" + run: "poetry run invoke yamllint" + pylint: + needs: + - "bandit" + - "pydocstyle" + - "flake8" + - "yamllint" + - "black" + runs-on: "ubuntu-20.04" + strategy: + fail-fast: true + matrix: + python-version: ["3.7"] + nautobot-version: ["1.3.3"] + env: + INVOKE_NAUTOBOT_BGP_MODELS_PYTHON_VER: "${{ matrix.python-version }}" + INVOKE_NAUTOBOT_BGP_MODELS_NAUTOBOT_VER: "${{ matrix.nautobot-version }}" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v2" + - name: "Set up Docker Buildx" + id: "buildx" + uses: "docker/setup-buildx-action@v1" + - name: "Build" + uses: "docker/build-push-action@v2" + with: + builder: "${{ steps.buildx.outputs.name }}" + context: "./" + push: false + load: true + tags: "${{ env.PLUGIN_NAME }}/nautobot:${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" + file: "./development/Dockerfile" + cache-from: "type=gha,scope=${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" + cache-to: "type=gha,scope=${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" + build-args: | + NAUTOBOT_VER=${{ matrix.nautobot-version }} + PYTHON_VER=${{ matrix.python-version }} + - name: "Copy credentials" + run: "cp development/creds.example.env development/creds.env" + - name: "Linting: pylint" + run: "poetry run invoke pylint" + unittest: + needs: + - "pylint" + strategy: + fail-fast: true + matrix: + python-version: ["3.7", "3.8", "3.9", "3.10"] + db-backend: ["postgresql"] + nautobot-version: ["1.3.3", "stable"] + runs-on: "ubuntu-20.04" + env: + INVOKE_NAUTOBOT_BGP_MODELS_PYTHON_VER: "${{ matrix.python-version }}" + INVOKE_NAUTOBOT_BGP_MODELS_NAUTOBOT_VER: "${{ matrix.nautobot-version }}" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v2" + - name: "Set up Docker Buildx" + id: "buildx" + uses: "docker/setup-buildx-action@v1" + - name: "Build" + uses: "docker/build-push-action@v2" + with: + builder: "${{ steps.buildx.outputs.name }}" + context: "./" + push: false + load: true + tags: "${{ env.PLUGIN_NAME }}/nautobot:${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" + file: "./development/Dockerfile" + cache-from: "type=gha,scope=${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" + cache-to: "type=gha,scope=${{ matrix.nautobot-version }}-py${{ matrix.python-version }}" + build-args: | + NAUTOBOT_VER=${{ matrix.nautobot-version }} + PYTHON_VER=${{ matrix.python-version }} + - name: "Copy credentials" + run: "cp development/creds.example.env development/creds.env" + - name: "Run Tests" + run: "poetry run invoke unittest" + publish_gh: + needs: + - "unittest" + name: "Publish to GitHub" + runs-on: "ubuntu-20.04" + if: "startsWith(github.ref, 'refs/tags/v')" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Set up Python" + uses: "actions/setup-python@v2" + with: + python-version: "3.9" + - name: "Install Python Packages" + run: "pip install poetry" + - name: "Set env" + run: "echo RELEASE_VERSION=${GITHUB_REF:10} >> $GITHUB_ENV" + - name: "Run Poetry Version" + run: "poetry version $RELEASE_VERSION" + - name: "Run Poetry Build" + run: "poetry build" + - name: "Upload binaries to release" + uses: "svenstaro/upload-release-action@v2" + with: + repo_token: "${{ secrets.GH_NAUTOBOT_BOT_TOKEN }}" + file: "dist/*" + tag: "${{ github.ref }}" + overwrite: true + file_glob: true + publish_pypi: + needs: + - "unittest" + name: "Push Package to PyPI" + runs-on: "ubuntu-20.04" + if: "startsWith(github.ref, 'refs/tags/v')" + steps: + - name: "Check out repository code" + uses: "actions/checkout@v2" + - name: "Set up Python" + uses: "actions/setup-python@v2" + with: + python-version: "3.9" + - name: "Install Python Packages" + run: "pip install poetry" + - name: "Set env" + run: "echo RELEASE_VERSION=${GITHUB_REF:10} >> $GITHUB_ENV" + - name: "Run Poetry Version" + run: "poetry version $RELEASE_VERSION" + - name: "Run Poetry Build" + run: "poetry build" + - name: "Push to PyPI" + uses: "pypa/gh-action-pypi-publish@release/v1" + with: + user: "__token__" + password: "${{ secrets.PYPI_API_TOKEN }}" + slack-notify: + needs: + - "publish_gh" + - "publish_pypi" + runs-on: "ubuntu-20.04" + env: + SLACK_WEBHOOK_URL: "${{ '{{ secrets.SLACK_WEBHOOK_URL }}' }}" + SLACK_MESSAGE: >- + *NOTIFICATION: NEW-RELEASE-PUBLISHED*\n + Repository: <${{ github.server_url }}/${{ github.repository }}|${{ github.repository }}>\n + Release: <${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}>\n + Published by: <${{ github.server_url }}/${{ github.actor }}|${{ github.actor }}> + steps: + - name: "Send a notification to Slack" + # ENVs cannot be used directly in job.if. This is a workaround to check + # if SLACK_WEBHOOK_URL is present. + if: "${{ env.SLACK_WEBHOOK_URL != '' }}" + uses: "slackapi/slack-github-action@v1.17.0" + with: + payload: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "${{ env.SLACK_MESSAGE }}" + } + } + ] + } + env: + SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}" + SLACK_WEBHOOK_TYPE: "INCOMING_WEBHOOK" diff --git a/.travis.yml b/.travis.yml index 59528c2..3281f4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,9 +3,11 @@ language: "python" python: - "3.7" - "3.8" +- "3.9" +- "3.10" env: matrix: - - "NAUTOBOT_VER=1.3.4" + - "NAUTOBOT_VER=1.3.3" # Add your encrypted secret below, you can encrypt secret using "travis encrypt" # https://docs.travis-ci.com/user/environment-variables/#defining-encrypted-variables-in-travisyml # global: @@ -16,8 +18,6 @@ services: # Tests # -------------------------------------------------------------------------- before_script: -- "pip install --upgrade pip" -- "pip install -U importlib_metadata" - "pip install invoke docker-compose" - "curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py > /tmp/get-poetry.py" - "python /tmp/get-poetry.py -y --version 1.0.2" diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..b49e490 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,12 @@ +--- +extends: "default" +rules: + comments: "enable" + empty-values: "disable" + indentation: + indent-sequences: "consistent" + line-length: "disable" + quoted-strings: + quote-type: "double" +ignore: | + .venv/ diff --git a/tasks.py b/tasks.py index 7931dbe..059160d 100644 --- a/tasks.py +++ b/tasks.py @@ -344,6 +344,17 @@ def unittest_coverage(context): run_command(context, command) +@task +def yamllint(context): + """Run yamllint to validate formating adheres to NTC defined YAML standards. + + Args: + context (obj): Used to run specific commands + """ + command = "yamllint . --format standard" + run_command(context, command) + + @task( help={ "failfast": "fail as soon as a single test fails don't run the entire test suite", @@ -360,6 +371,8 @@ def tests(context, failfast=False): black(context) print("Running flake8...") flake8(context) + print("Running yamllint...") + yamllint(context) print("Running bandit...") bandit(context) print("Running pydocstyle...")