1+ name : CI Build Reusable Workflow
2+ on :
3+ workflow_call :
4+ secrets :
5+ GH_TOKEN :
6+ description : ' GitHub token for authentication'
7+ required : true
8+ PYPI_TOKEN :
9+ description : ' PyPI API token to publish package'
10+ required : false
11+ inputs :
12+ UPLOAD_PACKAGE :
13+ description : ' Should the package be uploaded to PyPI?'
14+ required : false
15+ default : false
16+ type : boolean
17+ REPOSITORY_NAME :
18+ description : ' Repository name'
19+ required : false
20+ type : string
21+ BRANCH_NAME :
22+ description : ' Branch name to checkout'
23+ required : true
24+ type : string
25+ PYTHON_VERSION :
26+ description : ' Python version to use'
27+ required : false
28+ default : ' 3.10.11'
29+ type : string
30+ PUSH_TAG :
31+ description : ' Push tag after version bump'
32+ required : false
33+ default : false
34+ type : boolean
35+ RELEASE_BUILD :
36+ description : ' Is release build?'
37+ required : false
38+ default : false
39+ type : boolean
40+ GIT_USER :
41+ description : ' Git user name for commit and tag'
42+ required : true
43+ type : string
44+ GIT_EMAIL :
45+ description : ' Git user email for commit and tag'
46+ required : true
47+ type : string
48+ PROJECT_NAME :
49+ description : ' Project name for tests'
50+ required : true
51+ type : string
52+ SOURCE_PATH :
53+ description : ' Path to the source code directory'
54+ required : false
55+ default : ' src'
56+ type : string
57+ RUNS_ON :
58+ description : ' Runner type for the job'
59+ required : false
60+ default : ' ubuntu-latest'
61+ type : string
62+
63+ jobs :
64+ build_whl :
65+ permissions :
66+ id-token : write
67+ environment :
68+ name : " pypi"
69+ url : https://pypi.org/p/${{ inputs.PROJECT_NAME }}
70+ runs-on : ${{ inputs.RUNS_ON }}
71+ steps :
72+ - uses : actions/checkout@v4
73+ with :
74+ fetch-tags : true
75+ fetch-depth : 0
76+ path : ${{ inputs.SOURCE_PATH }}
77+ ref : ${{ inputs.BRANCH_NAME }}
78+
79+ - name : Set up Python
80+ uses : actions/setup-python@v5
81+ with :
82+ python-version : ${{ inputs.PYTHON_VERSION }}
83+ cache : ' pip'
84+
85+ - name : Version bumping
86+ id : VERSION_BUMP
87+ env :
88+ GIT_AUTHOR_NAME : ${{ inputs.GIT_USER }}
89+ GIT_AUTHOR_EMAIL : ${{ inputs.GIT_EMAIL }}
90+ GIT_COMMITTER_NAME : ${{ inputs.GIT_USER }}
91+ GIT_COMMITTER_EMAIL : ${{ inputs.GIT_EMAIL }}
92+ shell : bash
93+ run : |
94+ python -m pip install --upgrade pip
95+ python -m venv bump_version
96+ source bump_version/bin/activate
97+ pip install python-semantic-release~=10.2
98+ pip install -r ${{ inputs.SOURCE_PATH }}/requirements-dev.txt
99+ pip install ./${{ inputs.SOURCE_PATH }}
100+ mfd-create-config-files --project-dir ./${{ inputs.SOURCE_PATH }}
101+ cd ${{ inputs.SOURCE_PATH }}
102+ version_after_bump=$(semantic-release version --print | tail -n 1 | tr -d '\n')
103+ version_from_tag=$(git describe --tags --abbrev=0 | tr -d '\n' | sed 's/^v//')
104+ echo "Version after semantic-release bump is: ${version_after_bump}"
105+ echo "Version from tag: ${version_from_tag}"
106+ if [ "$version_after_bump" == "$version_from_tag" ]; then
107+ echo "Version would not change: version_after_bump=${version_after_bump}, version_from_tag=${version_from_tag}"
108+ exit 1
109+ fi
110+ semantic-release version --no-push --no-vcs-release
111+ cat pyproject.toml
112+ echo "version_after_bump=v${version_after_bump}" >> $GITHUB_OUTPUT
113+ - name : Create virtual environment for whl creation
114+ shell : bash
115+ run : |
116+ python -m venv whl_creation
117+ source whl_creation/bin/activate
118+ pip install build==1.2.2.post1
119+ cd ${{ inputs.SOURCE_PATH }}
120+ ../whl_creation/bin/python -m build --wheel --outdir ../whl_creation/dist
121+ ls -l ../whl_creation/dist
122+
123+ - name : Determine if unit and functional tests should run
124+ id : test_check
125+ shell : bash
126+ run : |
127+ # Extract repo name from PROJECT_NAME (format: org/repo)
128+ REPO_NAME=$(echo "${{ inputs.PROJECT_NAME }}" | awk -F'/' '{print $2}')
129+ UNIT_TEST_DIR="${{ inputs.SOURCE_PATH }}/tests/unit/test_$(echo "${REPO_NAME}" | tr '-' '_')"
130+ FUNC_TEST_DIR="${{ inputs.SOURCE_PATH }}/tests/system/test_$(echo "${REPO_NAME}" | tr '-' '_')"
131+ if [ -d "$UNIT_TEST_DIR" ]; then
132+ echo "Unit tests directory exists: $UNIT_TEST_DIR"
133+ echo "run_unit_tests=true" >> $GITHUB_OUTPUT
134+ else
135+ echo "Unit tests directory does not exist: $UNIT_TEST_DIR"
136+ echo "run_unit_tests=false" >> $GITHUB_OUTPUT
137+ fi
138+ if [ -d "$FUNC_TEST_DIR" ]; then
139+ echo "Functional tests directory exists: $FUNC_TEST_DIR"
140+ echo "run_functional_tests=true" >> $GITHUB_OUTPUT
141+ else
142+ echo "Functional tests directory does not exist: $FUNC_TEST_DIR"
143+ echo "run_functional_tests=false" >> $GITHUB_OUTPUT
144+ fi
145+
146+ - name : Install dependencies for tests
147+ if : steps.test_check.outputs.run_unit_tests == 'true' || steps.test_check.outputs.run_functional_tests == 'true'
148+ shell : bash
149+ run : |
150+ python -m venv test_env
151+ source test_env/bin/activate
152+ python -m pip install -r "${{ inputs.SOURCE_PATH }}/requirements.txt" -r "${{ inputs.SOURCE_PATH }}/requirements-test.txt" -r "${{ inputs.SOURCE_PATH }}/requirements-dev.txt"
153+ python -m pip install ./${{ inputs.SOURCE_PATH }}
154+
155+ - name : Run unit tests if test directory exists
156+ if : steps.test_check.outputs.run_unit_tests == 'true'
157+ shell : bash
158+ run : |
159+ source test_env/bin/activate
160+ mfd-unit-tests --project-dir ${{ github.workspace }}/${{ inputs.SOURCE_PATH }}
161+
162+ - name : Run functional tests if test directory exists
163+ if : steps.test_check.outputs.run_functional_tests == 'true'
164+ shell : bash
165+ run : |
166+ source test_env/bin/activate
167+ mfd-system-tests --project-dir ${{ github.workspace }}/${{ inputs.SOURCE_PATH }}
168+ - name : Publish package distributions to PyPI
169+ if : ${{ inputs.RELEASE_BUILD == true && inputs.UPLOAD_PACKAGE == true }}
170+ uses : pypa/gh-action-pypi-publish@release/v1
171+ with :
172+ packages-dir : ' whl_creation/dist/*.whl'
173+ password : ${{ secrets.PYPI_TOKEN }}
174+
175+ - name : Publish comment how to build .whl
176+ if : inputs.RELEASE_BUILD == false
177+ uses : actions/github-script@v7
178+ with :
179+ github-token : ${{ secrets.GH_TOKEN }}
180+ script : |
181+ const prNumber = context.payload.pull_request.number;
182+ const commentBody = "We don't publish DEVs .whl.\n To build .whl, run 'pip install git+https://github.com/${{ inputs.REPOSITORY_NAME }}@${{ inputs.BRANCH_NAME }}'";
183+ await github.rest.issues.createComment({
184+ owner: context.repo.owner,
185+ repo: context.repo.repo,
186+ issue_number: prNumber,
187+ body: commentBody
188+ });
189+
190+ - name : Push git tag after version bump
191+ if : ${{ inputs.RELEASE_BUILD == true && inputs.PUSH_TAG == true }}
192+ shell : bash
193+ env :
194+ GIT_AUTHOR_NAME : ${{ inputs.GIT_USER }}
195+ GIT_AUTHOR_EMAIL : ${{ inputs.GIT_EMAIL }}
196+ GIT_COMMITTER_NAME : ${{ inputs.GIT_USER }}
197+ GIT_COMMITTER_EMAIL : ${{ inputs.GIT_EMAIL }}
198+ version_after_bump : ${{ steps.VERSION_BUMP.outputs.version_after_bump }}
199+ run : |
200+ cd ${{ inputs.SOURCE_PATH }}
201+ git push origin "${version_after_bump}"
0 commit comments