Skip to content

on-demand-deployment #158

on-demand-deployment

on-demand-deployment #158

name: on-demand-deployment
on:
release:
types: [edited]
jobs:
setup:
if: github.repository == 'MusculoskeletalAtlasProject/mapclient'
runs-on: ubuntu-24.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
run-installer: ${{ steps.set-matrix.outputs.run-installer }}
package: ${{ steps.set-matrix.outputs.run-packaging }}
tag: ${{ steps.get-tag.outputs.tag }}
steps:
- name: Get the tag
id: get-tag
shell: bash
run: |
echo "Setting tag as: ${GITHUB_REF#refs/tags/}"
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Get the release name
id: get-release-name
shell: bash
run: |
tag=${{ steps.get-tag.outputs.tag }}
bare_tag=${tag/v/}
IFS='.' read -ra bare_tag_parts <<< "$bare_tag"
name="${bare_tag_parts[0]}.${bare_tag_parts[1]}.${bare_tag_parts[2]}"
echo "Setting name as: ${name}"
echo "name=$name" >> $GITHUB_OUTPUT
- name: Determine required assets
id: set-variants
shell: cmake -P {0}
run: |
set(RELEASE_BODY "${{ github.event.release.body }}")
string(REPLACE "\n" ";" _PARTS "${RELEASE_BODY}")
set(VARIANTS)
foreach(_PART ${_PARTS})
string(STRIP "${_PART}" _PART)
string(REGEX MATCH "\\[odd release ([A-Za-z0-9-]+)\\]" _MATCHED_OUTPUT "${_PART}")
if (_MATCHED_OUTPUT)
set(VARIANTS "${VARIANTS} ${CMAKE_MATCH_1}")
endif()
endforeach()
message(STATUS "variants=\"${VARIANTS}\"")
file(APPEND $ENV{GITHUB_OUTPUT} "variants=\"${VARIANTS}\"")
- name: set_matrix
id: set-matrix
shell: bash
run: |
matrixElements=()
variants=${{ steps.set-variants.outputs.variants }}
for v in $variants; do
matrixElements+=('{"os":"windows-2019","variant":"'$v'","tag":"${{ steps.get-tag.outputs.tag }}","release-name":"${{ steps.get-release-name.outputs.name }}","python-version":"3.9"}')
matrixElements+=('{"os":"macos-13","variant":"'$v'","tag":"${{ steps.get-tag.outputs.tag }}","release-name":"${{ steps.get-release-name.outputs.name }}","python-version":"3.10"}')
done
if [ "${#matrixElements[@]}" -eq "0" ]; then
echo run-installer=false >> $GITHUB_OUTPUT
echo run-packaging=false >> $GITHUB_OUTPUT
else
echo run-installer=true >> $GITHUB_OUTPUT
echo run-packaging=true >> $GITHUB_OUTPUT
fi
function join_by { local IFS="$1"; shift; echo "$*"; }
content=`join_by , ${matrixElements[@]}`
echo "{\"include\":[$content]}"
echo "matrix={\"include\":[$content]}" >> $GITHUB_OUTPUT
pypipackage:
needs: setup
name: PyPIPackage
if: needs.setup.outputs.package == 'true'
runs-on: ubuntu-24.04
steps:
- name: Checkout codebase
uses: actions/checkout@v4
with:
ref: ${{ needs.setup.outputs.tag }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Set target url
id: target-url
run: |
if [ '${{ github.event.release.prerelease }}' = 'true' ]; then
url="https://test.pypi.org/legacy/"
version="${{ needs.setup.outputs.tag }}"
echo "__version__ = '${version:1}'" > src/mapclient/settings/version.py
else
url="https://upload.pypi.org/legacy/"
fi
echo "url: $url"
echo pypi-url=$url >> $GITHUB_OUTPUT
- name: Create package
run: |
cat src/mapclient/settings/version.py
pip install --upgrade pip
pip install build
pip install -e src/
pip list
python -m build --wheel src/
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ steps.target-url.outputs.pypi-url == 'https://upload.pypi.org/legacy/' && secrets.PYPI_API_TOKEN || secrets.TEST_PYPI_API_TOKEN }}
repository-url: ${{ steps.target-url.outputs.pypi-url }}
packages-dir: src/dist/
skip-existing: true
installer:
needs: setup
name: installer
if: needs.setup.outputs.run-installer == 'true'
runs-on: ${{ matrix.os }}
strategy:
matrix: ${{fromJson(needs.setup.outputs.matrix)}}
steps:
- name: Install create-dmg (macOS)
if: runner.os == 'macOS'
shell: bash
run: brew install create-dmg
- name: Import Certificates (macOS)
uses: apple-actions/import-codesign-certs@v3
if: runner.os == 'macOS'
with:
p12-file-base64: ${{ secrets.APPLE_DEV_APP_CERT }}
p12-password: ${{ secrets.APPLE_DEV_APP_CERT_PASSWORD }}
- name: Save secret to file (Windows)
if: runner.os == 'Windows'
env:
EV_CERTIFICATE_PFX_BASE64: ${{ secrets.WIN_EV_CERTIFICATE_PFX_BASE64 }}
shell: bash
run: |
echo -n $EV_CERTIFICATE_PFX_BASE64 | base64 -d - > ./ev_certificate.pfx
#dotnet tool install --global AzureSignTool
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Checkout codebase
uses: actions/checkout@v4
with:
ref: ${{ needs.setup.outputs.tag }}
path: mapclient
- name: Setup scripts
uses: actions/checkout@v4
with:
repository: hsorby/mapclientreleasescripts
path: scripts
- name: Setup Python virtual environment
id: python-environment
shell: bash
run: |
echo "Creating application asset"
python -m venv venv
if [ "$RUNNER_OS" == "macOS" ]; then
python_exe=$GITHUB_WORKSPACE/venv/bin/python
pip_exe=$GITHUB_WORKSPACE/venv/bin/pip
# source venv/bin/activate
elif [ "$RUNNER_OS" == "Windows" ]; then
python_exe=$GITHUB_WORKSPACE/venv/Scripts/python.exe
pip_exe=$GITHUB_WORKSPACE/venv/Scripts/pip.exe
# source venv/Scripts/activate
else
echo "$RUNNER_OS not supported"
exit 1
fi
cd mapclient
echo "==============================================="
echo "=== setting extensions.worktreeconfig false ==="
echo "====== because Dulwich cannot handle it. ======"
echo "==============================================="
git config extensions.worktreeconfig false
echo "---=---"
git config --list
cd ..
python_exe=${python_exe//\\//}
echo "python_exe=$python_exe"
echo "python_exe=$python_exe" >> $GITHUB_OUTPUT
pip_exe=${pip_exe//\\//}
echo "pip_exe=$pip_exe"
echo "pip_exe=$pip_exe" >> $GITHUB_OUTPUT
- name: Create application asset
id: create-application
shell: bash
run: |
echo "Creating application asset"
if [ "${{ matrix.variant }}" == "standard" ]; then
variant=
else
variant="-${{ matrix.variant }}"
fi
cd $GITHUB_WORKSPACE
cd scripts
# ${{ steps.get_tag.outputs.tag }}
# Manually install PyInstaller rather than use the dev install requires from setup.py.
${{ steps.python-environment.outputs.pip_exe }} install pyinstaller
git fetch
git switch ${{ matrix.variant }}
git log -1 --oneline
${{ steps.python-environment.outputs.python_exe }} create_mapclient_application.py -v "${{ matrix.variant }}" -l $GITHUB_WORKSPACE/mapclient ${{ matrix.tag }}
if [ "$RUNNER_OS" == "macOS" ]; then
asset="${GITHUB_WORKSPACE}/mapclient/res/pyinstaller/dist/MAP-Client${variant}.app"
fi
if [ "$RUNNER_OS" == "Windows" ]; then
asset="${GITHUB_WORKSPACE}/mapclient/res/pyinstaller/dist/MAP-Client${variant}/MAP-Client${variant}.exe"
asset=${asset//\\//}
fi
echo "file=$asset" >> $GITHUB_OUTPUT
cat $GITHUB_OUTPUT
- name: Codesign application (Windows)
if: runner.os == 'Windows'
shell: cmd
run: |
rem AzureSignTool sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.acs.microsoft.com -v ${{ steps.create-application.outputs.file }}
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86\signtool" sign /d "MAP Client - mapping tools" /tr http://rfc3161timestamp.globalsign.com/advanced /fd SHA256 /td SHA256 /f ev_certificate.pfx ${{ steps.create-application.outputs.file }}
- name: Codesign application (macOS)
if: runner.os == 'macOS'
run: |
codesign --force -s "${{ secrets.APPLE_DEV_ID_APPLICATION}}" -v "${{ steps.create-application.outputs.file }}" --deep --strict --options=runtime --timestamp
- name: Create installer asset
id: create-installer
shell: bash
run: |
echo "Creating installer asset"
if [ "${{ matrix.variant }}" == "standard" ]; then
variant=
else
variant="-${{ matrix.variant }}"
fi
cd $GITHUB_WORKSPACE
cd scripts
${{ steps.python-environment.outputs.python_exe }} create_mapclient_installer.py -v "${{ matrix.variant }}" -l $GITHUB_WORKSPACE/mapclient ${{ matrix.tag }}
if [ "$RUNNER_OS" == "macOS" ]; then
asset=$GITHUB_WORKSPACE/mapclient/res/macos/MAP-Client${variant}-${{ matrix.release-name }}.dmg
elif [ "$RUNNER_OS" == "Windows" ]; then
asset=$GITHUB_WORKSPACE/mapclient/package/MAP-Client${variant}-${{ matrix.release-name }}.exe
asset=${asset//\\//}
else
echo "$RUNNER_OS not supported"
exit 1
fi
echo $asset
echo "file=$asset" >> $GITHUB_OUTPUT
- name: Codesign installer (Windows)
if: runner.os == 'Windows'
shell: cmd
run: |
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86\signtool" sign /d "MAP Client - mapping tools" /tr http://rfc3161timestamp.globalsign.com/advanced /fd SHA256 /td SHA256 /f ev_certificate.pfx ${{ steps.create-installer.outputs.file }}
rem AzureSignTool sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.acs.microsoft.com -v ${{ steps.create-installer.outputs.file }}
- name: Notarize and Staple installer (macOS)
if: runner.os == 'macOS'
run: |
#codesign -s "${{ secrets.APPLE_DEV_ID_APPLICATION}}" --timestamp --force "${{ steps.create-installer.outputs.file }}"
xcrun notarytool submit "${{ steps.create-installer.outputs.file }}" --apple-id ${{ secrets.APPLE_NOTARIZATION_USERNAME }} --password ${{ secrets.APPLE_NOTARIZATION_PASSWORD }} --team-id ${{ secrets.APPLE_DEV_TEAM_ID }} --wait
xcrun stapler staple "${{ steps.create-installer.outputs.file }}"
- name: Upload asset
uses: softprops/action-gh-release@v2
with:
files: ${{ steps.create-installer.outputs.file }}
tag_name: ${{ matrix.tag }}