From 9677b7aded5d18bf77504733a6fd1983a90b1e2c Mon Sep 17 00:00:00 2001 From: Kyle Finley Date: Mon, 12 Aug 2024 12:48:27 -0400 Subject: [PATCH] use `poetry-dynamic-versioning`, update workflows to consolidate steps (#2488) --- .devcontainer/Dockerfile | 7 +- .editorconfig | 13 +- .github/labels.yml | 2 +- .github/scripts/cicd/build_pyinstaller.sh | 44 ++-- .../scripts/cicd/check_distance_from_tag.sh | 12 +- .github/workflows/cicd.yml | 159 +++++---------- .github/workflows/label-maker.yml | 4 +- .github/workflows/on-pr-target-opened.yml | 26 --- .github/workflows/on-pr.yml | 17 -- .github/workflows/on-push-pyinstaller.yml | 95 ++++----- .github/workflows/pull_request_target.yml | 36 ++++ .github/workflows/release-management.yml | 5 +- .../{publish-on-release.yml => release.yml} | 190 +++++++----------- .github/workflows/spell-check.yml | 15 +- .readthedocs.yml | 25 +-- .vscode/cspell.json | 17 +- Makefile | 61 +++--- docs/source/conf.py | 15 +- docs/source/developers/getting_started.rst | 13 +- docs/source/runway_config.rst | 4 +- package-lock.json | 5 +- package.json | 3 +- poetry.lock | 16 +- pyproject.toml | 16 +- runway/__init__.py | 21 +- runway/config/models/runway/__init__.py | 2 +- .../unit/config/models/runway/test_runway.py | 2 +- tests/unit/core/test_core.py | 3 + tests/unit/factories.py | 2 +- 29 files changed, 360 insertions(+), 470 deletions(-) delete mode 100644 .github/workflows/on-pr-target-opened.yml delete mode 100644 .github/workflows/on-pr.yml create mode 100644 .github/workflows/pull_request_target.yml rename .github/workflows/{publish-on-release.yml => release.yml} (63%) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 389e8c022..4d5681ad8 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -42,8 +42,11 @@ ADD --chown=vscode:vscode files/.bash_completion /home/vscode/.bash_completion RUN mkdir /home/vscode/.bash_completion.d/ # Setup AWS CLI -RUN pip3 install --user awscli poetry==1.5.1 -RUN echo "complete -C '/home/vscode/.local/bin/aws_completer' aws" >> ~/.bashrc +RUN set -e; \ + pip3 install --no-cache-dir --user awscli pipx; \ + pipx install poetry; \ + pipx inject poetry "poetry-dynamic-versioning[plugin]" poetry-plugin-export; \ + echo "complete -C '/home/vscode/.local/bin/aws_completer' aws" >> ~/.bashrc # Setup OS_NAME var for runway builds from this dev container RUN echo "export OS_NAME=ubuntu-latest" >> ~/.bashrc diff --git a/.editorconfig b/.editorconfig index 0f1d28c6c..1ad016f58 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,20 +1,15 @@ root = true [*] +charset = utf-8 end_of_line = lf -indent_size = 4 +indent_size = 2 indent_style = space insert_final_newline = true trim_trailing_whitespace = true -[*.{html,js,jsx,md,rst,toml,ts,xml,yml,yaml}] -indent_size = 2 - -[*.py] -charset = utf-8 - -[*.rst] -indent_size = 2 +[{*.{json,py},Makefile}] +indent_size = 4 [Makefile] indent_style = tab diff --git a/.github/labels.yml b/.github/labels.yml index 19ead9d6b..9960c8e06 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -48,7 +48,7 @@ color: f0db4f description: Pull request that updates Javascript code - name: maintenance - color: fbca04 + color: fbca04 # cspell:ignore fbca04 description: General repo or CI/CD upkeep - name: npm color: cc3534 diff --git a/.github/scripts/cicd/build_pyinstaller.sh b/.github/scripts/cicd/build_pyinstaller.sh index b3dd85292..1b6d66a57 100644 --- a/.github/scripts/cicd/build_pyinstaller.sh +++ b/.github/scripts/cicd/build_pyinstaller.sh @@ -5,42 +5,46 @@ set -ev if [ "$OS_NAME" == "ubuntu-latest" ]; then - LOCAL_OS_NAME="linux" + LOCAL_OS_NAME="linux" elif [ "$OS_NAME" == "macos-12" ]; then - LOCAL_OS_NAME="osx" + LOCAL_OS_NAME="osx" elif [ "$OS_NAME" == "windows-latest" ]; then - LOCAL_OS_NAME="windows" + LOCAL_OS_NAME="windows" else - echo 'Environment variable "OS_NAME" must be one of ["ubuntu-latest", "macos-12", "windows-latest"]' - exit 1 + echo 'Environment variable "OS_NAME" must be one of ["ubuntu-latest", "macos-12", "windows-latest"]' + exit 1 fi if [ "$1" != "file" ] && [ "$1" != "folder" ]; then - echo 'First positional argument must be one of ["file", "folder"]' - exit 1 + echo 'First positional argument must be one of ["file", "folder"]' + exit 1 fi RUNWAY_VERSION=$(poetry version --short) +if [[ -z "${GITHUB_ACTION}" ]]; then + rm -rf ./.venv; # NOTE (kyle): this needs to be removed on GitHub +fi + poetry build poetry run pip install "$(find dist -type f -name 'runway-*.tar.gz' -print | tail -n 1)" find dist/* -exec rm -rfv "{}" + mkdir -p "artifacts/${RUNWAY_VERSION}/${LOCAL_OS_NAME}" poetry run pip show setuptools -poetry run pyinstaller --noconfirm --clean runway.$1.spec +poetry run pyinstaller --noconfirm --clean "runway.$1.spec" # cspell:ignore noconfirm if [ "$1" == 'file' ]; then - mv dist/* "artifacts/${RUNWAY_VERSION}/$LOCAL_OS_NAME" - chmod +x "artifacts/${RUNWAY_VERSION}/$LOCAL_OS_NAME/runway" - # quick functional test - ./artifacts/${RUNWAY_VERSION}/$LOCAL_OS_NAME/runway --version + mv dist/* "artifacts/${RUNWAY_VERSION}/$LOCAL_OS_NAME" + chmod +x "artifacts/${RUNWAY_VERSION}/$LOCAL_OS_NAME/runway" + # quick functional test + "./artifacts/${RUNWAY_VERSION}/$LOCAL_OS_NAME/runway" --version else - if [ "$OS_NAME" == "windows-latest" ]; then - 7z a -ttar -so ./runway.tar ./dist/runway/* | 7z a -si "./artifacts/${RUNWAY_VERSION}/${LOCAL_OS_NAME}/runway.tar.gz" - else - chmod +x dist/runway/runway-cli - # quick functional test - ./dist/runway/runway-cli --version - tar -C dist/runway/ -czvf ."/artifacts/${RUNWAY_VERSION}/${LOCAL_OS_NAME}/runway.tar.gz" . - fi + if [ "$OS_NAME" == "windows-latest" ]; then + 7z a -ttar -so ./runway.tar ./dist/runway/* | 7z a -si "./artifacts/${RUNWAY_VERSION}/${LOCAL_OS_NAME}/runway.tar.gz" # cspell:disable-line + else + chmod +x dist/runway/runway-cli + # quick functional test + ./dist/runway/runway-cli --version + tar -C dist/runway/ -czvf ."/artifacts/${RUNWAY_VERSION}/${LOCAL_OS_NAME}/runway.tar.gz" . # cspell:disable-line + fi fi diff --git a/.github/scripts/cicd/check_distance_from_tag.sh b/.github/scripts/cicd/check_distance_from_tag.sh index cce90fa3e..936eba261 100644 --- a/.github/scripts/cicd/check_distance_from_tag.sh +++ b/.github/scripts/cicd/check_distance_from_tag.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Checks for this distance from the last tag. -# If there is no distence, return a non-zero exit code. +# If there is no distance, return a non-zero exit code. # # This can be used in GitHub actions with the following steps using conditionals to handle either case. # @@ -20,10 +20,10 @@ DESCRIBE=`git describe --tags --match "v*.*.*"` echo "Result from 'git describe': ${DESCRIBE}" DISTANCE=`echo ${DESCRIBE} | grep -P '\-(\d)*\-g(\d)*'` if [ -n "${DISTANCE}" ]; then - echo "Distance from last tag detected: ${DISTANCE}" - echo "It is safe to proceed with a pre-production release." - exit 0 + echo "Distance from last tag detected: ${DISTANCE}" + echo "It is safe to proceed with a pre-production release." + exit 0 else - echo "No distance from last tag; skipping pre-production release." - exit 1 + echo "No distance from last tag; skipping pre-production release." + exit 1 fi diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index b9d593afa..0400f34b6 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -15,7 +15,7 @@ env: AWS_DEFAULT_REGION: us-east-1 AWS_MAX_ATTEMPTS: 20 # retry attempts for AWS API calls AWS_RETRY_MODE: adaptive # defaults to "legacy"; this handles more errors - NODE_VERSION: '18' + NODE_VERSION: '20' PYTEST_ADDOPTS: --color=yes RUNWAY_TEST_NAMESPACE: gh-${{ github.run_id }} PIPENV_IGNORE_VIRTUALENVS: '1' @@ -28,7 +28,8 @@ jobs: infra-test: ${{ steps.filter.outputs.infrastructure-test }} infra-test-alt: ${{ steps.filter.outputs.infrastructure-test-alt }} steps: - - uses: actions/checkout@v4 # not needed for pull_request + - name: ⤵️ Check out code from GitHub + uses: actions/checkout@v4 # not needed for pull_request if: | github.event_name == 'push' - uses: dorny/paths-filter@v3 # cspell:ignore dorny @@ -57,7 +58,7 @@ jobs: repo-head: ${{ steps.gh-context.outputs.repo-head }} # repo where change occurred repo-origin: ${{ steps.gh-context.outputs.repo-origin }} # origin of codebase steps: - - name: Output GitHub Context + - name: ℹ️ Output GitHub Context id: gh-context run: | export _REPO_ORIGIN="onicagroup/runway"; @@ -86,31 +87,21 @@ jobs: (needs.changes.outputs.infra-test == 'true' || needs.changes.outputs.infra-test-alt == 'true') runs-on: ubuntu-latest steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - id: setup-python - with: - python-version: 3.9 - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Configure AWS Credentials + poetry-plugins: poetry-dynamic-versioning + - name: 🏗 Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.DEPLOY_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.DEPLOY_AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - - run: make deploy test + - name: 🚀 Deploy to the test environment + run: make deploy test working-directory: infrastructure - - run: make deploy test-alt + - name: 🚀 Deploy to the test-alt environment + run: make deploy test-alt working-directory: infrastructure lint-python: name: Lint Python @@ -124,29 +115,21 @@ jobs: AWS_ACCESS_KEY_ID: test AWS_SECRET_ACCESS_KEY: test steps: - - name: Checkout Repo + - name: ⤵️ Check out code from GitHub uses: actions/checkout@v4 - - name: Install Node + - name: 🏗 Setup Node uses: actions/setup-node@v4 with: + cache: npm node-version: ${{ env.NODE_VERSION }} - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-plugins: poetry-dynamic-versioning python-version: ${{ matrix.python-version }} - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Install Node Dependencies + - name: ⤵️ Install Node Dependencies run: make npm-ci - - name: Run Linters + - name: 🚀 Run Linters run: make lint pre-commit: name: pre-commit @@ -155,22 +138,12 @@ jobs: matrix: python-version: ['3.10'] steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - id: setup-python - with: - python-version: ${{ matrix.python-version }} - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - uses: pre-commit/action@v3.0.1 + - name: ⤵️ Check out code from GitHub + uses: actions/checkout@v4 + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 + - name: 🚀 Run pre-commit + uses: pre-commit/action@v3.0.1 test-functional: name: Functional Tests needs: @@ -183,36 +156,29 @@ jobs: (needs.deploy-test-infrastructure.result == 'success' || needs.deploy-test-infrastructure.result == 'skipped') runs-on: ubuntu-latest steps: - - name: Checkout Repo + - name: ⤵️ Check out code from GitHub uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - name: 🏗 Setup Node + uses: actions/setup-node@v4 with: + cache: npm node-version: ${{ env.NODE_VERSION }} - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-plugins: poetry-dynamic-versioning python-version: '3.10' - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Install Ubuntu Dependencies + - name: ⤵️ Install Ubuntu Dependencies run: | sudo apt update -y sudo apt install -y default-libmysqlclient-dev libxml2-dev libxmlsec1-dev libxmlsec1-openssl pkg-config - - name: Configure AWS Credentials + - name: 🏗 Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.TEST_RUNNER_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.TEST_RUNNER_AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - - name: Run Tests + - name: 🚀 Run Tests run: make test-functional test-python: name: Test Python @@ -226,41 +192,33 @@ jobs: AWS_ACCESS_KEY_ID: test AWS_SECRET_ACCESS_KEY: test steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Install Node + - name: 🏗 Setup Node uses: actions/setup-node@v4 with: + cache: npm node-version: ${{ env.NODE_VERSION }} - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-plugins: poetry-dynamic-versioning python-version: ${{ matrix.python-version }} - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Install Node Dependencies + - name: ⤵️ Install Node Dependencies run: make npm-install - - name: Configure Pagefile # avoid MemoryError during tests + - name: 🏗 Configure Pagefile # avoid MemoryError during tests if: runner.os == 'Windows' uses: al-cheb/configure-pagefile-action@v1.4 # cspell:ignore cheb with: minimum-size: 16GB maximum-size: 16GB disk-root: 'C:' - - name: Run Integration & Unit Tests + - name: 🚀 Run Integration & Unit Tests # assertions assume linux so some fail when run on windows run: make test cov-xml - - name: Upload to Codecov + - name: ⤴️ Upload to Codecov uses: codecov/codecov-action@v4.5.0 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -271,34 +229,25 @@ jobs: - pre-commit runs-on: ubuntu-latest steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: - python-version: 3.9 + poetry-install: false + poetry-plugins: poetry-dynamic-versioning # Remove apt repos that are known to break from time to time # See https://github.com/actions/virtual-environments/issues/323 - name: Remove broken apt repos (ubuntu) run: | for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Install Dependencies (ubuntu) + - name: ⤵️ Install Dependencies (ubuntu) run: sudo apt-get update && sudo apt-get install sed -y - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Run Build + - name: 👷 Build run: make build - - name: Upload Distribution Artifact + - name: ⤴️ Upload distribution artifact uses: actions/upload-artifact@v4 with: name: pypi-dist diff --git a/.github/workflows/label-maker.yml b/.github/workflows/label-maker.yml index cef7692b5..4daf073f0 100644 --- a/.github/workflows/label-maker.yml +++ b/.github/workflows/label-maker.yml @@ -15,9 +15,9 @@ jobs: if: github.repository == 'onicagroup/runway' && github.actor != 'dependabot[bot]' runs-on: ubuntu-latest steps: - - name: Checkout + - name: ⤵️ Check out code from GitHub uses: actions/checkout@v4 - - name: Run Label Maker + - name: 🚀 Run Label Maker uses: crazy-max/ghaction-github-labeler@v5 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/on-pr-target-opened.yml b/.github/workflows/on-pr-target-opened.yml deleted file mode 100644 index c135e959b..000000000 --- a/.github/workflows/on-pr-target-opened.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: PR Target (opened) - - -on: - pull_request_target: - types: - - opened - - reopened - - -jobs: - assign-author: - name: Assign Author to PR - if: github.actor != 'dependabot[bot]' - runs-on: ubuntu-latest - steps: - - uses: technote-space/assign-author@v1 # cspell:ignore technote - label-pr: - name: Label PR - runs-on: ubuntu-latest - steps: - - uses: release-drafter/release-drafter@v6.0.0 - with: - disable-releaser: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml deleted file mode 100644 index b03eef6a9..000000000 --- a/.github/workflows/on-pr.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: PR - - -on: - pull_request: - - -jobs: - branch-name: - name: Enforce Branch Name - runs-on: ubuntu-latest - steps: - - uses: deepakputhraya/action-branch-name@v1.0.0 # cspell:ignore deepakputhraya - with: - regex: ([a-z])+\/([a-zA-Z0-9\-\_])+ - allowed_prefixes: bugfix,chore,depend,dependabot,docs,feat,feature,fix,hotfix,maint,maintain,maintenance,release - ignore: develop,master,release,v0_47_fixes diff --git a/.github/workflows/on-push-pyinstaller.yml b/.github/workflows/on-push-pyinstaller.yml index eb6f50d73..e2a26bfa2 100644 --- a/.github/workflows/on-push-pyinstaller.yml +++ b/.github/workflows/on-push-pyinstaller.yml @@ -31,13 +31,15 @@ jobs: # https://github.com/pyinstaller/pyinstaller/issues/4406 PIP_NO_BINARY: pydantic steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-install: false + poetry-plugins: poetry-dynamic-versioning python-version: ${{ matrix.python-version }} # Remove apt repos that are known to break from time to time # See https://github.com/actions/virtual-environments/issues/323 @@ -45,25 +47,15 @@ jobs: if: startsWith( matrix.os, 'ubuntu' ) run: | for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Install Dependencies (ubuntu) + - name: ⤵️ Install Dependencies (ubuntu) if: startsWith( matrix.os, 'ubuntu' ) run: sudo apt-get update && sudo apt-get install sed -y - - name: Install Dependencies (windows) + - name: ⤵️ Install Dependencies (windows) if: matrix.os == 'windows-latest' run: choco install make sed - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Run Build + - name: 👷 Build run: make build-pyinstaller-file - - name: Upload Artifacts + - name: ⤴️ Upload distribution artifact uses: actions/upload-artifact@v4 with: name: pyinstaller-onefile-${{ matrix.os }} @@ -81,13 +73,15 @@ jobs: # https://github.com/pyinstaller/pyinstaller/issues/4406 PIP_NO_BINARY: pydantic steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-install: false + poetry-plugins: poetry-dynamic-versioning python-version: ${{ matrix.python-version }} # Remove apt repos that are known to break from time to time # See https://github.com/actions/virtual-environments/issues/323 @@ -95,25 +89,15 @@ jobs: if: startsWith( matrix.os, 'ubuntu' ) run: | for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Install Dependencies (ubuntu) + - name: ⤵️ Dependencies (ubuntu) if: startsWith( matrix.os, 'ubuntu' ) run: sudo apt-get update && sudo apt-get install sed -y - - name: Install Dependencies (windows) + - name: ⤵️ Install Dependencies (windows) if: matrix.os == 'windows-latest' run: choco install make sed - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Run Build + - name: 👷 Build run: make build-pyinstaller-folder - - name: Upload Artifacts + - name: ⤴️ Upload distribution artifact uses: actions/upload-artifact@v4 with: name: pyinstaller-onefolder-${{ matrix.os }} @@ -124,7 +108,7 @@ jobs: needs: - build-pyinstaller-onefolder env: - NODE_VERSION: 18 + NODE_VERSION: 20 NPM_PACKAGE_NAME: '@onica/runway' strategy: fail-fast: false @@ -133,20 +117,23 @@ jobs: python-version: [3.9] runs-on: ${{ matrix.os }} steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - id: check_distance - name: Ensure Commit Is Not Tagged + name: 💂 Ensure Commit Is Not Tagged continue-on-error: true run: bash ./check_distance_from_tag.sh working-directory: .github/scripts/cicd - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-install: false + poetry-plugins: poetry-dynamic-versioning python-version: ${{ matrix.python-version }} - - uses: actions/setup-node@v4 + - name: 🏗 Setup Node + uses: actions/setup-node@v4 if: steps.check_distance.outcome == 'success' with: always-auth: true @@ -159,53 +146,43 @@ jobs: if: startsWith( matrix.os, 'ubuntu' ) run: | for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Install Dependencies (ubuntu) + - name: ⤵️ Install Dependencies (ubuntu) if: steps.check_distance.outcome == 'success' run: sudo apt-get update && sudo apt-get install sed tree -y - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Download Artifacts (macOS) + - name: ⤵️ Download distribution artifacts (macOS) if: steps.check_distance.outcome == 'success' uses: actions/download-artifact@v4 with: name: pyinstaller-onefolder-macos-12 path: artifacts - - name: Download Artifacts (ubuntu) + - name: ⤵️ Download distribution artifacts (ubuntu) if: steps.check_distance.outcome == 'success' uses: actions/download-artifact@v4 with: name: pyinstaller-onefolder-ubuntu-latest path: artifacts - - name: Download Artifacts (windows) + - name: ⤵️ Download distribution artifacts (windows) if: steps.check_distance.outcome == 'success' uses: actions/download-artifact@v4 with: name: pyinstaller-onefolder-windows-latest path: artifacts - - name: List Artifacts + - name: ℹ️ List artifacts if: steps.check_distance.outcome == 'success' run: tree artifacts/ - - name: npm Prep + - name: 👷 npm Prep if: steps.check_distance.outcome == 'success' run: make npm-prep - - name: npm pack + - name: 👷 Build if: steps.check_distance.outcome == 'success' run: | npm pack rm -rf artifacts && mkdir -p artifacts find . -name 'onica-runway-*.*.*.tgz' -exec mv {} artifacts/ \; - - name: Skipped Publishing + - name: ℹ️ Skipped Publishing if: steps.check_distance.outcome == 'failure' run: echo "A pre-production version was not published because the current commit is tagged for release." - - name: Upload Artifacts + - name: ⤴️ Upload distribution artifacts if: steps.check_distance.outcome == 'success' uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/pull_request_target.yml b/.github/workflows/pull_request_target.yml new file mode 100644 index 000000000..4e75abe08 --- /dev/null +++ b/.github/workflows/pull_request_target.yml @@ -0,0 +1,36 @@ +name: pull_request_target + +on: + pull_request_target: + +jobs: + assign-author-to-pr: + name: Assign Author to PR + if: ${{ !endswith(github.actor, '[bot]') && (github.event.action == 'opened' || github.event.action == 'reopened') }} + runs-on: ubuntu-latest + steps: + - uses: technote-space/assign-author@v1 # cspell:ignore technote + enforce-branch-name: + name: Enforce Branch Name + runs-on: ubuntu-latest + steps: + - name: 💂 Enforce Branch Name + uses: finleyfamily/action-enforce-branch-name@v1.0.0 + with: + allowed_prefixes: >- + bugfix,chore,dependabot,docs,feat,feature,fix,hotfix, + maint,maintain,maintenance,release,renovate,snyk + label-pr: + name: Label PR + if: ${{ github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'synchronize' }} + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: 🚀 Run Release Drafter + uses: release-drafter/release-drafter@v6 + with: + disable-releaser: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-management.yml b/.github/workflows/release-management.yml index 511f31bdb..0f36a5012 100644 --- a/.github/workflows/release-management.yml +++ b/.github/workflows/release-management.yml @@ -9,10 +9,13 @@ on: jobs: update_draft_release: name: Draft release + permissions: + contents: write runs-on: ubuntu-latest steps: # https://github.com/release-drafter/release-drafter - - uses: release-drafter/release-drafter@v6.0.0 + - name: 🚀 Run Release Drafter + uses: release-drafter/release-drafter@v6.0.0 env: # Using a PAT here will allow releases to trigger a build/release but # we're just using the actions token for the time being since we diff --git a/.github/workflows/publish-on-release.yml b/.github/workflows/release.yml similarity index 63% rename from .github/workflows/publish-on-release.yml rename to .github/workflows/release.yml index b259dfeb4..23349b58c 100644 --- a/.github/workflows/publish-on-release.yml +++ b/.github/workflows/release.yml @@ -25,13 +25,14 @@ jobs: # https://github.com/pyinstaller/pyinstaller/issues/4406 PIP_NO_BINARY: pydantic steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-plugins: poetry-dynamic-versioning python-version: ${{ matrix.python-version }} # Remove apt repos that are known to break from time to time # See https://github.com/actions/virtual-environments/issues/323 @@ -39,25 +40,15 @@ jobs: if: startsWith( matrix.os, 'ubuntu' ) run: | for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Install Dependencies (ubuntu) + - name: ⤵️ Install Dependencies (ubuntu) if: startsWith( matrix.os, 'ubuntu' ) run: sudo apt-get update && sudo apt-get install sed -y - - name: Install Dependencies (windows) + - name: ⤵️ Install Dependencies (windows) if: matrix.os == 'windows-latest' run: choco install make sed - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Run Build + - name: 👷 Build run: make build-pyinstaller-file - - name: Upload Artifacts + - name: ⤴️ Upload distribution artifacts uses: actions/upload-artifact@v4 with: name: pyinstaller-onefile-${{ matrix.os }} @@ -76,13 +67,14 @@ jobs: # https://github.com/pyinstaller/pyinstaller/issues/4406 PIP_NO_BINARY: pydantic steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-plugins: poetry-dynamic-versioning python-version: ${{ matrix.python-version }} # Remove apt repos that are known to break from time to time # See https://github.com/actions/virtual-environments/issues/323 @@ -90,25 +82,15 @@ jobs: if: startsWith( matrix.os, 'ubuntu' ) run: | for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Install Dependencies (ubuntu) + - name: ⤵️ Install Dependencies (ubuntu) if: startsWith( matrix.os, 'ubuntu' ) run: sudo apt-get update && sudo apt-get install sed -y - - name: Install Dependencies (windows) + - name: ⤵️ Install Dependencies (windows) if: matrix.os == 'windows-latest' run: choco install make sed - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Run Build + - name: 👷 Build run: make build-pyinstaller-folder - - name: Upload Artifacts + - name: ⤴️ Upload distribution artifact uses: actions/upload-artifact@v4 with: name: pyinstaller-onefolder-${{ matrix.os }} @@ -118,7 +100,7 @@ jobs: needs: - build-pyinstaller-onefolder env: - NODE_VERSION: 18 + NODE_VERSION: 20 NPM_PACKAGE_NAME: '@onica/runway' strategy: fail-fast: true @@ -127,15 +109,17 @@ jobs: python-version: [3.9] runs-on: ${{ matrix.os }} steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: + poetry-plugins: poetry-dynamic-versioning python-version: ${{ matrix.python-version }} - - uses: actions/setup-node@v4 + - name: 🏗 Setup Node + uses: actions/setup-node@v4 with: always-auth: true node-version: ${{ env.NODE_VERSION }} @@ -147,43 +131,33 @@ jobs: if: startsWith( matrix.os, 'ubuntu' ) run: | for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Install Dependencies (ubuntu) + - name: ⤵️ Install Dependencies (ubuntu) run: sudo apt-get update && sudo apt-get install sed tree -y - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Download Artifacts (macOS) + - name: ⤵️ Download distribution artifacts (macOS) uses: actions/download-artifact@v4 with: name: pyinstaller-onefolder-macos-12 path: artifacts - - name: Download Artifacts (ubuntu) + - name: ⤵️ Download distribution artifacts (ubuntu) uses: actions/download-artifact@v4 with: name: pyinstaller-onefolder-ubuntu-latest path: artifacts - - name: Download Artifacts (windows) + - name: ⤵️ Download distribution artifacts (windows) uses: actions/download-artifact@v4 with: name: pyinstaller-onefolder-windows-latest path: artifacts - - name: List Artifacts + - name: ℹ️ List Artifacts run: tree artifacts/ - - name: npm Prep + - name: 👷 npm Prep run: make npm-prep - - name: npm pack + - name: 👷 Build run: | npm pack rm -rf artifacts && mkdir -p artifacts find . -name 'onica-runway-*.*.*.tgz' -exec mv {} artifacts/ \; - - name: Upload Artifacts + - name: ⤴️ Upload distribution artifacts uses: actions/upload-artifact@v4 with: name: npm-pack @@ -194,7 +168,7 @@ jobs: - build-npm env: CI: true - NODE_VERSION: 18 + NODE_VERSION: 20 NPM_PACKAGE_NAME: '@onica/runway' NODE_AUTH_TOKEN: ${{ secrets.npm_api_token }} strategy: @@ -204,16 +178,17 @@ jobs: python-version: [3.9] runs-on: ${{ matrix.os }} steps: - - uses: actions/setup-node@v4 + - name: 🏗 Setup Node + uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} registry-url: https://registry.npmjs.org/ - - name: Download Artifact + - name: ⤵️ Download distribution artifact uses: actions/download-artifact@v4 with: name: npm-pack path: artifacts - - name: Publish Distribution 📦 to npm + - name: 🚀 Publish Distribution 📦 to npm env: NODE_AUTH_TOKEN: ${{ secrets.npm_api_token }} run: | @@ -222,34 +197,24 @@ jobs: name: Build PyPi 📦 runs-on: ubuntu-latest steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: - python-version: 3.9 + poetry-plugins: poetry-dynamic-versioning # Remove apt repos that are known to break from time to time # See https://github.com/actions/virtual-environments/issues/323 - name: Remove broken apt repos (ubuntu) run: | for apt_file in `grep -lr microsoft /etc/apt/sources.list.d/`; do sudo rm $apt_file; done - - name: Install Dependencies (ubuntu) + - name: ⤵️ Install Dependencies (ubuntu) run: sudo apt-get update && sudo apt-get install sed -y - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Run Build + - name: 👷 Build run: make build - - name: Upload Distribution Artifact + - name: ⤴️ Upload distribution artifact uses: actions/upload-artifact@v4 with: name: pypi-dist @@ -260,31 +225,21 @@ jobs: - build-pypi runs-on: ubuntu-latest steps: - - name: Checkout Repo (complete) + - name: ⤵️ Check out code from GitHub (complete) uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Download Distribution Artifact + - name: ⤵️ Download distribution artifact uses: actions/download-artifact@v4 with: name: pypi-dist path: dist - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: - python-version: 3.9 - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache - with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - run: make version - - name: Publish Distribution 📦 to PyPI + poetry-install: false + poetry-plugins: poetry-dynamic-versioning + - name: 🚀 Publish Distribution 📦 to PyPI env: POETRY_PYPI_TOKEN_PYPI: ${{ secrets.pypi_password }} run: poetry publish @@ -294,31 +249,31 @@ jobs: - build-pyinstaller-onefile env: AWS_DEFAULT_REGION: us-west-2 - AWS_S3_BUCKET: common-runway-assets-bucket83908e77-u2xp1bj1tuhp + AWS_S3_BUCKET: common-runway-assets-bucket83908e77-u2xp1bj1tuhp # cspell:ignore common-runway-assets-bucket83908e77-u2xp1bj1tuhp AWS_ACCESS_KEY_ID: ${{ secrets.aws_access_key }} AWS_SECRET_ACCESS_KEY: ${{ secrets.aws_secret_key }} runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v5 - id: setup-python + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: - python-version: 3.9 - - name: Download Artifacts (macOS) + poetry-install: false + - name: ⤵️ Download distribution artifacts (macOS) uses: actions/download-artifact@v4 with: name: pyinstaller-onefile-macos-12 path: artifacts - - name: Download Artifacts (ubuntu) + - name: ⤵️ Download distribution artifacts (ubuntu) uses: actions/download-artifact@v4 with: name: pyinstaller-onefile-ubuntu-latest path: artifacts - - name: Download Artifacts (windows) + - name: ⤵️ Download distribution artifacts (windows) uses: actions/download-artifact@v4 with: name: pyinstaller-onefile-windows-latest path: artifacts - - name: Install AWS CLI & Upload 📦 + - name: 🚀 Install AWS CLI & Upload 📦 run: | pip install "awscli~=1.18.19" aws s3 cp artifacts s3://$AWS_S3_BUCKET/runway/ --recursive --acl public-read @@ -334,29 +289,19 @@ jobs: VERSION: ${{ github.ref }} runs-on: ubuntu-latest steps: - - name: Checkout Repo + - name: ⤵️ Check out code from GitHub uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - id: setup-python - with: - python-version: 3.9 - - uses: Gr1N/setup-poetry@v9 - - uses: actions/cache@v4 - id: cache + - name: 🏗 Setup Python + uses: finleyfamily/action-setup-python@v1.0.0 with: - path: .venv - key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }} - - name: Ensure Cache Is Healthy - if: runner.os != 'Windows' && steps.cache.outputs.cache-hit == 'true' - run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv - - run: poetry install -vv - - name: Configure AWS Credentials + poetry-plugins: poetry-dynamic-versioning + - name: 🏗 Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.aws_access_key }} aws-secret-access-key: ${{ secrets.aws_secret_key }} aws-region: us-east-1 - - name: Run Script + - name: 🚀 Run Script working-directory: .github/scripts/urlshortener run: | poetry run python update_urls.py \ @@ -374,9 +319,10 @@ jobs: - update-urlshortener runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Microsoft Teams Notification - uses: skitionek/notify-microsoft-teams@v1.0.8 + - name: ⤵️ Check out code from GitHub + uses: actions/checkout@v4 + - name: 🚀 Microsoft Teams Notification + uses: skitionek/notify-microsoft-teams@v1.0.8 # cspell:ignore skitionek if: always() with: webhook_url: ${{ secrets.MSTEAMS_WEBHOOK }} diff --git a/.github/workflows/spell-check.yml b/.github/workflows/spell-check.yml index 4bfbf9370..fd45bcdd0 100644 --- a/.github/workflows/spell-check.yml +++ b/.github/workflows/spell-check.yml @@ -10,15 +10,20 @@ on: - master env: - NODE_VERSION: '18' + NODE_VERSION: '20' jobs: spell-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - name: ⤵️ Check out code from GitHub + uses: actions/checkout@v4 + - name: 🏗 Setup Node + uses: actions/setup-node@v4 with: + cache: npm node-version: ${{ env.NODE_VERSION }} - - run: make npm-ci - - run: make spellcheck + - name: ⤵️ Install Node Dependencies + run: make npm-ci + - name: 🚀 Run spellcheck + run: make spellcheck diff --git a/.readthedocs.yml b/.readthedocs.yml index bf2eee012..62bbf124f 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,37 +1,24 @@ -# .readthedocs.yml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details - -# Required version: 2 -# Set the version of Python and other tools you might need build: + os: ubuntu-24.04 + tools: + python: '3.12' jobs: post_create_environment: # Install poetry # https://python-poetry.org/docs/#installing-manually - pip install poetry + - poetry self add "poetry-dynamic-versioning[plugin]" + - poetry dynamic-versioning post_install: # Install dependencies with 'docs' dependency group # https://python-poetry.org/docs/managing-dependencies/#dependency-groups # VIRTUAL_ENV needs to be set manually for now. # See https://github.com/readthedocs/readthedocs.org/pull/11152/ - - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with docs,types - os: ubuntu-22.04 - tools: - python: '3.12' - -# Optionally build your docs in additional formats such as PDF and ePub -formats: all - -# Optionally declare the Python requirements required to build your docs -python: - install: - - method: pip - path: . - extra_requirements: - - docs + - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with docs # Build documentation in the docs/ directory with Sphinx sphinx: diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 6a7acece2..e95577a5a 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -1,4 +1,5 @@ { + "allowCompoundWords": true, "dictionaries": [ "local", "pypi", @@ -27,13 +28,26 @@ ], "ignorePaths": [ "**/*.egg-info/**", + "**/*.gzip", "**/*.js", "**/*.pyc", + "**/*.tar*", "**/*.ts", + "**/.cache", + "**/.envrc", + "**/.git", + ".devcontainer/files/.bash_completion", + "**/.gitignore", "**/.runway/**", + "**/.secret", "**/.serverless/**", + "**/.terraform.lock.hcl", "**/.terraform/**", "**/.venv/**", + "**/.vscode/cspell.json", + "**/.vscode/extensions.json", + "**/.vscode/launch.json", + "**/.vscode/settings.json", "**/Pipfile", "**/Pipfile.lock", "**/__pycache__/**", @@ -41,8 +55,7 @@ "**/angular.json", "**/artifacts/**", "**/build/**", - "**/build/**", - "**/dist/**", + "**/cdk.json", "**/dist/**", "**/dot_gitignore", "**/node_modules/**", diff --git a/Makefile b/Makefile index e00bbb94d..349e7d00a 100644 --- a/Makefile +++ b/Makefile @@ -1,37 +1,33 @@ -.PHONY: build clean docs help install lint list release test version +.PHONY: build clean docs help install lint list release test SHELL := /bin/bash +ifeq ($(CI), yes) + POETRY_OPTS = "-v" + PRE_COMMIT_OPTS = --show-diff-on-failure --verbose +endif help: ## show this message - @IFS=$$'\n' ; \ - help_lines=(`fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##/:/'`); \ - printf "%-30s %s\n" "target" "help" ; \ - printf "%-30s %s\n" "------" "----" ; \ - for help_line in $${help_lines[@]}; do \ - IFS=$$':' ; \ - help_split=($$help_line) ; \ - help_command=`echo $${help_split[0]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \ - help_info=`echo $${help_split[2]} | sed -e 's/^ *//' -e 's/ *$$//'` ; \ - printf '\033[36m'; \ - printf "%-30s %s" $$help_command ; \ - printf '\033[0m'; \ - printf "%s\n" $$help_info; \ - done - - -build: clean create-tfenv-ver-file version ## build the PyPi release - poetry build - -build-pyinstaller-file: clean create-tfenv-ver-file version ## build Pyinstaller single file release (github) + @awk \ + 'BEGIN {FS = ":.*##"; printf "\nUsage: make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-30s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' \ + $(MAKEFILE_LIST) + + +build: clean create-tfenv-ver-file ## build the PyPi release + @poetry build + +build-pyinstaller-file: clean create-tfenv-ver-file ## build Pyinstaller single file release (github) + @poetry dynamic-versioning bash ./.github/scripts/cicd/build_pyinstaller.sh file -build-pyinstaller-folder: clean create-tfenv-ver-file version ## build Pyinstaller folder release (github) +build-pyinstaller-folder: clean create-tfenv-ver-file ## build Pyinstaller folder release (github) + @poetry dynamic-versioning bash ./.github/scripts/cicd/build_pyinstaller.sh folder clean: ## remove generated file from the project directory rm -rf ./build/ ./dist/ ./src/ ./tmp/ ./runway.egg-info/; - rm -rf ./.pytest_cache + rm -rf ./.pytest_cache ./.venv; + find . -type d -name ".venv" -prune -exec rm -rf '{}' +; find . -type d -name "node_modules" -prune -exec rm -rf '{}' +; find . -type d -name ".runway" -prune -exec rm -rf '{}' +; find . -type f -name "*.py[co]" -delete; @@ -101,9 +97,10 @@ npm-install: ## run "npm install" with the option to ignore scripts - required t @npm install --ignore-scripts # copies artifacts to src & npm package files to the root of the repo -npm-prep: version ## process that needs to be run before creating an npm package +npm-prep: ## process that needs to be run before creating an npm package mkdir -p tmp mkdir -p src + npm version $$(poetry version --short) --allow-same-version --no-git-tag-version cp -r artifacts/$$(poetry version --short)/* src/ cp npm/* . && cp npm/.[^.]* . cp package.json tmp/package.json @@ -114,23 +111,27 @@ open-docs: ## open docs (HTML files must already exists) @make -C docs open run-pre-commit: ## run pre-commit for all files - @poetry run pre-commit run -a + @poetry run pre-commit run $(PRE_COMMIT_OPTS) \ + --all-files \ + --color always setup: setup-poetry setup-pre-commit setup-npm ## setup development environment setup-npm: npm-ci ## install node dependencies with npm setup-poetry: ## setup python virtual environment - @poetry install --sync + @poetry install $(POETRY_OPTS) --sync setup-pre-commit: ## install pre-commit git hooks @poetry run pre-commit install spellcheck: ## run cspell @echo "Running cSpell to checking spelling..." - @npx cspell "**/*" \ + @npm exec --no -- cspell lint . \ --color \ --config .vscode/cspell.json \ + --dot \ + --gitignore \ --must-find-files \ --no-progress \ --relative \ @@ -180,9 +181,3 @@ test-unit: ## run unit tests only --cov=runway \ --cov-config=tests/unit/.coveragerc \ --cov-report term-missing:skip-covered - -version: ## set project version using distance from last tag - @VERSION=$$(poetry run dunamai from git --style semver --no-metadata) && \ - echo setting version to $${VERSION}... && \ - poetry version $${VERSION} && \ - npm version $${VERSION} --allow-same-version --no-git-tag-version diff --git a/docs/source/conf.py b/docs/source/conf.py index 290fc2d3b..db5fe2eb3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -5,21 +5,28 @@ """ # noqa: INP001 import os +import sys from pathlib import Path -from dunamai import Style, Version +if sys.version_info < (3, 11): + import tomli as tomllib +else: + import tomllib DOCS_DIR = Path(__file__).parent.parent.resolve() ROOT_DIR = DOCS_DIR.parent SRC_DIR = DOCS_DIR / "source" +PYPROJECT_TOML = tomllib.loads((ROOT_DIR / "pyproject.toml").read_text()) +"""Read in the contents of ``../../pyproject.toml`` to reuse it's values.""" + # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -project = "Runway" +project = PYPROJECT_TOML["tool"]["poetry"]["name"].title() copyright = "2021, Onica Group" # noqa: A001 -author = "Onica Group" -release = Version.from_git().serialize(metadata=False, style=Style.SemVer) +author = PYPROJECT_TOML["tool"]["poetry"]["authors"][0] +release = PYPROJECT_TOML["tool"]["poetry"]["version"] version = ".".join(release.split(".")[:2]) # short X.Y version diff --git a/docs/source/developers/getting_started.rst b/docs/source/developers/getting_started.rst index 474b42d03..2892fad02 100644 --- a/docs/source/developers/getting_started.rst +++ b/docs/source/developers/getting_started.rst @@ -14,14 +14,21 @@ Before getting started, `fork this repo`_ and `clone your fork`_. Development Environment *********************** -This project includes an optional `VSCode Dev Container `__. This is an Ubuntu 22.04 image that will launch with operating system pre-requisites already installed and VSCode configured for Python debugging. It's not required to use this for development work, but does provide an easy and consistent way to get started. +This project includes an optional `VSCode Dev Container `__. +This is an Ubuntu 22.04 image that will launch with operating system pre-requisites already installed and VSCode configured for Python debugging. +It's not required to use this for development work, but does provide an easy and consistent way to get started. -This project uses `poetry `__ to create Python virtual environment. This must be installed on your system before setting up your dev environment. +This project uses poetry_ to create Python virtual environment. +This must be installed on your system before setting up your dev environment. +Additionally, the poetry-dynamic-versioning_ plugin should be installed. +Refer to the documentation of poetry-dynamic-versioning_ for how to install it based on how you installed poetry_. -With poetry installed, run ``make setup`` to setup your development environment. +With poetry_ installed, run ``make setup`` to setup your development environment. This will create all the required virtual environments to work on Runway, build docs locally, and run integration tests locally. The virtual environments all have Runway installed as editable meaning as you make changes to the code of your local clone, it will be reflected in all the virtual environments. +.. _poetry: https://python-poetry.org +.. _poetry-dynamic-versioning: https://github.com/mtkennerly/poetry-dynamic-versioning pre-commit ========== diff --git a/docs/source/runway_config.rst b/docs/source/runway_config.rst index eed27f6dc..461847831 100644 --- a/docs/source/runway_config.rst +++ b/docs/source/runway_config.rst @@ -47,8 +47,8 @@ Top-Level Configuration .. note:: The existence of ``DEPLOY_ENVIRONMENT`` in the environment will automatically ignore the git branch. .. attribute:: runway_version - :type: str - :value: ">=1.10.0" + :type: str | None + :value: None Define the versions of Runway that can be used with this configuration file. diff --git a/package-lock.json b/package-lock.json index 1aee53915..352093dd4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "runway", - "version": "2.0.0-dev", + "version": "0.0.0", "lockfileVersion": 2, "requires": true, "packages": { @@ -19,7 +19,8 @@ "devDependencies": { "cspell": "^8.13.2", "pyright": "^1.1.223" - } + }, + "version": "0.0.0" }, "node_modules/@cspell/cspell-bundled-dicts": { "version": "8.13.2", diff --git a/package.json b/package.json index be636da0d..99402eda6 100644 --- a/package.json +++ b/package.json @@ -55,5 +55,6 @@ "scripts": { "postinstall": "node ./postinstall.js", "preuninstall": "node ./preuninstall.js" - } + }, + "version": "0.0.0" } diff --git a/poetry.lock b/poetry.lock index eccb22a4e..6ebe88621 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1096,20 +1096,6 @@ files = [ {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, ] -[[package]] -name = "dunamai" -version = "1.22.0" -description = "Dynamic version generation" -optional = false -python-versions = ">=3.5" -files = [ - {file = "dunamai-1.22.0-py3-none-any.whl", hash = "sha256:eab3894b31e145bd028a74b13491c57db01986a7510482c9b5fff3b4e53d77b7"}, - {file = "dunamai-1.22.0.tar.gz", hash = "sha256:375a0b21309336f0d8b6bbaea3e038c36f462318c68795166e31f9873fdad676"}, -] - -[package.dependencies] -packaging = ">=20.9" - [[package]] name = "ecdsa" version = "0.18.0" @@ -3304,4 +3290,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = ">=3.9, <3.13" -content-hash = "c2bf0dfcf1f2093cf1c4ecad97d68c84738bf2c447fb7b94f67bdea7726c4a47" +content-hash = "509340a409a84ea437c99ac0b7d4e25bdad336db790a6d42630db61b69d1e8de" diff --git a/pyproject.toml b/pyproject.toml index bcc0541af..30b8ce012 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "runway" -version = "2.0.0-dev" # do not change +version = "0.0.0" authors = [ "Onica Group LLC ", ] @@ -65,7 +65,6 @@ yamllint = "*" [tool.poetry.group.dev.dependencies] coverage = {extras = ["toml"], version = ">=6.3"} doc8 = ">=0.10" # for linting with vscode rst extension -dunamai = "^1.5" mock = ">=4.0" moto = {extras = ["ec2", "ecs", "iam", "s3", "ssm"], version = ">=3.0"} pipenv = "^2022.1.8" # only used in tests @@ -82,7 +81,6 @@ testfixtures = "^7.0.3" # TODO remove use of this dependency - was inherited tomli-w = ">=1.0" [tool.poetry.group.docs.dependencies] -dunamai = "^1.5" jsx-lexer = "^1.0" sphinx = "^4.3" sphinx-github-changelog = "^1.1" @@ -173,6 +171,14 @@ omit = [ "*/type_defs.py", ] +[tool.poetry-dynamic-versioning] # poetry self add "poetry-dynamic-versioning[plugin]" +bump = true +enable = true +fix-shallow-repository = true +metadata = false +strict = true +style = "pep440" + [tool.pyright] exclude = [ "**/.demo", @@ -354,5 +360,5 @@ overrides."tool.poetry".first = ["name", "version"] overrides."tool.poetry.dependencies".first = ["python"] [build-system] -build-backend = "poetry.core.masonry.api" -requires = ["poetry_core>=1.0.7"] +build-backend = "poetry_dynamic_versioning.backend" +requires = ["poetry-core", "poetry-dynamic-versioning>=1.2.0,<2.0.0"] diff --git a/runway/__init__.py b/runway/__init__.py index 1a381e765..8f613a465 100644 --- a/runway/__init__.py +++ b/runway/__init__.py @@ -1,14 +1,23 @@ """Set package version.""" +from __future__ import annotations + import logging -from importlib.metadata import PackageNotFoundError, version # type: ignore from ._logging import LogLevels, RunwayLogger # noqa: F401 logging.setLoggerClass(RunwayLogger) -try: - __version__ = version(__name__) -except PackageNotFoundError: - # package is not installed - __version__ = "0.0.0" +__version__: str = "0.0.0" +"""Version of the Python package presented as a :class:`string`. + +Dynamically set upon release by `poetry-dynamic-versioning `__. + +""" + +__version_tuple__: tuple[int, int, int] | tuple[int, int, int, str] = (0, 0, 0) +"""Version of the Python package presented as a :class:`tuple`. + +Dynamically set upon release by `poetry-dynamic-versioning `__. + +""" diff --git a/runway/config/models/runway/__init__.py b/runway/config/models/runway/__init__.py index daef9a546..b6113e408 100644 --- a/runway/config/models/runway/__init__.py +++ b/runway/config/models/runway/__init__.py @@ -586,7 +586,7 @@ class RunwayConfigDefinitionModel(ConfigProperty): "current deploy environment.", ) runway_version: Optional[RunwayVersionField] = Field( - default=">1.10", + default=None, description="Define the versions of Runway that can be used with this " "configuration file.", examples=['"<2.0.0"', '"==1.14.0"', '">=1.14.0,<2.0.0"'], diff --git a/tests/unit/config/models/runway/test_runway.py b/tests/unit/config/models/runway/test_runway.py index 4d9d6c0f9..4697f5966 100644 --- a/tests/unit/config/models/runway/test_runway.py +++ b/tests/unit/config/models/runway/test_runway.py @@ -143,7 +143,7 @@ def test_field_defaults(self) -> None: assert obj.deployments == [] assert isinstance(obj.future, RunwayFutureDefinitionModel) assert not obj.ignore_git_branch - assert obj.runway_version == SpecifierSet(">1.10", prereleases=True) + assert obj.runway_version is None assert obj.tests == [] assert isinstance(obj.variables, RunwayVariablesDefinitionModel) diff --git a/tests/unit/core/test_core.py b/tests/unit/core/test_core.py index 8b53e49cd..79cbb9771 100644 --- a/tests/unit/core/test_core.py +++ b/tests/unit/core/test_core.py @@ -8,6 +8,7 @@ from unittest.mock import MagicMock, call import pytest +from packaging.specifiers import SpecifierSet from runway.core import Runway @@ -44,6 +45,7 @@ def test___init___undetermined_version( ) -> None: """Test __init__ with unsupported version.""" monkeypatch.setattr(MODULE + ".__version__", "0.1.0-dev1") + runway_config.runway_version = SpecifierSet(">=1.10") caplog.set_level(logging.WARNING, logger=MODULE) assert Runway(runway_config, runway_context) # type: ignore assert "shallow clone of the repo" in "\n".join(caplog.messages) @@ -56,6 +58,7 @@ def test___init___unsupported_version( ) -> None: """Test __init__ with unsupported version.""" monkeypatch.setattr(MODULE + ".__version__", "1.3") + runway_config.runway_version = SpecifierSet(">=1.10") with pytest.raises(SystemExit) as excinfo: assert not Runway(runway_config, runway_context) # type: ignore assert excinfo.value.code == 1 diff --git a/tests/unit/factories.py b/tests/unit/factories.py index ffa454c26..c4fb0b3e4 100644 --- a/tests/unit/factories.py +++ b/tests/unit/factories.py @@ -286,7 +286,7 @@ def __init__(self, **kwargs: Any) -> None: self.future = MagicMock() self.tests = [] self.ignore_git_branch = False - self.runway_version = SpecifierSet(">=1.10", prereleases=True) + self.runway_version = SpecifierSet(">=0.0.0", prereleases=True) self.variables = MutableMap() # classmethods