Skip to content

fix: close widget before STK shutdown #3117

fix: close widget before STK shutdown

fix: close widget before STK shutdown #3117

Workflow file for this run

name: pull-request
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
env:
ANSYS_STK: 'ansys-stk'
DOCUMENTATION_CNAME: 'stk.docs.pyansys.com'
LICENSE_SERVER_PORT: '1055'
MAIN_PYTHON_VERSION: '3.13'
MINIMUM_PYTHON_VERSION: '3.10'
PYSTK_DIR: '/home/stk/pystk'
QUARTO_VERSION: '1.5.55'
STK_DOCKER_IMAGE: 'ansys/stk-13.0:dev-ubuntu22.04'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Apply the principle of least privilege to state at job level the right
# permissions. More information about workflow permissions in the page
# https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#permissions
permissions: {}
jobs:
labeler:
name: "Labels"
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
if: |
!contains(github.event.pull_request.labels.*.name, 'ci:skip') &&
github.event.type != 'labeled'
steps:
- name: "Checkout repository"
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
clean: true
persist-credentials: false
- name: "Update labels"
uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c # v1.3.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Label pull-request"
uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
changelog-fragment:
name: "Create changelog fragment"
needs: labeler
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: ansys/actions/doc-changelog@c2fa7c93f6883114e0e643599431b33d29f0b13f # v10.1.4
with:
token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }}
use-conventional-commits: true
use-default-towncrier-config: true
bot-user: ${{ secrets.PYANSYS_CI_BOT_USERNAME }}
bot-email: ${{ secrets.PYANSYS_CI_BOT_EMAIL }}
vulnerabilities:
name: "Vulnerabilities"
runs-on: ubuntu-latest
needs: labeler
permissions:
contents: read
steps:
- uses: ansys/actions/check-vulnerabilities@c2fa7c93f6883114e0e643599431b33d29f0b13f # v10.1.4
with:
python-version: ${{ env.MAIN_PYTHON_VERSION }}
python-package-name: ${{ env.ANSYS_STK }}
token: ${{ secrets.PYANSYS_CI_BOT_TOKEN }}
dev-mode: true
actions-style:
name: "Actions style checks"
runs-on: ubuntu-latest
if: |
!contains(github.event.pull_request.labels.*.name, 'ci:skip') &&
!contains(github.event.pull_request.labels.*.name, 'style:skip')
needs: vulnerabilities
permissions:
contents: read
steps:
- uses: ansys/actions/check-actions-security@c2fa7c93f6883114e0e643599431b33d29f0b13f # v10.1.4
with:
generate-summary: true
token: ${{ secrets.GITHUB_TOKEN }}
auditing-level: 'high'
trust-ansys-actions: true
code-style:
name: "Code style checks"
runs-on: ubuntu-latest
if: |
!contains(github.event.pull_request.labels.*.name, 'ci:skip') &&
!contains(github.event.pull_request.labels.*.name, 'style:skip')
needs: actions-style
permissions:
contents: read
steps:
- uses: ansys/actions/code-style@c2fa7c93f6883114e0e643599431b33d29f0b13f # v10.1.4
with:
python-version: ${{ env.MAIN_PYTHON_VERSION }}
doc-style:
name: "Doc style checks"
runs-on: ubuntu-latest
if: |
!contains(github.event.pull_request.labels.*.name, 'ci:skip') &&
!contains(github.event.pull_request.labels.*.name, 'style:skip')
needs: actions-style
steps:
- name: "Checkout project"
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
clean: true
persist-credentials: false
- name: "Install jq"
run: |
# Used to format Vale input as a JSON-formatted list of files
sudo apt install -y jq
- name: "Collect desired files"
id: vale
run: |
# Find all .rst files excluding those in doc/source/api/
rst_files=$(find doc/source -type f -name "*.rst" ! -path "doc/source/api/*")
# Find all .py files inside the examples/ directory, excluding those with an underscore
python_files=$(find examples -type f -name "*.py" ! -name "*_*")
# TODO: include Python files too. See Vale issue
# https://github.com/errata-ai/vale/issues/858
# Combine both file lists and convert them to a JSON array
# vale_files=$(echo -e "${rst_files}\n${python_files}" | jq -R . | jq -s .)
vale_files=$(echo -e "${rst_files}" | jq -R . | jq -s .)
echo "files=$(jq -c <<< "${vale_files}")" >> "${GITHUB_OUTPUT}"
- uses: ansys/actions/doc-style@c2fa7c93f6883114e0e643599431b33d29f0b13f # v10.1.4
with:
checkout: false
files: '${{ steps.vale.outputs.files }}'
vale-config: doc/.vale.ini
token: ${{ secrets.GITHUB_TOKEN }}
fail-level: 'warning'
build-wheelhouse:
name: "Wheelhouse ansys-stk[${{ matrix.target }}] / ${{ matrix.os }} / ${{ matrix.python-version }}"
runs-on: ${{ matrix.os }}
needs: [code-style, doc-style]
permissions:
attestations: write
contents: read
id-token: write
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.10', '3.11', '3.12', '3.13']
target: ['core', 'extensions', 'grpc', 'jupyter', 'migration', 'all']
steps:
- uses: ansys/actions/build-wheelhouse@c2fa7c93f6883114e0e643599431b33d29f0b13f # v10.1.4
with:
library-name: ${{ env.ANSYS_STK }}
operating-system: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
target: ${{ matrix.target }}
attest-provenance: true
doc-build:
name: "Doc build"
runs-on: ${{ matrix.runner }}
needs: build-wheelhouse
if: |
!contains(github.event.pull_request.labels.*.name, 'ci:skip') &&
!contains(github.event.pull_request.labels.*.name, 'docs:skip')
# Limitations with one line GitHub actions conditionals forces us to use a
# matrix strategy. If examples execution is required, a self-hosted runner
# is selected. Otherwise, a GitHub runner is used.
strategy:
matrix:
runner: [ubuntu-latest, [self-hosted, pystk]]
needs-self-hosted-runner:
- ${{ contains(github.event.pull_request.labels.*.name, 'docs:examples') }}
exclude:
- needs-self-hosted-runner: false
runner: [self-hosted, pystk]
- needs-self-hosted-runner: true
runner: ubuntu-latest
timeout-minutes: 360
permissions:
contents: read
steps:
- name: "Checkout the project"
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
clean: true
persist-credentials: false
- name: "Install Python ${{ env.MAIN_PYTHON_VERSION }}"
if: |
!contains(github.event.pull_request.labels.*.name, 'docs:examples')
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.MAIN_PYTHON_VERSION }}
- name: "Download wheelhouse into static path"
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
path: "doc/source/_static/wheelhouse"
pattern: "*-wheelhouse-*"
- name: "Display the wheelhouse layout"
run: |
tree doc/source/_static/wheelhouse
- name: "Generate the name of the Docker image and the container"
if: |
contains(github.event.pull_request.labels.*.name, 'docs:examples')
id: docker
env:
RUNNER: ${{ runner.name }}
run: |
image_name="${STK_DOCKER_IMAGE}-python${MAIN_PYTHON_VERSION}"
container_name="stk-python${MAIN_PYTHON_VERSION}-${RUNNER}"
echo "image=${image_name}" >> "${GITHUB_OUTPUT}"
echo "container=${container_name}" >> "${GITHUB_OUTPUT}"
- name: "Start the container from the desired image"
if: |
contains(github.event.pull_request.labels.*.name, 'docs:examples')
env:
STK_IMAGE: ${{ steps.docker.outputs.image }}
STK_CONTAINER: ${{ steps.docker.outputs.container }}
LICENSE_SERVER: ${{ secrets.LICENSE_SERVER }}
run: |
docker run \
--detach -it \
--network="host" \
--name="${STK_CONTAINER}" \
--env ANSYSLMD_LICENSE_FILE="${LICENSE_SERVER_PORT}@${LICENSE_SERVER}" \
--volume ${PWD}:/home/stk/pystk \
"${STK_IMAGE}"
- name: "Install system dependencies required for building examples"
if: |
contains(github.event.pull_request.labels.*.name, 'docs:examples')
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--user root \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"apt update && apt install -y wget pandoc"
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"wget --no-check-certificate https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.deb"
docker exec \
--user root \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"dpkg -i quarto-${QUARTO_VERSION}-linux-amd64.deb"
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"quarto install tinytex"
- name: "Install Tox in the GitHub runner or the self-hosted runner"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
NEEDS_SELF_HOSTED_RUNNER: ${{ contains(github.event.pull_request.labels.*.name, 'docs:examples') }}
run: |
if [[ "${NEEDS_SELF_HOSTED_RUNNER}" == "true" ]]; then
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"python -m pip install --upgrade pip tox && rm -rf .tox"
else
python --version
python -m pip install --upgrade pip tox && rm -rf .tox
fi
# Render the documentation including or excluding different sections
# according to the labels of the pull-request.
- name: "Build docs including the 'Examples' section"
id: build-doc-with-examples
if: |
contains(github.event.pull_request.labels.*.name, 'docs:examples') &&
!contains(github.event.pull_request.labels.*.name, 'docs:api')
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export BUILD_API=false BUILD_EXAMPLES=true && tox -e doc-clean,doc-links,doc-html"
- name: "Build docs including the 'API' section"
id: build-doc-with-api
if: |
contains(github.event.pull_request.labels.*.name, 'docs:api') &&
!contains(github.event.pull_request.labels.*.name, 'docs:examples')
run: |
python -m tox -e doc-clean,doc-links,doc-html
env:
BUILD_API: true
BUILD_EXAMPLES: false
- name: "Build docs excluding 'API' and 'Examples' sections"
id: build-doc-minimum
if: |
!contains(github.event.pull_request.labels.*.name, 'docs:examples') &&
!contains(github.event.pull_request.labels.*.name, 'docs:api')
run: |
python -m tox -e doc-clean,doc-links,doc-html
env:
BUILD_API: false
BUILD_EXAMPLES: false
- name: "Build docs including 'API' and 'Examples' sections"
id: build-doc-full
if: |
contains(github.event.pull_request.labels.*.name, 'docs:examples') &&
contains(github.event.pull_request.labels.*.name, 'docs:api')
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export BUILD_API=true BUILD_EXAMPLES=true && tox -e doc-clean,doc-links,doc-html"
# If required, combine partially rendered documentation with the nightly
# build artifacts. Upload the generated documentation as an artifact in
# the CI/CD session.
- name: "Download latest API docs"
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
if: steps.build-doc-full.outcome == 'skipped'
with:
ref: "gh-pages"
path: "gh-pages"
persist-credentials: false
- name: "Include 'API' section from nightly build docs"
if: |
steps.build-doc-with-examples.outcome == 'success' ||
steps.build-doc-minimum.outcome == 'success'
run: |
cp gh-pages/version/dev/api.html doc/_build/html/api.html
cp -r gh-pages/version/dev/api doc/_build/html/api
- name: "Include 'Examples' section from nightly build docs"
if: |
steps.build-doc-with-api.outcome == 'success' ||
steps.build-doc-minimum.outcome == 'success'
run: |
cp -r gh-pages/version/dev/_images/* doc/_build/html/_images
cp gh-pages/version/dev/examples.html doc/_build/html/examples.html
cp -r gh-pages/version/dev/examples doc/_build/html/examples
- name: "Include 'search.json' section from nightly build docs"
if: |
steps.build-doc-with-api.outcome == 'success' ||
steps.build-doc-with-examples.outcome == 'success' ||
steps.build-doc-minimum.outcome == 'success'
run:
cp gh-pages/version/dev/_static/search.json doc/_build/html/_static/search.json
- name: "Upload HTML documentation artifacts"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
path: doc/_build/html
name: documentation-html
- name: "Stop the container"
if: always()
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
NEEDS_SELF_HOSTED_RUNNER: ${{ contains(github.event.pull_request.labels.*.name, 'docs:examples') }}
run: |
if [[ "${NEEDS_SELF_HOSTED_RUNNER}" == "true" ]]; then
docker stop "${STK_CONTAINER}"
docker logs "${STK_CONTAINER}"
docker rm "${STK_CONTAINER}"
fi
tests:
name: "Tests Python ${{ matrix.python }}"
runs-on: [self-hosted, pystk]
if: |
!contains(github.event.pull_request.labels.*.name, 'ci:skip') &&
!contains(github.event.pull_request.labels.*.name, 'tests:skip')
needs: code-style
strategy:
matrix:
# Tests run against Python 3.10 to ensure backwards compatibility with
# the lowest supported Python version. Testing against a single version
# minimizes the time for CI/CD runs.
#
# Can not use ${{ env.MINIMUM_PYTHON_VERSION }} because GitHub actions
# does not support ENV variable substitution in matrix definition
python: ['3.10']
fail-fast: false
steps:
- name: "Checkout the project"
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
clean: true
persist-credentials: false
- name: "Generate the name of the Docker image and the container"
id: docker
env:
PYTHON_VERSION: ${{ matrix.python }}
RUNNER: ${{ runner.name }}
run: |
image_name="${STK_DOCKER_IMAGE}-python${PYTHON_VERSION}"
container_name="stk-python${PYTHON_VERSION}-${RUNNER}"
echo "image=${image_name}" >> "${GITHUB_OUTPUT}"
echo "container=${container_name}" >> "${GITHUB_OUTPUT}"
- name: "Start the container from the desired image"
env:
STK_IMAGE: ${{ steps.docker.outputs.image }}
STK_CONTAINER: ${{ steps.docker.outputs.container }}
LICENSE_SERVER: ${{ secrets.LICENSE_SERVER }}
run: |
docker run \
--detach -it \
--network="host" \
--name="${STK_CONTAINER}" \
--env ANSYSLMD_LICENSE_FILE="${LICENSE_SERVER_PORT}@${LICENSE_SERVER}" \
--volume ${PWD}:/home/stk/pystk \
"${STK_IMAGE}"
- name: "Install the project with the testing dependencies"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"python -m pip install --upgrade pip tox && rm -rf .tox"
- name: "Install coverage dependencies"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"python -m pip install --group tests ."
- name: "Run the extensions tests"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export COVERAGE_FILE=.cov/extensions && tox -e tests-extensions-cov"
- name: "Run the API migration assistant tests"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export COVERAGE_FILE=.cov/migration && tox -e tests-core-migration-cov"
- name: "Run the aviator tests"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export COVERAGE_FILE=.cov/aviator && tox -e tests-core-aviator-graphics-cov-linux"
- name: "Run the non graphics stk tests"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export COVERAGE_FILE=.cov/stknogfx && tox -e tests-core-stk-nographics-cov-linux"
- name: "Run the graphics only stk tests"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export COVERAGE_FILE=.cov/stkgfx && tox -e tests-core-stk-graphicsonly-cov-linux"
- name: "Run the vgt tests"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export COVERAGE_FILE=.cov/vgt && tox -e tests-core-vgt-graphics-cov-linux"
- name: "Run the doc snippet tests"
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"export COVERAGE_FILE=.cov/snippets && tox -e tests-core-snippets-graphics-cov-linux"
# -- Coverage
- name: "Combine all coverage results"
if: ${{ matrix.python == env.MINIMUM_PYTHON_VERSION }}
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR}/.cov \
"${STK_CONTAINER}" /bin/bash -c \
"export COVERAGE_FILE=coverage && coverage combine aviator stknogfx stkgfx vgt snippets migration extensions"
- name: "Generate coverage report in XML and HTML"
if: ${{ matrix.python == env.MINIMUM_PYTHON_VERSION }}
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"coverage html --rcfile pyproject.toml --data-file=.cov/coverage --directory=.cov/${ANSYS_STK}-coverage --fail-under=89"
docker exec \
--workdir ${PYSTK_DIR} \
"${STK_CONTAINER}" /bin/bash -c \
"coverage xml --rcfile pyproject.toml --data-file=.cov/coverage -o .cov/coverage.xml"
- name: "Upload ${{ env.ANSYS_STK }} coverage results"
if: ${{ matrix.python == env.MINIMUM_PYTHON_VERSION }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
path: .cov/${{ env.ANSYS_STK }}-coverage
name: ${{ env.ANSYS_STK }}-coverage
- name: "Upload coverage reports to Codecov"
if: ${{ matrix.python == env.MINIMUM_PYTHON_VERSION }}
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
with:
files: .cov/coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
- name: "Stop the container"
if: always()
env:
STK_CONTAINER: ${{ steps.docker.outputs.container }}
run: |
docker stop "${STK_CONTAINER}"
docker logs "${STK_CONTAINER}"
docker rm "${STK_CONTAINER}"
build-library:
name: "Build library"
runs-on: ubuntu-latest
needs: [doc-build, tests]
permissions:
attestations: write
contents: read
id-token: write
steps:
- uses: ansys/actions/build-library@c2fa7c93f6883114e0e643599431b33d29f0b13f # v10.1.4
with:
library-name: ${{ env.ANSYS_STK }}
attest-provenance: true