diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..82542c4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,163 @@ +name: CI + +on: + workflow_call: + inputs: + release: + required: false + type: boolean + default: false + version: + required: false + type: string + secrets: + PYPI_API_TOKEN: + required: false + TEST_PYPI_API_TOKEN: + required: false + + +jobs: + get-changed-files: + name: Get Changed Files + runs-on: ubuntu-latest + permissions: + contents: read # for dorny/paths-filter to fetch a list of changed files + pull-requests: read # for dorny/paths-filter to read pull requests + outputs: + changed-files: ${{ toJSON(steps.changed-files.outputs) }} + steps: + - uses: actions/checkout@v3 + - name: Get Changed Files + id: changed-files + uses: dorny/paths-filter@v2 + with: + token: ${{ github.token }} + list-files: json + filters: | + repo: + - added|modified: + - '**' + deleted: + - deleted: + - '**' + + pre-commit: + name: Pre-Commit + uses: ./.github/workflows/pre-commit-action.yml + needs: + - get-changed-files + with: + changed-files: ${{ needs.get-changed-files.outputs.changed-files }} + + test: + name: Test + needs: + - get-changed-files + uses: ./.github/workflows/test-action.yml + with: + changed-files: ${{ needs.get-changed-files.outputs.changed-files }} + + docs: + name: Docs + needs: + - get-changed-files + uses: ./.github/workflows/docs-action.yml + with: + changed-files: ${{ needs.get-changed-files.outputs.changed-files }} + +# build-python-package: +# name: Python Package +# if: ${{ inputs.release && success() }} +# uses: ./.github/workflows/package-action.yml +# needs: +# - pre-commit +# with: +# version: "${{ inputs.version }}" +# +# deploy-python-package-test-pypi: +# name: Deploy Python Package (Test PyPI) +# uses: ./.github/workflows/deploy-package-action.yml +# if: ${{ inputs.release && success() }} +# needs: +# - pre-commit +# - test +# - docs +# - build-python-package +# secrets: +# TEST_PYPI_API_TOKEN: "${{ secrets.TEST_PYPI_API_TOKEN }}" +# with: +# version: "${{ inputs.version }}" +# +# deploy-python-package: +# name: Deploy Python Package (PyPI) +# uses: ./.github/workflows/deploy-package-action.yml +# if: ${{ inputs.release && success() }} +# needs: +# - pre-commit +# - test +# - docs +# - build-python-package +# - deploy-python-package-test-pypi +# secrets: +# PYPI_API_TOKEN: "${{ secrets.PYPI_API_TOKEN }}" +# with: +# test: false +# version: "${{ inputs.version }}" +# +# push-tag: +# name: Push Version Tag +# runs-on: ubuntu-latest +# permissions: +# contents: write +# if: ${{ inputs.release && success() }} +# needs: +# - build-python-package +# - deploy-python-package +# steps: +# - name: Checkout +# uses: actions/checkout@v3 +# - name: Push Tag +# uses: rickstaa/action-create-tag@v1 +# with: +# tag: "v${{ inputs.version }}" +# message: "Version ${{ inputs.version }}" +# + set-pipeline-exit-status: + # This step is just so we can make github require this step, to pass checks + # on a pull request instead of requiring all + name: Set the CI Pipeline Exit Status + runs-on: ubuntu-latest + if: always() + needs: + - pre-commit + - test + - docs +# - build-python-package +# - deploy-python-package-test-pypi +# - deploy-python-package +# - push-tag + steps: + - name: Download Exit Status Files + if: always() + uses: actions/download-artifact@v3 + with: + name: exitstatus + path: exitstatus + + - name: Delete Exit Status Artifacts + if: always() + uses: geekyeggo/delete-artifact@v2 + with: + name: exitstatus + failOnError: false + + - name: Set Pipeline Exit Status + run: | + tree exitstatus + grep -RE 'failure|cancelled' exitstatus/ && exit 1 || exit 0 + + - name: Done + if: always() + run: + echo "All workflows finished" diff --git a/.github/workflows/docs-action.yml b/.github/workflows/docs-action.yml new file mode 100644 index 0000000..2f56891 --- /dev/null +++ b/.github/workflows/docs-action.yml @@ -0,0 +1,43 @@ +name: Build Documentation + +on: + workflow_call: + inputs: + changed-files: + required: true + type: string + description: JSON string containing information about changed files + +jobs: + Docs: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.7 For Nox + uses: actions/setup-python@v1 + with: + python-version: 3.7 + + - name: Install Nox + run: | + python -m pip install --upgrade pip + pip install nox + + - name: Install Doc Requirements + run: | + nox --force-color -e docs --install-only + + - name: Build Docs + env: + SKIP_REQUIREMENTS_INSTALL: YES + run: | + nox --force-color -e docs + + - name: Set Exit Status + if: always() + run: | + mkdir exitstatus + echo "${{ job.status }}" > exitstatus/${{ github.job }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..b466b04 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,11 @@ +name: Pull Request or Push + +on: [push, pull_request] + +jobs: + ci: + name: CI + uses: ./.github/workflows/ci.yml + permissions: + contents: write + pull-requests: read diff --git a/.github/workflows/pre-commit-action.yml b/.github/workflows/pre-commit-action.yml new file mode 100644 index 0000000..982a48a --- /dev/null +++ b/.github/workflows/pre-commit-action.yml @@ -0,0 +1,58 @@ +name: Pre-Commit + +on: + workflow_call: + inputs: + changed-files: + required: true + type: string + description: JSON string containing information about changed files + +jobs: + Pre-Commit: + name: Pre-Commit + runs-on: ubuntu-latest + container: + image: python:3.10.9-slim-buster + + steps: + - name: Install System Deps + run: | + echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list + apt-get update + apt-get install -y enchant git gcc make zlib1g-dev libc-dev libffi-dev g++ libxml2 libxml2-dev libxslt-dev libcurl4-openssl-dev libssl-dev libgnutls28-dev + apt-get install -y git/buster-backports + + - uses: actions/checkout@v4 + + - name: Install Pre-Commit + run: | + # TODO: Update pip version without error + # python -m pip install --upgrade pip + python -m pip install pip==19.3.1 + pip install pre-commit + pre-commit install --install-hooks + + - name: Check ALL Files On Branch + if: github.event_name != 'pull_request' + run: | + pre-commit run --show-diff-on-failure --color=always --all-files + + - name: Check Changed Files On PR + if: github.event_name == 'pull_request' && fromJSON(inputs.changed-files)['repo'] == 'true' + run: | + pre-commit run --show-diff-on-failure --color=always --files ${{ join(fromJSON(inputs.changed-files)['repo_files'], ' ') }} + + - name: Set Exit Status + if: always() + run: | + mkdir exitstatus + echo "${{ job.status }}" > exitstatus/${{ github.job }} + + - name: Upload Exit Status + if: always() + uses: actions/upload-artifact@v3 + with: + name: exitstatus + path: exitstatus + if-no-files-found: error diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml new file mode 100644 index 0000000..01be12d --- /dev/null +++ b/.github/workflows/test-action.yml @@ -0,0 +1,402 @@ +name: Testing + +on: + workflow_call: + inputs: + changed-files: + required: true + type: string + description: JSON string containing information about changed files + +jobs: + Linux: + runs-on: ubuntu-latest + timeout-minutes: 30 + + strategy: + fail-fast: false + max-parallel: 4 + matrix: + python-version: + - '3.8' + - '3.9' + salt-version: + - '3005.4' + - '3006.4' + include: + - python-version: '3.10' + salt-version: '3006.4' + + steps: + - uses: actions/checkout@v4 + + - uses: eLco/setup-vault@v1 + with: + vault_version: 1.15.4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Nox + run: | + python -m pip install --upgrade pip + pip install nox + + - name: Install Test Requirements + env: + SALT_REQUIREMENT: salt==${{ matrix.salt-version }} + run: | + nox --force-color -e tests-3 --install-only + + - name: Test + env: + SALT_REQUIREMENT: salt==${{ matrix.salt-version }} + SKIP_REQUIREMENTS_INSTALL: YES + run: | + nox --force-color -e tests-3 -- -vv tests/ + + - name: Create CodeCov Flags + if: always() + id: codecov-flags + run: | + echo ::set-output name=flags::$(python -c "import sys; print('{},{},salt_{}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info), '_'.join(str(v) for v in '${{ matrix.salt-version }}'.replace('==', '_').split('.'))))") + + - name: Upload Project Code Coverage + if: always() + shell: bash + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},project + REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-project + REPORT_PATH: artifacts/coverage-project.xml + run: | + if [ ! -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + if [ -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + + - name: Upload Tests Code Coverage + if: always() + shell: bash + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests + REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-tests + REPORT_PATH: artifacts/coverage-tests.xml + run: | + if [ ! -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + if [ -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + + - name: Upload Logs + if: always() + uses: actions/upload-artifact@main + with: + name: runtests-${{ runner.os }}-py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}.log + path: artifacts/runtests-*.log + + - name: Set Exit Status + if: always() + run: | + mkdir exitstatus + echo "${{ job.status }}" > exitstatus/${{ github.job }} + + Windows: + runs-on: windows-latest + timeout-minutes: 40 + + strategy: + fail-fast: false + max-parallel: 3 + matrix: + include: + - python-version: '3.8' + salt-version: '3005.4' + - python-version: '3.8' + salt-version: '3006.4' + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Download libeay32.dll + run: | + export PY_LOC=$(which python.exe) + echo ${PY_LOC} + export PY_DIR=$(dirname ${PY_LOC}) + echo ${PY_DIR} + curl https://repo.saltproject.io/windows/dependencies/64/libeay32.dll --output ${PY_DIR}/libeay32.dll + ls -l ${PY_DIR} + shell: bash + + - name: Install Nox + run: | + python -m pip install --upgrade pip + pip install nox + + - name: Install Test Requirements + shell: bash + env: + SALT_REQUIREMENT: salt==${{ matrix.salt-version }} + # EXTRA_REQUIREMENTS_INSTALL: Cython + run: | + export PATH="/C/Program Files (x86)/Windows Kits/10/bin/10.0.18362.0/x64;$PATH" + nox --force-color -e tests-3 --install-only + + - name: Test + shell: bash + env: + SALT_REQUIREMENT: salt==${{ matrix.salt-version }} + SKIP_REQUIREMENTS_INSTALL: YES + run: | + export PATH="/C/Program Files (x86)/Windows Kits/10/bin/10.0.18362.0/x64;$PATH" + nox --force-color -e tests-3 -- -vv tests/ + + - name: Create CodeCov Flags + if: always() + id: codecov-flags + run: | + echo ::set-output name=flags::$(python -c "import sys; print('{},{},salt_{}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info), '_'.join(str(v) for v in '${{ matrix.salt-version }}'.replace('==', '_').split('.'))))") + + - name: Upload Project Code Coverage + if: always() + shell: bash + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},project + REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-project + REPORT_PATH: artifacts/coverage-project.xml + run: | + if [ ! -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + if [ -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + + - name: Upload Tests Code Coverage + if: always() + shell: bash + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests + REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-tests + REPORT_PATH: artifacts/coverage-tests.xml + run: | + if [ ! -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + if [ -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + + - name: Upload Logs + if: always() + uses: actions/upload-artifact@main + with: + name: runtests-${{ runner.os }}-py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}.log + path: artifacts/runtests-*.log + + - name: Set Exit Status + if: always() + run: | + mkdir exitstatus + echo "${{ job.status }}" > exitstatus/${{ github.job }} + + macOS: + runs-on: macOS-latest + timeout-minutes: 40 + + strategy: + fail-fast: false + max-parallel: 3 + matrix: + include: + - python-version: '3.9' + salt-version: '3005.4' + - python-version: '3.10' + salt-version: '3006.4' + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Nox + run: | + python -m pip install --upgrade pip + pip install nox + + - name: Install Test Requirements + env: + SALT_REQUIREMENT: salt==${{ matrix.salt-version }} + run: | + nox --force-color -e tests-3 --install-only + + - name: Test + env: + SALT_REQUIREMENT: salt==${{ matrix.salt-version }} + SKIP_REQUIREMENTS_INSTALL: YES + run: | + nox --force-color -e tests-3 -- -vv tests/ + + - name: Create CodeCov Flags + if: always() + id: codecov-flags + run: | + echo ::set-output name=flags::$(python -c "import sys; print('{},{},salt_{}'.format('${{ runner.os }}'.replace('-latest', ''), 'py{}{}'.format(*sys.version_info), '_'.join(str(v) for v in '${{ matrix.salt-version }}'.replace('==', '_').split('.'))))") + + - name: Upload Project Code Coverage + if: always() + shell: bash + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},project + REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-project + REPORT_PATH: artifacts/coverage-project.xml + run: | + if [ ! -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + if [ -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + + - name: Upload Tests Code Coverage + if: always() + shell: bash + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + REPORT_FLAGS: ${{ steps.codecov-flags.outputs.flags }},tests + REPORT_NAME: ${{ runner.os }}-Py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}-tests + REPORT_PATH: artifacts/coverage-tests.xml + run: | + if [ ! -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if curl --max-time 30 -L https://codecov.io/bash --output codecov.sh; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + if [ -f codecov.sh ]; then + n=0 + until [ "$n" -ge 5 ] + do + if bash codecov.sh -R $(pwd) -n "${REPORT_NAME}" -f "${REPORT_PATH}" -F "${REPORT_FLAGS}"; then + break + fi + n=$((n+1)) + sleep 15 + done + fi + + - name: Upload Logs + if: always() + uses: actions/upload-artifact@main + with: + name: runtests-${{ runner.os }}-py${{ matrix.python-version }}-Salt${{ matrix.salt-version }}.log + path: artifacts/runtests-*.log + + - name: Set Exit Status + if: always() + run: | + mkdir exitstatus + echo "${{ job.status }}" > exitstatus/${{ github.job }} diff --git a/.gitignore b/.gitignore index 68bc17f..ec2b5c6 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ parts/ sdist/ var/ wheels/ +pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg @@ -83,9 +84,7 @@ profile_default/ ipython_config.py # pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version +.python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. @@ -158,3 +157,9 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +# Ignore the setuptools_scm auto-generated version module +src/saltext/vault/version.py + +# Ignore CI generated artifacts +artifacts/