Skip to content

Integration

Integration #432

Workflow file for this run

name: Integration
on:
push:
branches:
- '*_rel'
schedule:
# run daily at 5:00 am UTC (12 am ET/9 pm PT)
- cron: '0 5 * * *'
repository_dispatch:
# to run this, send a POST API call at repos/IDAES/idaes-pse/dispatches with the specified event_type
# e.g. `gh repos/IDAES/idaes-pse/dispatches -F event_type=ci_run_integration`
types: [ci_run_integration]
workflow_dispatch:
inputs:
git-ref:
description: Git hash (optional)
required: false
pull_request:
types:
- labeled
- synchronize
pull_request_review:
types:
- submitted
concurrency:
# NOTE: the value of `group` should be chosen carefully,
# otherwise we might end up over- or under-canceling workflow runs
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true
env:
IDAES_CONDA_ENV_NAME_DEV: idaes-pse-dev
PYTEST_ADDOPTS: "--color=yes"
DEFAULT_PYTHON_VERSION: '3.10'
defaults:
run:
# -l: login shell, needed when using Conda run:
shell: bash -l {0}
jobs:
precheck:
name: (util) Check if should run
runs-on: ubuntu-20.04
# the ">-" YAML syntax will result in a single string without terminating newline
# it is used here to make the relatively complex if clause more readable by adding line breaks
if: >-
(
(
github.event.action == 'labeled'
&& contains(github.event.label.description, 'triggers_workflow')
&& contains(github.event.label.description, github.workflow)
)
|| (
github.event.action == 'submitted'
&& github.event.review.state == 'APPROVED'
)
|| github.event.action == 'synchronize'
|| !contains(github.event_name, 'pull_request')
)
outputs:
is-pr-approved: ${{ steps.check-pr-approval.outputs.is-approved }}
workflow-trigger: ${{ steps.determine-trigger.outputs.workflow-trigger }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/display-debug-info
- id: check-pr-approval
uses: ./.github/actions/check-pr-approval
if: contains(github.event_name, 'pull_request')
with:
number: ${{ github.event.pull_request.number }}
- name: Process intermediate steps outputs
run: |
jq . <<EOF
${{ toJSON(steps) }}
EOF
echo "steps.check-pr-approval.outputs.is-approved=${{ steps.check-pr-approval.outputs.is-approved }}"
# make "is_pr_approved" available to next steps as an env variable
echo "is_pr_approved=${{ steps.check-pr-approval.outputs.is-approved }}" >> $GITHUB_ENV
- id: determine-trigger
name: Determine workflow trigger
env:
_GITHUB_EVENT_ACTION: ${{ github.event.action }}
shell: python {0}
run: |
import json
from os import environ as env
def _display_on_run_dashboard(msg):
# workflow warnings are displayed on the workflow run dashboard,
# so we use this as a way to display a short summary of why this workflow is being run
# without having to dig in each job's log output
print(f'::warning ::{msg}')
def _set_output(name, val):
print(f'::set-output name={name}::{val}')
event_name = env["GITHUB_EVENT_NAME"]
event_action = env["_GITHUB_EVENT_ACTION"]
is_pr = 'pull_request' in event_name.lower()
# if the event is not a PR event, the "is_pr_approved" env var will be set to an empty string,
# which cannot be parsed as valid json
is_pr_approved = json.loads(env.get("is_pr_approved") or "null")
workflow_trigger = 'undetermined'
if is_pr:
if event_action == 'labeled':
workflow_trigger = 'user_dispatch'
elif is_pr_approved is True:
workflow_trigger = 'approved_pr'
elif is_pr_approved is False:
workflow_trigger = 'unapproved_pr'
else:
workflow_trigger = 'not_pr'
msg = f'{workflow_trigger=} event/action={event_name}/{event_action or "N/A"} is_pr_approved={is_pr_approved or "N/A"}'
_display_on_run_dashboard(msg)
_set_output('workflow-trigger', workflow_trigger)
pytest:
name: pytest (py${{ matrix.python-version }}/${{ matrix.os }}/integration)
runs-on: ${{ matrix.runner-image }}
needs: [precheck]
if: >-
(
needs.precheck.outputs.workflow-trigger == 'user_dispatch'
|| needs.precheck.outputs.workflow-trigger == 'not_pr'
|| needs.precheck.outputs.workflow-trigger == 'approved_pr'
)
strategy:
fail-fast: false
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
os:
- linux
- win64
include:
- os: linux
runner-image: ubuntu-20.04
- os: win64
runner-image: windows-2022
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/display-debug-info
- name: Set up Conda environment
uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: ${{ env.IDAES_CONDA_ENV_NAME_DEV }}
python-version: ${{ matrix.python-version }}
- name: Set up idaes
uses: ./.github/actions/setup-idaes
with:
install-target: -r requirements-dev.txt
- name: Run pytest (integration)
run: pytest --pyargs idaes -m integration
examples:
name: Run examples (py${{ matrix.python-version }}/${{ matrix.os }})
runs-on: ${{ matrix.runner-image }}
needs: [precheck]
if: >-
(
needs.precheck.outputs.workflow-trigger == 'user_dispatch'
|| needs.precheck.outputs.workflow-trigger == 'not_pr'
|| needs.precheck.outputs.workflow-trigger == 'approved_pr'
)
strategy:
fail-fast: false
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
os:
- linux
- win64
include:
- os: linux
runner-image: ubuntu-20.04
- os: win64
runner-image: windows-2022
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/display-debug-info
- name: Set up Conda environment
uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: ${{ env.IDAES_CONDA_ENV_NAME_DEV }}
python-version: ${{ matrix.python-version }}
- name: Set up idaes
uses: ./.github/actions/setup-idaes
with:
install-target: -r requirements-dev.txt
- name: Fetch and run examples
uses: ./.github/actions/run-examples
with:
examples-repository: IDAES/examples
examples-ref: main
reinstall-target: -r requirements-dev.txt
notebook-cell-exec-timeout: '600'
working-dir: ${{ runner.temp }}
pytest-site-packages:
name: Run tests from site-packages (non-editable) installation (${{ matrix.install-mode }}/${{ matrix.os }})
# NOTE: using ubuntu-latest (20.04) instead of 18.04 results in failures in power_generation/carbon_capture/mea_solvent_system/unit_models/tests/test_column.py
runs-on: ${{ matrix.runner-image }}
needs: [precheck]
if: >-
(
needs.precheck.outputs.workflow-trigger == 'user_dispatch'
|| needs.precheck.outputs.workflow-trigger == 'not_pr'
|| needs.precheck.outputs.workflow-trigger == 'approved_pr'
)
strategy:
fail-fast: false
matrix:
install-mode:
- pip-default
- pip-complete
- pip-all
- conda-like
os:
- linux
include:
- os: linux
runner-image: ubuntu-20.04
- install-mode: pip-default
pip-install-target: '.'
- install-mode: pip-complete
pip-install-target: .[ui,dmf,grid]
- install-mode: pip-all
pip-install-target: .[ui,dmf,grid,omlt,coolprop]
- install-mode: conda-like
pip-install-target: '.'
dependencies-to-uninstall: omlt
steps:
- uses: actions/checkout@v4
- name: Set up Conda environment
uses: conda-incubator/setup-miniconda@v3
with:
activate-environment: idaes-env
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
- name: Set up idaes (non-editable installation)
uses: ./.github/actions/setup-idaes
with:
install-target: ${{ matrix.pip-install-target }}
- name: Remove dependencies installable with pip but not with conda
# NOTE some dependencies that are installed by default with pip are not available through conda
# so they're not installed if IDAES is installed with `conda -c conda-forge -c IDAES-PSE idaes-pse`
# to ensure this scenario is handled properly, since we don't have (yet) the conda-build process integrated with the CI,
# we manually remove the "pip-but-not-conda" dependencies after installing with pip
# as an approximation of the enviroment that we'd get from `conda install`
if: matrix.dependencies-to-uninstall
run: |
pip uninstall --yes ${{ matrix.dependencies-to-uninstall }}
- name: Install and run pytest in empty directory
run: |
pushd "$(mktemp -d)"
pip install pytest
pytest --pyargs idaes -W ignore -rs