Skip to content

fix: vscode binary now needs to be instructed about the location of the binary with version use sub-command - closes #217 #972

fix: vscode binary now needs to be instructed about the location of the binary with version use sub-command - closes #217

fix: vscode binary now needs to be instructed about the location of the binary with version use sub-command - closes #217 #972

name: CI/CD
on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
env:
PYTHON_VERSION: '3.11.9'
jobs:
dependencies:
name: Install Dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
name: Checkout
- name: System Dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y portaudio19-dev
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix: ubuntu-latest
- name: Create virtualenv
run: |
uv venv --system-site-packages
- name: Install dependencies
run: uv sync --frozen
ubo-pod-dependencies:
name: Install Ubo Pod Dependencies
runs-on: ubo-pod-pi5
outputs:
python-version: ${{ steps.get-python-version.outputs.PYTHON_VERSION }}
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Extract Python Version
id: get-python-version
run: |
echo "PYTHON_VERSION=$(python --version | cut -d' ' -f2)" >>$GITHUB_OUTPUT
echo "PYTHON_VERSION=$(python --version | cut -d' ' -f2)"
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix: ubo-pod
- name: Create virtualenv
run: |
uv venv --system-site-packages
- name: Install dependencies
run: |
uv sync --frozen
type-check:
name: Type Check
needs:
- ubo-pod-dependencies
runs-on: ubo-pod-pi5
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix: ubo-pod
- name: Create virtualenv
run: |
uv venv --system-site-packages
- name: Create stub files
run: |
uv run --frozen pyright --createstub kivy
- name: Type Check
run: |
uv run --frozen poe typecheck
lint:
name: Lint
needs:
- dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix: ubuntu-latest
- name: Lint
run: uvx ruff check
test:
name: Test
needs:
- dependencies
- ubo-pod-dependencies
strategy:
matrix:
runner: ['ubo-pod', 'ubo-pod-pi5', 'ubuntu-latest']
runs-on: ${{ matrix.runner }}
environment:
name: test
url: https://app.codecov.io/gh/${{ github.repository }}/
steps:
- name: System Dependencies
if: matrix.runner == 'ubuntu-latest'
run: |
sudo apt-get update -y
sudo apt-get install -y libegl1 libgl1 libmtdev1 libzbar0
- uses: actions/checkout@v4
name: Checkout
- name: Setup Python
if: matrix.runner == 'ubuntu-latest'
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix:
${{ startsWith(matrix.runner, 'ubo-pod') && 'ubo-pod' ||
'ubuntu-latest' }}
- name: Create virtualenv
run: |
uv venv --system-site-packages
- name: Run Tests
env:
THREADS: ${{ startsWith(matrix.runner, 'ubo-pod') && '1' || 'auto' }}
run: |
uv run --frozen poe test --verbosity=2 --make-screenshots --cov-report=xml --cov-report=html --log-level=DEBUG --log-cli-level=5 -n "$THREADS"
- name: Collect Window Screenshots
uses: actions/upload-artifact@v4
if: always()
with:
name: screenshots-${{ matrix.runner }}
path: tests/**/results/**/*.png
- name: Collect Store Snapshots
uses: actions/upload-artifact@v4
if: always()
with:
name: snapshots-${{ matrix.runner }}
path: tests/**/results/**/*.jsonc
- name: Collect HTML Coverage Report
uses: actions/upload-artifact@v4
with:
name: coverage-report-${{ matrix.runner }}
path: htmlcov
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
flags: ${{ matrix.runner }}
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
build:
name: Build
needs:
- dependencies
runs-on: ubuntu-latest
outputs:
version: ${{ steps.extract-version.outputs.VERSION }}
name: ${{ steps.extract-version.outputs.NAME }}
steps:
- uses: actions/checkout@v4
name: Checkout
with:
lfs: true
- uses: actions/setup-python@v5
name: Setup Python
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix: ubuntu-latest
- name: Extract Version
id: extract-version
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
echo "VERSION=$(uvx hatch version)" >>"$GITHUB_OUTPUT"
echo "VERSION=$(uvx hatch version)"
echo "NAME=$(uvx hatch project metadata | jq -r .name)" >>"$GITHUB_OUTPUT"
echo "NAME=$(uvx hatch project metadata | jq -r .name)"
- name: Configure Sentry
env:
VERSION: ${{ steps.extract-version.outputs.VERSION }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_REF: ${{ github.ref }}
GITHUB_SHA: ${{ github.sha }}
run: |
echo "SENTRY_DSN=$SENTRY_DSN" >>ubo_app/.env
# conditionally set it based on whether it's a tag or not using github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
if [ "$GITHUB_EVENT_NAME" == "push" ] && [ "$(echo $GITHUB_REF | grep -c 'refs/tags/v')" -eq 1 ]; then
echo "SENTRY_RELEASE=ubo-app@$VERSION" >>ubo_app/.env
else
echo "SENTRY_RELEASE=ubo-app@$GITHUB_SHA" >>ubo_app/.env
fi
cat ubo_app/.env
- name: Build
env:
SETUPTOOLS_SCM_PRETEND_VERSION:
${{ steps.extract-version.outputs.VERSION }}
run: uv build
- name: Upload wheel
uses: actions/upload-artifact@v4
with:
name: wheel
path: dist/*.whl
if-no-files-found: error
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: binary
path: dist/*.tar.gz
if-no-files-found: error
images:
name: Create Images
needs:
- type-check
- lint
- test
- build
runs-on: ubuntu-24.04-arm
container:
image: mkaczanowski/packer-builder-arm
volumes:
- /dev:/dev
options: --rm --privileged
strategy:
fail-fast: false
matrix:
suffix: ['lite', '']
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: wheel
path: /build/dist
- uses: actions/download-artifact@v4
with:
name: binary
path: /build/dist
- name: Generate Image URL and Checksum
id: generate-image-url
env:
MATRIX_SUFFIX: ${{ matrix.suffix }}
run: |
SUFFIX=""
if [ -n "$MATRIX_SUFFIX" ]; then
SUFFIX="_$MATRIX_SUFFIX"
fi
DASHED_SUFFIX=$(echo $SUFFIX | sed 's/_/-/g')
IMAGE_DATE='2024-11-19'
IMAGE_NAME="${IMAGE_DATE}-raspios-bookworm-arm64${DASHED_SUFFIX}"
IMAGE_URL="https://downloads.raspberrypi.com/raspios${SUFFIX}_arm64/images/raspios${SUFFIX}_arm64-${IMAGE_DATE}/${IMAGE_NAME}.img.xz"
CHECKSUM_URL="${IMAGE_URL}.sha256"
echo "suffix=$SUFFIX" >>"$GITHUB_OUTPUT"
echo "dashed_suffix=$DASHED_SUFFIX" >>"$GITHUB_OUTPUT"
echo "image_url=$IMAGE_URL" >>"$GITHUB_OUTPUT"
echo "image_name=$IMAGE_NAME" >>"$GITHUB_OUTPUT"
echo "image_checksum_url=$CHECKSUM_URL" >>"$GITHUB_OUTPUT"
if $MATRIX_SUFFIX == 'lite'; then
IMAGE_SIZE_GB=4.5
elif $MATRIX_SUFFIX == ''; then
IMAGE_SIZE_GB=6.75
else
IMAGE_SIZE_GB=13
fi
IMAGE_SIZE=$(awk -v IMAGE_SIZE_GB=$IMAGE_SIZE_GB 'BEGIN {printf "%.0f", IMAGE_SIZE_GB * 1024 ^ 3}')
echo "image_size=$IMAGE_SIZE" >>"$GITHUB_OUTPUT"
- name: Build Artifact
env:
PKR_VAR_ubo_app_version: ${{ needs.build.outputs.version }}
PKR_VAR_image_url: ${{ steps.generate-image-url.outputs.image_url }}
PKR_VAR_image_name: ${{ steps.generate-image-url.outputs.image_name }}
PKR_VAR_image_checksum_url:
${{ steps.generate-image-url.outputs.image_checksum_url }}
PKR_VAR_target_image_size:
${{ steps.generate-image-url.outputs.image_size}}
run: |
/entrypoint.sh init scripts/packer/image.pkr.hcl
SETUP_QEMU=false /entrypoint.sh build scripts/packer/image.pkr.hcl
ls -lh
mv image.img /build
ls -lh /build
- name: Fill Free Space with Zeros
run: |
apt-get update
apt-get install -y zerofree
LOOP_DEV=$(losetup -f)
losetup -P $LOOP_DEV /build/image.img
zerofree -v "${LOOP_DEV}p2"
losetup -d $LOOP_DEV
- name: Compress File with Gzip
env:
VERSION: ${{ needs.build.outputs.version }}
DASHED_SUFFIX: ${{ steps.generate-image-url.outputs.dashed_suffix }}
run: |
scripts/consume.sh /build/image.img | gzip -9 >/ubo_app-$VERSION-bookworm$DASHED_SUFFIX.img.gz
- name: Upload Image
uses: actions/upload-artifact@v4
with:
name:
ubo_app-${{ needs.build.outputs.version }}-bookworm${{
steps.generate-image-url.outputs.dashed_suffix}}-arm64.img.gz
path:
/ubo_app-${{ needs.build.outputs.version }}-bookworm${{
steps.generate-image-url.outputs.dashed_suffix }}.img.gz
if-no-files-found: error
publish:
name: Publish
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
needs:
- type-check
- lint
- test
- build
runs-on: ubuntu-latest
environment:
name: pypi
url:
https://pypi.org/project/${{ needs.build.outputs.name }}/${{
needs.build.outputs.version }}
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
name: wheel
path: dist
- uses: actions/download-artifact@v4
with:
name: binary
path: dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist
release:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
name: Release
needs:
- type-check
- lint
- test
- build
- publish
- images
runs-on: ubuntu-latest
environment:
name: release
url:
https://github.com/${{ github.repository }}/releases/tag/v${{
needs.build.outputs.version }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
name: Checkout
- name: Procure Lite Image
uses: actions/download-artifact@v4
with:
name:
ubo_app-${{ needs.build.outputs.version
}}-bookworm-lite-arm64.img.gz
path: artifacts
- name: Procure Default Image
uses: actions/download-artifact@v4
with:
name: ubo_app-${{ needs.build.outputs.version }}-bookworm-arm64.img.gz
path: artifacts
- name: Procure Wheel
uses: actions/download-artifact@v4
with:
name: wheel
path: artifacts
- name: Procure Binary
uses: actions/download-artifact@v4
with:
name: binary
path: artifacts
- name:
Split Large Files into 2GB chunks in a for loop only if they are
bigger than 2GB
run: |
for file in artifacts/*; do
if [ $(stat -c%s "$file") -gt 2147000000 ]; then
split -b 2147000000 "$file" "$file"_
rm "$file"
fi
done
- name: Extract Changelog
id: changelog
run: |
perl -0777 -ne 'while (/## Version ${{ needs.build.outputs.version }}\n(\s*\n)*(.*?)(\s*\n)*## Version \d+\.\d+\.\d+\n/sg) {print "$2\n"}' CHANGELOG.md >CURRENT_CHANGELOG.md
{
echo "CONTENT<<EOF"
cat CURRENT_CHANGELOG.md
echo "EOF"
} >>"$GITHUB_OUTPUT"
- name: Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*
tag_name: v${{ needs.build.outputs.version }}
body: |
PyPI package: https://pypi.org/project/${{ needs.build.outputs.name }}/${{ needs.build.outputs.version }}
# Changes:
${{ steps.changelog.outputs.CONTENT }}
---
*Note than GitHub doesn't allow assets bigger than 2GB in a release. Due to this, the files bigger than 2GB have been split into 2GB chunks. You can join them using the following command:*
```bash
cat [[filename]]_* > [[filename]]
```
prerelease: false
draft: false