Skip to content

Distribution smoke tests #20

Distribution smoke tests

Distribution smoke tests #20

name: Distribution smoke tests
# Smoke-tests each published distribution channel:
# uvx — PyPI via uvx
# docker — pull & run ulisesjeremias/create-awesome-python-app:latest
# homebrew — brew install on macos-latest
# aur — makepkg inside an archlinux container
# versions — cross-check channel versions against PyPI
on:
schedule:
- cron: "0 6 * * *"
workflow_dispatch:
permissions:
contents: read
env:
PACKAGE_NAME: create-awesome-python-app
DOCKER_IMAGE: ulisesjeremias/create-awesome-python-app
concurrency:
group: smoke-distribution
cancel-in-progress: true
jobs:
uvx:
name: uvx (PyPI)
runs-on: ubuntu-latest
steps:
- uses: astral-sh/setup-uv@v7
- name: Smoke uvx
run: |
set -euo pipefail
VERSION="$(uvx "$PACKAGE_NAME@latest" --version 2>&1)"
echo "uvx version: $VERSION"
echo "$VERSION" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+' || {
echo "::error::Unexpected uvx version output: $VERSION"
exit 1
}
uvx "$PACKAGE_NAME@latest" --help > /tmp/cpa-help.txt
test -s /tmp/cpa-help.txt
python3 -c "from pathlib import Path; print('\n'.join(Path('/tmp/cpa-help.txt').read_text().splitlines()[:5]))"
docker:
name: Docker Hub
runs-on: ubuntu-latest
steps:
- name: Pull image
run: docker pull "$DOCKER_IMAGE:latest"
- name: Verify --version
run: |
VERSION=$(docker run --rm ulisesjeremias/create-awesome-python-app:latest --version 2>&1)
echo "docker version: $VERSION"
echo "$VERSION" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+' || {
echo "::error::Unexpected version output: $VERSION"
exit 1
}
- name: Verify --help
run: |
docker run --rm "$DOCKER_IMAGE:latest" --help > /tmp/cpa-help.txt
test -s /tmp/cpa-help.txt
python3 -c "from pathlib import Path; print('\n'.join(Path('/tmp/cpa-help.txt').read_text().splitlines()[:5]))"
# Image must ship git so template/extension clones work (see #219).
- name: Verify scaffold smoke
run: |
set -euo pipefail
mkdir -p /tmp/cpa-docker-smoke
docker run --rm \
-e CI=true \
-v /tmp/cpa-docker-smoke:/out \
-w /out \
--user root \
"$DOCKER_IMAGE:latest" \
--template fastapi-starter \
--addons github-setup \
--no-interactive \
--no-install \
--refresh always \
/out/app
test -d /tmp/cpa-docker-smoke/app/.github/workflows
test -d /tmp/cpa-docker-smoke/app/app
homebrew:
name: Homebrew (Create-Python-App/tap)
runs-on: macos-latest
steps:
- name: Tap and install
run: |
brew tap Create-Python-App/tap
brew trust create-python-app/tap || true
brew install create-awesome-python-app
- name: Verify --version
run: |
VERSION=$(create-awesome-python-app --version 2>&1)
echo "homebrew version: $VERSION"
echo "$VERSION" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+' || {
echo "::error::Unexpected version output: $VERSION"
exit 1
}
- name: Verify --help
run: |
create-awesome-python-app --help > /tmp/cpa-help.txt
test -s /tmp/cpa-help.txt
python3 -c "from pathlib import Path; print('\n'.join(Path('/tmp/cpa-help.txt').read_text().splitlines()[:5]))"
aur:
name: AUR (archlinux container)
runs-on: ubuntu-latest
container:
image: archlinux:latest
steps:
- name: Bootstrap Arch system and non-root builder
run: |
pacman -Sy --noconfirm --needed \
python python-pip python-build python-installer python-wheel \
base-devel sudo git curl ca-certificates
useradd -m -G wheel builder
echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
- name: Clone AUR package and build
run: |
su builder -c "
set -euo pipefail
# Prefer live AUR; fall back to GitHub mirror during bootstrap.
if git clone https://aur.archlinux.org/create-awesome-python-app.git /tmp/cpa 2>/dev/null; then
cd /tmp/cpa
else
git clone https://github.com/Create-Python-App/aur-package.git /tmp/cpa
cd /tmp/cpa
fi
makepkg -si --noconfirm
"
- name: Verify --version
run: |
su builder -c "
VERSION=\$(create-awesome-python-app --version 2>&1)
echo \"aur version: \$VERSION\"
echo \"\$VERSION\" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+' || exit 1
"
- name: Verify --help
run: |
su builder -c "create-awesome-python-app --help > /tmp/cpa-help.txt && test -s /tmp/cpa-help.txt"
python3 -c "from pathlib import Path; print('\n'.join(Path('/tmp/cpa-help.txt').read_text().splitlines()[:5]))"
versions:
name: Cross-check published versions
runs-on: ubuntu-latest
if: always()
steps:
- uses: astral-sh/setup-uv@v7
- name: Gather versions from each channel
run: |
set -euo pipefail
PYPI=$(
curl -sfL https://pypi.org/pypi/create-awesome-python-app/json \
| python3 -c "import json,sys; print(json.load(sys.stdin)['info']['version'])"
)
DOCKER=$(
docker run --rm "$DOCKER_IMAGE:latest" --version 2>&1 \
| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
| head -1 \
|| echo "unavailable"
)
FORMULA_URL="https://raw.githubusercontent.com/Create-Python-App/homebrew-tap/main/Formula/create-awesome-python-app.rb"
HOMEBREW=$(
curl -sfL "$FORMULA_URL" \
| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' \
| head -1 \
|| echo "unavailable"
)
AUR_RPC="https://aur.archlinux.org/rpc/v5/info?arg=create-awesome-python-app"
AUR=$(
curl -sfL "$AUR_RPC" \
| python3 -c "import json,sys; d=json.load(sys.stdin); r=d.get('results') or []; print(r[0]['Version'].split('-')[0] if r else 'unavailable')" \
|| echo "unavailable"
)
echo "Channel versions:"
echo " pypi: $PYPI"
echo " docker: $DOCKER"
echo " homebrew: $HOMEBREW"
echo " aur: $AUR"
{
echo "## Distribution smoke versions"
echo
echo "| Channel | Version |"
echo "|---------|---------|"
echo "| PyPI | $PYPI |"
echo "| Docker | $DOCKER |"
echo "| Homebrew | $HOMEBREW |"
echo "| AUR | $AUR |"
} >> "$GITHUB_STEP_SUMMARY"
for CHANNEL_VER in "$DOCKER" "$HOMEBREW"; do
if [ "$CHANNEL_VER" != "unavailable" ] && [ "$CHANNEL_VER" != "$PYPI" ]; then
echo "::warning::Version mismatch vs pypi=$PYPI: $CHANNEL_VER"
fi
done
if [ "$AUR" != "unavailable" ] && [ "$AUR" != "$PYPI" ]; then
echo "::warning::Version mismatch: pypi=$PYPI aur=$AUR (AUR may lag)"
fi