You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
374 lines
18 KiB
YAML
374 lines
18 KiB
YAML
name: release
|
|
|
|
# https://data-dive.com/multi-os-deployment-in-cloud-using-pyinstaller-and-github-actions
|
|
# https://github.com/actions/upload-artifact
|
|
# https://github.com/actions/download-artifact
|
|
# https://github.com/docker/metadata-action
|
|
# https://github.com/marketplace/actions/generate-release-hashes
|
|
|
|
# https://github.com/oleksis/pyinstaller-manylinux
|
|
# https://github.com/pypa/manylinux
|
|
# https://github.com/batonogov/docker-pyinstaller
|
|
|
|
# https://docs.github.com/de/actions/using-workflows/workflow-syntax-for-github-actions
|
|
# https://docs.github.com/en/actions/using-workflows
|
|
# https://docs.github.com/en/actions/learn-github-actions/contexts
|
|
# https://docs.github.com/en/actions/learn-github-actions/expressions
|
|
|
|
# https://docs.github.com/en/rest/releases/releases
|
|
|
|
# https://peps.python.org/pep-0440/
|
|
# https://semver.org/
|
|
|
|
# Build matrix:
|
|
# - Linux x86_64 glibc 2.35: ubuntu-latest
|
|
# - Linux x86_64 glibc 2.34: extract_otp_secrets:buster
|
|
# - Windows x86_64: windows-latest
|
|
# - MacOS x86_64: macos-11
|
|
# - Linux x86_64 glibc 2.28: extract_otp_secrets:buster
|
|
# - Linux aarch64 glibc 2.28: extract_otp_secrets:buster
|
|
# - MacOS universal2: macos-11
|
|
# - Windows arm64: [buildx + https://github.com/batonogov/docker-pyinstaller]
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
|
pull_request:
|
|
schedule:
|
|
# Run weekly on default branch
|
|
- cron: '47 4 * * 6'
|
|
|
|
jobs:
|
|
|
|
create-release:
|
|
name: Create Release
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Set meta data
|
|
id: meta
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
# Writing to env with >> $GITHUB_ENV is an alternative
|
|
run: |
|
|
echo "date=$(TZ=Europe/Zurich date +'%d.%m.%Y')" >> $GITHUB_OUTPUT
|
|
echo "version=${TAG_NAME/v/}" >> $GITHUB_OUTPUT
|
|
echo "tag_name=${{ github.ref_name }}" >> $GITHUB_OUTPUT
|
|
echo "tag_message=$(git tag -l --format='%(contents:subject)' ${{ github.ref_name }})" >> $GITHUB_OUTPUT
|
|
env:
|
|
TAG_NAME: ${{ github.ref_name }}
|
|
- name: Create Release
|
|
id: create_release
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
run: |
|
|
# https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release
|
|
response=$(curl \
|
|
-X POST \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
|
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
https://api.github.com/repos/scito/extract_otp_secrets/releases \
|
|
--silent \
|
|
--show-error \
|
|
-d '{"tag_name":"${{ github.ref }}","target_commitish":"master","name":"${{ steps.meta.outputs.version }} - ${{ steps.meta.outputs.date }}","body":"${{ steps.meta.outputs.tag_message }}","draft":true,"prerelease":false,"generate_release_notes":true}')
|
|
echo upload_url=$(jq '.upload_url' <<< "$response") >> $GITHUB_OUTPUT
|
|
echo $(jq -r '.upload_url' <<< "$response") > release_url.txt
|
|
echo $(jq -r '.id' <<< "$response") > release_id.txt
|
|
- name: Save Release URL File for publish
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: release_url
|
|
path: release_url.txt
|
|
- name: Save asset upload id for publish
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: release_id
|
|
path: release_id.txt
|
|
|
|
build-linux-executable-in-docker:
|
|
name: Build Linux release in docker container
|
|
# run only when code is compiling and tests are passing
|
|
runs-on: ubuntu-latest
|
|
needs: create-release
|
|
|
|
# steps to perform in job
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v3
|
|
|
|
# avoid building if there are testing errors
|
|
- name: Run smoke test
|
|
run: |
|
|
sudo apt-get install -y libzbar0
|
|
python -m pip install --upgrade pip
|
|
pip install -U -r requirements-dev.txt
|
|
pip install -U .
|
|
pytest
|
|
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@v2
|
|
|
|
# setup Docker build action
|
|
- name: Set up Docker Buildx
|
|
id: buildx
|
|
uses: docker/setup-buildx-action@v2
|
|
# Workaround for failing builds: https://github.com/docker/build-push-action/issues/761#issuecomment-1383822381
|
|
# TODO remove workaround when fixed
|
|
with:
|
|
driver-opts: |
|
|
image=moby/buildkit:v0.10.6
|
|
|
|
- name: Login to DockerHub
|
|
uses: docker/login-action@v2
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
- name: Login to Github Packages
|
|
uses: docker/login-action@v2
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GHCR_IO_TOKEN }}
|
|
|
|
- name: "Build image from Buster and push to GitHub Container Registry"
|
|
id: docker_build_buster
|
|
# Disable and build in ci_docker for speeding up releases
|
|
if: false
|
|
uses: docker/build-push-action@v3
|
|
with:
|
|
platforms: linux/amd64,linux/arm64
|
|
# relative path to the place where source code with Dockerfile is located
|
|
# TODO file:, move to docker/
|
|
context: .
|
|
file: Dockerfile
|
|
# builder: ${{ steps.buildx.outputs.name }}
|
|
build-args: |
|
|
BASE_IMAGE=python:3.11-slim-buster
|
|
# Note: tags has to be all lower-case
|
|
pull: true
|
|
tags: |
|
|
scit0/extract_otp_secrets:buster
|
|
push: true
|
|
|
|
# # https://stackoverflow.com/a/61155718/1663871
|
|
# - name: Build docker images
|
|
# run: docker build -t local < .devcontainer/Dockerfile
|
|
# - name: Run tests
|
|
# run: docker run -it -v $PWD:/srv -w/srv local make test
|
|
|
|
- name: Image digest
|
|
# TODO upload digests to assets
|
|
run: |
|
|
echo "extract_otp_secrets: ${{ steps.docker_build_buster.outputs.digest }}"
|
|
|
|
- name: Run Pyinstaller in container
|
|
run: |
|
|
# TODO use local docker image https://stackoverflow.com/a/61155718/1663871
|
|
docker run --pull always --entrypoint /bin/bash --rm -v "$(pwd)":/files -w /files scit0/extract_otp_secrets:buster -c 'apt-get update && apt-get -y install binutils && pip install -U -r /files/requirements.txt && pip install pyinstaller && pyinstaller -y --add-data /usr/local/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --name extract_otp_secrets_linux_x86_64 --distpath /files/dist/ /files/src/extract_otp_secrets.py'
|
|
|
|
- name: Smoke tests
|
|
run: |
|
|
dist/extract_otp_secrets_linux_x86_64 -V
|
|
dist/extract_otp_secrets_linux_x86_64 -h
|
|
dist/extract_otp_secrets_linux_x86_64 example_export.png
|
|
dist/extract_otp_secrets_linux_x86_64 - < example_export.txt
|
|
dist/extract_otp_secrets_linux_x86_64 --qr ZBAR example_export.png
|
|
dist/extract_otp_secrets_linux_x86_64 --qr QREADER example_export.png
|
|
dist/extract_otp_secrets_linux_x86_64 --qr QREADER_DEEP example_export.png
|
|
dist/extract_otp_secrets_linux_x86_64 --qr CV2 example_export.png
|
|
dist/extract_otp_secrets_linux_x86_64 --qr CV2_WECHAT example_export.png
|
|
- name: Load Release URL File from release job
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: actions/download-artifact@v3
|
|
with:
|
|
name: release_url
|
|
- name: Display structure of files
|
|
run: ls -R
|
|
- name: Upload Release Asset
|
|
id: upload-release-asset
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
run: |
|
|
response=$(curl \
|
|
-X POST \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Content-Type: application/x-executable" \
|
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
|
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
--silent \
|
|
--show-error \
|
|
--data-binary @dist/extract_otp_secrets_linux_x86_64 \
|
|
$(cat release_url.txt)=extract_otp_secrets_linux_x86_64)
|
|
|
|
build-native-executables:
|
|
name: Build native packages
|
|
needs: create-release
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
matrix:
|
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#choosing-github-hosted-runners
|
|
include:
|
|
- os: windows-latest
|
|
TARGET: windows
|
|
# TODO add --icon
|
|
# TODO add --manifest
|
|
# TODO find more elegant solution for pyzbar\libiconv.dll and pyzbar\libzbar-64.dll
|
|
# Files of Visual C++ 2013 Redistributable Package: https://support.microsoft.com/en-us/topic/update-for-visual-c-2013-redistributable-package-d8ccd6a5-4e26-c290-517b-8da6cfdf4f10
|
|
CMD_BUILD: |
|
|
pyinstaller -y --add-data "$($Env:pythonLocation)\__yolo_v3_qr_detector;__yolo_v3_qr_detector" --add-binary "$($Env:pythonLocation)\Lib\site-packages\pyzbar\libiconv.dll;pyzbar" --add-binary "$($Env:pythonLocation)\Lib\site-packages\pyzbar\libzbar-64.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\msvcr120.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\msvcp120.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\vcamp120.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\vcomp120.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\vccorlib120.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120u.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120chs.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120cht.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120deu.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120enu.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120esn.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120fra.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120ita.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120jpn.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120kor.dll;pyzbar" --add-binary "$($Env:WinDir)\system32\mfc120rus.dll;pyzbar" --onefile --version-file build\file_version_info.txt src\extract_otp_secrets.py
|
|
OUT_FILE_NAME: extract_otp_secrets.exe
|
|
ASSET_NAME: extract_otp_secrets_win_x86_64.exe
|
|
ASSET_MIME: application/vnd.microsoft.portable-executable
|
|
UPLOAD: true
|
|
- os: macos-11
|
|
TARGET: macos
|
|
# TODO add --icon
|
|
# TODO add --osx-bundle-identifier
|
|
# TODO add --codesign-identity
|
|
# TODO add --osx-entitlements-file
|
|
# TODO https://pyinstaller.org/en/stable/spec-files.html#spec-file-options-for-a-macos-bundle
|
|
# TODO --target-arch universal2
|
|
CMD_BUILD: |
|
|
pyinstaller -y --add-data $macos_python_path/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --argv-emulation src/extract_otp_secrets.py
|
|
OUT_FILE_NAME: extract_otp_secrets
|
|
ASSET_NAME: extract_otp_secrets_macos_x86_64
|
|
ASSET_MIME: application/x-newton-compatible-pkg
|
|
UPLOAD: true
|
|
- os: ubuntu-latest
|
|
TARGET: linux
|
|
CMD_BUILD: |
|
|
pyinstaller -y --add-data $pythonLocation/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile src/extract_otp_secrets.py
|
|
OUT_FILE_NAME: extract_otp_secrets
|
|
ASSET_NAME: extract_otp_secrets_linux_x86_64_ubuntu_latest
|
|
ASSET_MIME: application/x-executable
|
|
UPLOAD: false
|
|
steps:
|
|
- name: Output path
|
|
if: runner.os == 'Windows'
|
|
run: echo "$($Env:Path)"
|
|
- name: List Windir
|
|
if: runner.os == 'Windows'
|
|
run: ls "$($Env:WinDir)\system32"
|
|
- uses: actions/checkout@v3
|
|
- name: Set macos macos_python_path
|
|
# TODO use variable for Python version
|
|
run: echo "macos_python_path=/Library/Frameworks/Python.framework/Versions/3.11" >> $GITHUB_ENV
|
|
- name: Set up Python 3.11
|
|
uses: actions/setup-python@v4
|
|
with:
|
|
python-version: 3.11
|
|
check-latest: true
|
|
- name: Install zbar shared lib for QReader (Linux)
|
|
if: runner.os == 'Linux'
|
|
run: |
|
|
sudo apt-get install -y libzbar0
|
|
- name: Install zbar shared lib for QReader (macOS)
|
|
if: runner.os == 'macOS'
|
|
run: |
|
|
brew install zbar
|
|
- name: Install dependencies
|
|
# TODO fix --use-pep517
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install -U -r requirements-dev.txt
|
|
pip install -U .
|
|
- name: Create Windows file_version_info.txt
|
|
shell: bash
|
|
run: |
|
|
mkdir -p build/
|
|
VERSION_STR=$(setuptools-git-versioning) VERSION_MAJOR=$(cut -d '.' -f 1 <<< "$(setuptools-git-versioning)") VERSION_MINOR=$(cut -d '.' -f 2 <<< "$(setuptools-git-versioning)") VERSION_PATCH=$(echo $(cut -d '.' -f 3 <<< "$(setuptools-git-versioning)") | sed -E -n "s/^([0-9]+).*/\1/p") VERSION_BUILD=$(echo $(cut -d '.' -f 3 <<< "$(setuptools-git-versioning)") | sed -E -n -e"s/^[0-9]+.+/99/p")$(($(git rev-list --count $(git tag | sort -V -r | sed '1!d')..HEAD))) YEARS='2020-2023' envsubst < file_version_info_template.txt > build/file_version_info.txt
|
|
- name: Build with pyinstaller for ${{ matrix.TARGET }}
|
|
run: ${{ matrix.CMD_BUILD }}
|
|
- name: Smoke tests for generated exe (general)
|
|
run: |
|
|
dist/${{ matrix.OUT_FILE_NAME }} -V
|
|
dist/${{ matrix.OUT_FILE_NAME }} -h
|
|
dist/${{ matrix.OUT_FILE_NAME }} example_export.png
|
|
dist/${{ matrix.OUT_FILE_NAME }} --qr ZBAR example_export.png
|
|
dist/${{ matrix.OUT_FILE_NAME }} --qr QREADER example_export.png
|
|
dist/${{ matrix.OUT_FILE_NAME }} --qr QREADER_DEEP example_export.png
|
|
dist/${{ matrix.OUT_FILE_NAME }} --qr CV2 example_export.png
|
|
dist/${{ matrix.OUT_FILE_NAME }} --qr CV2_WECHAT example_export.png
|
|
- name: Smoke tests for generated exe (stdin)
|
|
if: runner.os != 'Windows'
|
|
run: |
|
|
dist/${{ matrix.OUT_FILE_NAME }} - < example_export.txt
|
|
- name: Load Release URL File from release job
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: actions/download-artifact@v3
|
|
with:
|
|
name: release_url
|
|
- name: Load Release Id File from release job
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
uses: actions/download-artifact@v3
|
|
with:
|
|
name: release_id
|
|
- name: Display structure of files
|
|
run: ls -R
|
|
- name: Set meta data
|
|
id: meta
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
shell: bash
|
|
run: |
|
|
echo "release_id=$(cat release_id.txt)" >> $GITHUB_OUTPUT
|
|
echo "upload_url=https://uploads.github.com/repos/scito/extract_otp_secrets/releases/$(cat release_id.txt)/assets?name=" >> $GITHUB_OUTPUT
|
|
- name: Upload Release Asset
|
|
id: upload-release-asset
|
|
if: matrix.UPLOAD && startsWith(github.ref, 'refs/tags/v')
|
|
run: |
|
|
curl -X POST -H "Accept: application/vnd.github+json" -H "Content-Type: ${{ matrix.ASSET_MIME }}" -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -H "X-GitHub-Api-Version: 2022-11-28" --show-error --data-binary @dist/${{ matrix.OUT_FILE_NAME }} ${{ steps.meta.outputs.upload_url }}=${{ matrix.ASSET_NAME }}
|
|
|
|
upload-hashes:
|
|
name: Upload hashes
|
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
needs:
|
|
- build-linux-executable-in-docker
|
|
- build-native-executables
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Load Release Id File from release job
|
|
uses: actions/download-artifact@v3
|
|
with:
|
|
name: release_id
|
|
- name: Set meta data
|
|
id: meta
|
|
run: |
|
|
echo "release_id=$(cat release_id.txt)" >> $GITHUB_OUTPUT
|
|
echo "upload_url=https://uploads.github.com/repos/scito/extract_otp_secrets/releases/$(cat release_id.txt)/assets?name=" >> $GITHUB_OUTPUT
|
|
- name: Calculate and upload hashes from assets
|
|
run: |
|
|
GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
|
|
for asset_url in $(curl \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer $GITHUB_TOKEN"\
|
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
--silent \
|
|
--show-error \
|
|
https://api.github.com/repos/scito/extract_otp_secrets/releases/${{ steps.meta.outputs.release_id }}/assets |
|
|
jq -r '.[].url'); do
|
|
echo "Download $asset_url"
|
|
name=$(curl \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer $GITHUB_TOKEN"\
|
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
--output-dir assets \
|
|
-L \
|
|
$asset_url |
|
|
jq -r '.name')
|
|
curl \
|
|
-H "Accept: application/octet-stream" \
|
|
-H "Authorization: Bearer $GITHUB_TOKEN"\
|
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
--create-dirs \
|
|
--output-dir assets \
|
|
-L \
|
|
-o $name \
|
|
$asset_url
|
|
done
|
|
(cd assets/ && sha256sum * > ../sha256_hashes.txt)
|
|
curl -X POST -H "Accept: application/vnd.github+json" -H "Content-Type: text/plain" -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -H "X-GitHub-Api-Version: 2022-11-28" --show-error --data-binary @sha256_hashes.txt ${{ steps.meta.outputs.upload_url }}=sha256_hashes.txt
|
|
|
|
(cd assets/ && sha512sum * > ../sha512_hashes.txt)
|
|
curl -X POST -H "Accept: application/vnd.github+json" -H "Content-Type: text/plain" -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -H "X-GitHub-Api-Version: 2022-11-28" --show-error --data-binary @sha512_hashes.txt ${{ steps.meta.outputs.upload_url }}=sha512_hashes.txt
|