Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable GitHub Actions #746

Merged
merged 1 commit into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 230 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
name: Run all checks for pull requests

on:
pull_request:
branches:
- main
workflow_dispatch:
inputs:
ref:
description: 'The git ref to build the package for'
required: false
default: ''
type: string

# Precompute the ref if the workflow was triggered by a workflow dispatch rather than copying this logic repeatedly
env:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || null }}

jobs:
eval:
name: Evaluate changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
name: Checkout repository
with:
ref: ${{ env.ref }}
fetch-depth: 2

# We want to enforce the following rules for PRs:
# * if all modifications are to README.md
# no testing is needed
# * if there are modifications to docs/* or to any code
# then docs need to be built to verify consistency
# * if there are modifications to notebooks/* or to any code
# then notebooks need to be run to verify consistency
# * for any code changes (or changes to metadata files)
# linting and testing should be run
# For a PR build, HEAD will be the merge commit, and we want to diff against the base branch,
# which will be the first parent: HEAD^
# (For non-PR changes, we will always perform all CI tasks)
# Note that GitHub Actions provides path filters, but they operate at the workflow level, not the job level
- run: |
if ($env:GITHUB_EVENT_NAME -eq 'pull_request') {
$editedFiles = git diff HEAD^ --name-only
$editedFiles # echo edited files to enable easier debugging
$codeChanges = $false
$docChanges = $false
$nbChanges = $false
$changeType = "none"
foreach ($file in $editedFiles) {
switch -Wildcard ($file) {
"README.md" { Continue }
".gitignore" { Continue }
"econml/_version.py" { Continue }
"prototypes/*" { Continue }
"images/*" { Continue }
"doc/*" { $docChanges = $true; Continue }
"notebooks/*" { $nbChanges = $true; Continue }
default { $codeChanges = $true; Continue }
}
}
}
echo "buildDocs=$(($env:GITHUB_EVENT_NAME -ne 'pull_request') -or ($docChanges -or $codeChanges))" >> $env:GITHUB_OUTPUT
echo "buildNbs=$(($env:GITHUB_EVENT_NAME -ne 'pull_request') -or ($nbChanges -or $codeChanges))" >> $env:GITHUB_OUTPUT
echo "testCode=$(($env:GITHUB_EVENT_NAME -ne 'pull_request') -or $codeChanges)" >> $env:GITHUB_OUTPUT
shell: pwsh
name: Determine type of code change
id: eval
outputs:
buildDocs: ${{ steps.eval.outputs.buildDocs }}
buildNbs: ${{ steps.eval.outputs.buildNbs }}
testCode: ${{ steps.eval.outputs.testCode }}

lint:
name: Lint code
needs: [eval]
if: ${{ needs.eval.outputs.testCode == 'True' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
name: Checkout repository
with:
ref: ${{ env.ref }}
- uses: actions/setup-python@v4
name: Setup Python
with:
python-version: 3.9
- run: python -m pip install --upgrade pip && pip install --upgrade setuptools
name: Ensure latest pip and setuptools
- run: 'pip install pycodestyle && pycodestyle econml'

notebooks:
name: Run notebooks
needs: [eval]
if: ${{ needs.eval.outputs.buildNbs == 'True' }}
runs-on: ubuntu-latest
strategy:
matrix:
kind: [except customer scenarios, customer scenarios]
include:
- kind: "except customer scenarios"
extras: "[tf,plt]"
pattern: "(?!CustomerScenarios)"
install_graphviz: true
version: 3.8 # no supported version of tensorflow for 3.9
- kind: "customer scenarios"
extras: "[plt,dowhy]"
pattern: "CustomerScenarios"
version: 3.9
install_graphviz: false
fail-fast: false
steps:
- uses: actions/checkout@v3
name: Checkout repository
with:
ref: ${{ env.ref }}
- uses: actions/setup-python@v4
name: Setup Python
with:
python-version: ${{ matrix.version }}
- run: python -m pip install --upgrade pip && pip install --upgrade setuptools
name: Ensure latest pip and setuptools
- run: sudo apt-get -yq install graphviz
name: Install graphviz
if: ${{ matrix.install_graphviz }}
- run: pip install -e .${{ matrix.extras }}
name: Install econml
- run: pip install pytest pytest-runner jupyter jupyter-client nbconvert nbformat seaborn xgboost tqdm
name: Install test and notebook requirements
- run: pip list
name: List installed packages
- run: python setup.py pytest
name: Run notebook tests
env:
PYTEST_ADDOPTS: '-m "notebook"'
NOTEBOOK_DIR_PATTERN: ${{ matrix.pattern }}

tests:
name: "Run tests"
needs: [eval]
if: ${{ needs.eval.outputs.testCode == 'True' }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: [3.6, 3.7, 3.8, 3.9]
kind: [serial, other, dml, main, treatment]
exclude:
# Serial tests fail randomly on mac sometimes, so we don't run them there
- os: macos-latest
kind: serial
# Python 3.6 isn't supported on ubuntu-latest
- os: ubuntu-latest
python-version: 3.6

# Assign the correct package and testing options for each kind of test
include:
- kind: serial
opts: '-m "serial" -n 1'
extras: "[tf,plt]"
- kind: other
opts: '-m "cate_api" -n auto'
extras: "[tf,plt]"
- kind: dml
opts: '-m "dml"'
extras: "[tf,plt]"
- kind: main
opts: '-m "not (notebook or automl or dml or serial or cate_api or treatment_featurization)" -n 2'
extras: "[tf,plt,dowhy]"
- kind: treatment
opts: '-m "treatment_featurization" -n auto'
extras: "[tf,plt]"
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
name: Checkout repository
with:
ref: ${{ env.ref }}
- uses: actions/setup-python@v4
name: Setup Python
with:
python-version: ${{ matrix.python-version }}
- run: python -m pip install --upgrade pip && pip install --upgrade setuptools
name: Ensure latest pip and setuptools
- run: pip install -e .${{ matrix.extras }}
name: Install econml
- run: pip install pytest pytest-runner coverage
name: Install pytest
- run: python setup.py pytest
name: Run tests
env:
PYTEST_ADDOPTS: ${{ matrix.opts }}
COVERAGE_PROCESS_START: 'setup.cfg'
# todo: publish test results, coverage info

build:
name: Build package
needs: [eval]
if: ${{ needs.eval.outputs.testCode == 'True' }}
uses: ./.github/workflows/publish-package.yml
with:
publish: false
repository: testpypi
# don't have access to env context here for some reason
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || null }}

docs:
name: Build documentation
needs: [eval]
if: ${{ needs.eval.outputs.buildDocs == 'True' }}
uses: ./.github/workflows/publish-documentation.yml
with:
publish: false
environment: test
# don't have access to env context here for some reason
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || null }}

verify:
name: Verify CI checks
needs: [lint, notebooks, tests, build, docs]
if: always()
runs-on: ubuntu-latest
steps:
- run: exit 1
name: At least one check failed or was cancelled
if: ${{ !(success()) }}
- run: exit 0
name: All checks passed
if: ${{ success() }}
80 changes: 80 additions & 0 deletions .github/workflows/publish-documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Build and publish the documentation
on:
workflow_dispatch:
inputs:
publish:
description: 'Whether to publish the documentation (as opposed to just building it)'
required: false
default: true
type: boolean
environment:
description: 'Whether to publish to production or test environment'
required: false
default: prod
type: choice
options: [prod, test]
ref:
description: 'The git ref to build the documentation for'
required: false
default: ''
type: string
# annoyingly, there does not seem to be a way to share these input definitions between triggers
workflow_call:
inputs:
publish:
description: 'Whether to publish the documentation (as opposed to just building it)'
required: false
default: true
type: boolean
# choice type only supported for workflow_dispatch, not workflow_call
environment:
description: 'Whether to publish to production or test environment'
required: false
default: prod
type: string
ref:
description: 'The git ref to build the documentation for'
required: false
default: ''
type: string


jobs:
create_docs:
name: Create and publish documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
name: Checkout repository
with:
ref: ${{ inputs.ref }}
- uses: actions/setup-python@v4
name: Setup Python
with:
python-version: 3.8 # because of our supported TensorFlow versions, must build on 3.6-3.8
- run: python -m pip install --upgrade pip && pip install --upgrade setuptools
name: Ensure latest pip and setuptools
- run: pip install -U cython && pip install -e .[all]
name: Install econml[all]
- run: sudo apt-get -yq install graphviz
name: Install graphviz
- run: pip install "sphinx~=4.4.0" "sphinx_rtd_theme~=1.0.0" && python setup.py build_sphinx -W
name: Build documentation
- uses: actions/upload-artifact@v3
name: Upload docs as artifact
with:
name: docs
path: build/sphinx/html/
- run: |-
pushd build/sphinx/html
zip -r docs.zip *
popd
name: Zip docs for publishing
if : ${{ inputs.publish }}
- uses: azure/webapps-deploy@v2
name: Deploy documentation to Azure web app
with:
app-name: ${{ inputs.environment == 'prod' && 'econml' || 'econml-dev' }}
package: build/sphinx/html/docs.zip
publish-profile: ${{ inputs.environment == 'prod' && secrets.PROD_WEBAPP_PUBLISH_PROFILE || secrets.STAGING_WEBAPP_PUBLISH_PROFILE }}
if: ${{ inputs.publish }}
Loading