1+ name : Create and Publish idaes-examples PyPI package
2+
3+ on :
4+ push :
5+ tags :
6+ - " *"
7+
8+ defaults :
9+ run :
10+ shell : bash -l {0}
11+
12+ env :
13+ PYTEST_ADDOPTS : --color=yes
14+ PIP_PROGRESS_BAR : " off"
15+ PYTHON_VERSION : " 3.12"
16+ PACKAGE_NAME : " idaes-examples"
17+
18+ jobs :
19+ build :
20+ runs-on : ubuntu-latest
21+
22+ steps :
23+ - name : Checkout code to be packaged
24+ uses : actions/checkout@v6
25+
26+ - name : Set up Python
27+ uses : actions/setup-python@v6
28+ with :
29+ python-version : ${{ env.PYTHON_VERSION }}
30+
31+ - name : Generate dist files
32+ run : |
33+ pip install build wheel
34+
35+ # We only build wheel because adding sdist can push package past PyPI 100 MB limit
36+ python -m build --wheel --outdir dist/
37+
38+ - name : Check that the dist directory's size is below PyPI's maximum
39+ run : |
40+ ls -lh dist/*
41+ _maxsize=100000 # 100 MB
42+ _dirsize=$(du -s dist/ | cut -f 1) ; echo $_dirsize
43+ echo "::notice title=dist::Total size of dist/ directory is $_dirsize kB"
44+ [ "$_dirsize" -lt "$_maxsize" ]
45+
46+ - name : Upload dist files as artifact
47+ uses : actions/upload-artifact@v7
48+ with :
49+ name : dist
50+ path : dist/
51+ retention-days : 1
52+
53+ test-whl :
54+ needs : [build]
55+ name : Test idaes-examples from .whl file
56+ runs-on : ubuntu-latest
57+
58+ steps :
59+ - uses : actions/download-artifact@v8
60+ with :
61+ name : dist
62+ path : dist
63+
64+ - name : Set up Python
65+ uses : actions/setup-python@v6
66+ with :
67+ python-version : ${{ env.PYTHON_VERSION }}
68+
69+ - name : Install from .whl file
70+ run : |
71+ ls -lh dist/
72+ whl_file="$(ls dist/*.whl)"
73+ echo "$whl_file"
74+ pip install "${whl_file}"
75+
76+ - name : Check that installed package has the expected tag
77+ run : |
78+ pip install packaging
79+ python -c '
80+ import sys
81+ from importlib.metadata import version
82+ from packaging.version import Version
83+
84+ name = sys.argv[1]
85+ tag = sys.argv[2]
86+ normalized_tag = str(Version(tag))
87+ pkg_version = version(name)
88+
89+ print(f"{name=}\n{tag=}\n{normalized_tag=}\n{pkg_version=}")
90+ assert pkg_version == normalized_tag
91+ ' "idaes-examples" "${{ github.ref_name }}"
92+
93+ - name : Run tests
94+ working-directory : /tmp
95+ run : |
96+ python -c 'from importlib.metadata import version; print(version("idaes-examples"))'
97+
98+ upload-test-pypi :
99+ needs : [test-whl]
100+ runs-on : ubuntu-latest
101+ permissions :
102+ id-token : write
103+ environment : test-release
104+
105+ steps :
106+ - uses : actions/download-artifact@v8
107+ with :
108+ name : dist
109+ path : dist
110+
111+ - name : Upload dist files to TestPyPI
112+ uses : pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b
113+ with :
114+ repository-url : https://test.pypi.org/legacy/
115+
116+ install-test-pypi :
117+ runs-on : ubuntu-latest
118+ needs : [upload-test-pypi]
119+
120+ steps :
121+ - name : Set up Python
122+ uses : actions/setup-python@v6
123+ with :
124+ python-version : ${{ env.PYTHON_VERSION }}
125+
126+ - name : Install idaes-examples==${{ github.ref_name }} from TestPyPI
127+ env :
128+ _wait_time_s : 15
129+ _pip_install_flags : --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/
130+ _pip_install_target : idaes-examples==${{ github.ref_name }}
131+ run : |
132+ until pip install $_pip_install_flags "$_pip_install_target"
133+ do
134+ echo "pip install failed; waiting $_wait_time_s seconds"
135+ sleep "$_wait_time_s"
136+ done
137+
138+ - name : Run tests
139+ run : |
140+ python -c 'from importlib.metadata import version; print(version("idaes-examples"))'
141+
142+ upload-pypi :
143+ needs : [install-test-pypi]
144+ runs-on : ubuntu-latest
145+ permissions :
146+ id-token : write
147+ environment : release
148+
149+ steps :
150+ - uses : actions/download-artifact@v8
151+ with :
152+ name : dist
153+ path : dist
154+
155+ - name : Upload dist files to PyPI
156+ uses : pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b
157+
158+ env-snapshot :
159+ name : Create and collect env snapshot
160+ needs : [upload-pypi]
161+ runs-on : ubuntu-latest
162+ permissions :
163+ contents : write
164+ env :
165+ ENV_NAME : idaes-examples-${{ github.ref_name }}
166+ OUTPUT_DIR : idaes-examples-${{ github.ref_name }}
167+
168+ steps :
169+ - name : Set up Conda environment with Python
170+ uses : conda-incubator/setup-miniconda@v4
171+ with :
172+ miniforge-version : latest
173+ activate-environment : ${{ env.ENV_NAME }}
174+ python-version : ${{ env.PYTHON_VERSION }}
175+
176+ - name : Install idaes-examples==${{ github.ref_name }}[idaes,omlt]
177+ run : |
178+ pip install "idaes-examples[idaes,omlt]==${{ github.ref_name }}"
179+
180+ - name : Create output directory
181+ run : mkdir "$OUTPUT_DIR"
182+
183+ - name : Save environment info (requirements.txt)
184+ working-directory : ${{ env.OUTPUT_DIR }}
185+ run : |
186+ pip freeze > requirements.txt
187+ cat requirements.txt
188+
189+ - name : Save environment info (environment.yml)
190+ working-directory : ${{ env.OUTPUT_DIR }}
191+ run : |
192+ conda env export \
193+ -n "$ENV_NAME" \
194+ --no-builds \
195+ -f environment.yml
196+ cat environment.yml
197+
198+ - name : List output directory contents
199+ run : ls -la "$OUTPUT_DIR/"
200+
201+ - name : Save as workflow artifact
202+ uses : actions/upload-artifact@v7
203+ with :
204+ name : ${{ env.ENV_NAME }}
205+ path : ${{ env.OUTPUT_DIR }}/
206+ if-no-files-found : error
207+ retention-days : 90
208+
209+ - name : Upload to GitHub Release
210+ uses : softprops/action-gh-release@v3
211+ with :
212+ files : |
213+ ${{ env.OUTPUT_DIR }}/requirements.txt
214+ ${{ env.OUTPUT_DIR }}/environment.yml
0 commit comments