Skip to content

Release

Release #388

Workflow file for this run

name: Release
on:
schedule:
- cron: "0 0 1 * *"
push:
tags: [ v* ]
env:
PIP_DISABLE_PIP_VERSION_CHECK: yes
jobs:
build:
name: Build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Fetch tags
if: github.event_name == 'schedule'
run: git fetch --tags
- name: Check if already released
if: github.event_name == 'schedule'
run: test -z $(git tag --list "v*" --points-at)
- name: Create tag
if: github.event_name == 'schedule'
run: git tag $(python -c "from time import strftime, gmtime; print(strftime('v%y.%m', gmtime()))")
- name: Push tag
if: github.event_name == 'schedule'
run: git push --tags
- name: Install build frontend
run: pip install "build==1.*"
- name: Build
run: python -m build
- name: Upload as build artifact
uses: actions/upload-artifact@v4
with:
path: dist
test-wheel:
name: Test wheel
runs-on: ubuntu-latest
needs:
- build
permissions: {}
continue-on-error: ${{ matrix.python-version == 3.13 }}
strategy:
fail-fast: false
matrix:
python-version:
- 3.12
- 3.13
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: artifact
- name: Install libcurl4-openssl-dev for compiling PycURL
run: |
sudo apt-get update
sudo apt-get install -y libcurl4-openssl-dev
- name: Install wheel
run: pip install *.whl
- name: Test starting
timeout-minutes: 1
run: python -m an_website -c
tests:
name: Run tests
runs-on: ubuntu-latest
permissions:
contents: read
continue-on-error: ${{ matrix.python-version == 3.13 }}
strategy:
fail-fast: false
matrix:
python-version:
- 3.12
- 3.13
license:
- basic
#- trial
redis-image:
- docker.io/redis/redis-stack-server:6.2.6-v13
#- docker.dragonflydb.io/dragonflydb/dragonfly
services:
redis:
image: ${{ matrix.redis-image }}
ports:
- 6379:6379
steps:
# - name: Configure sysctl limits
# run: |
# sudo swapoff -a
# sudo sysctl -w vm.swappiness=1
# sudo sysctl -w fs.file-max=262144
# sudo sysctl -w vm.max_map_count=262144
# - name: Start Elasticsearch
# uses: elastic/elastic-github-actions/elasticsearch@2c3ec0418fabc996180995c47b86a65b581f1561
# with:
# stack-version: 8.12.2
# security-enabled: false
# nodes: 3
# license: ${{ matrix.license }}
# plugins: |
# analysis-icu
# analysis-phonetic
# mapper-size
# mapper-murmur3
# mapper-annotated-text
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
cache: pip
cache-dependency-path: Pipfile.lock
- name: Install libcurl4-openssl-dev for compiling PycURL
run: |
sudo apt-get update
sudo apt-get install -y libcurl4-openssl-dev
- name: Install requirements
run: pip install -r pip-requirements.txt
- name: Install stuff needed for the tests
run: grep "^pytest-" pip-constraints.txt | xargs pip install -c pip-constraints.txt html5lib pytest time-machine
- name: Run pytest
timeout-minutes: 5
run: pytest --durations=0 --verbose --cov --cov-report=term:skip-covered
- name: Upload coverage as artifact
uses: actions/upload-artifact@v4
with:
path: .coverage
name: coverage
release:
name: Create release
runs-on: ubuntu-latest
permissions:
contents: write
needs:
- run-tests-in-oci-image
- test-running-oci-image
- test-wheel
- tests
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: artifact
- name: Version
id: version
shell: python
run: |
import os
from pathlib import Path
from time import strftime, gmtime
path = Path(os.getenv("GITHUB_OUTPUT"))
if "${{ github.event_name }}" == "schedule":
path.write_text(f"version={strftime('v%y.%m', gmtime())}\n")
elif "${{ github.event_name }}" == "push" and "${{ github.ref_type }}" == "tag":
path.write_text("version=${{ github.ref_name }}\n")
else:
assert 6 * 9 == 42
- name: Create release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.version }}
generate_release_notes: true
files: |
*.tar.gz
*.whl
pypi:
name: Upload to PyPI
runs-on: ubuntu-latest
needs:
- run-tests-in-oci-image
- test-running-oci-image
- test-wheel
- tests
permissions: {}
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: artifact
- name: Install Twine
run: pip install "twine==4.*"
- name: Run Twine
run: |
twine check --strict *.tar.gz *.whl
twine upload --verbose --disable-progress-bar *.tar.gz
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
sourcemaps:
name: Upload sourcemaps
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
needs:
- test-wheel
- tests
permissions: {}
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: artifact
- name: Install required library
run: pip install packaging==23.2
- name: Version
id: version
shell: python
run: |
import os
from pathlib import Path
from subprocess import run
from packaging.utils import parse_sdist_filename
command = "ls an-website-*.tar.gz"
result = run(command, shell=True, capture_output=True)
filename = result.stdout.decode("UTF-8").strip()
_, version = parse_sdist_filename(filename)
path = Path(os.getenv("GITHUB_OUTPUT"))
path.write_text(f"version={version}\n")
- name: Unpack source distribution
run: tar xvf an-website-*.tar.gz
- name: Upload sourcemaps
run: |
cd an-website-*/an_website
find static/js -type f -name "*.js" -exec \
curl -sSfk https://kibana.asozial.org:5601/api/apm/sourcemaps \
-H "Authorization: ApiKey ${{ secrets.SOURCEMAP_API_KEY }}" \
-H "kbn-xsrf: true" \
-F service_name="an-website" \
-F service_version="${{ steps.version.outputs.version }}" \
-F bundle_filepath="/{}" \
-F sourcemap=@{}.map \;
deploy:
name: Deploy website
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
needs:
- sourcemaps
permissions: {}
environment:
name: production
url: https://asozial.org
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: artifact
- name: Deploy website
run: |
curl -sSf -T *.whl https://asozial.org/api/update/ \
-H "Authorization: ${{ secrets.UPDATE_API_SECRET }}"
- name: Checkout repository
uses: actions/checkout@v4
- name: Check deployment
uses: ./.github/actions/check_deployment
with:
origin: https://asozial.org
version: ${{ needs.sourcemaps.outputs.version }}
github-pages:
name: GitHub Pages
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
needs:
- deploy
permissions:
actions: read
contents: read
id-token: write
pages: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.12
cache: pip
cache-dependency-path: Pipfile.lock
- name: Download coverage
uses: actions/download-artifact@v4
with:
name: coverage
- name: Make directory
run: mkdir github-pages
- name: Hash files
run: ./scripts/hash_files.py > github-pages/hashes.txt
- name: Install Coverage.py
run: pip install -c pip-constraints.txt coverage
- name: Create coverage files
run: |
coverage html -d github-pages/coverage
coverage json -o github-pages/coverage.json
./generate-badge.sh > github-pages/coverage/badge.svg
rm -f github-pages/coverage/.gitignore
- name: Generate commitment.txt
run: git log "--pretty=%H %ct %s" > github-pages/commitment.txt
- name: Upload GitHub Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: github-pages
- name: Deploy GitHub Pages site
id: deployment
uses: actions/deploy-pages@v4
build-oci-image:
name: Build OCI image
runs-on: ubuntu-latest
needs:
- build
permissions:
packages: write
steps:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.20
- name: Install netavark
run: |
wget http://mirrors.kernel.org/ubuntu/pool/universe/n/netavark/netavark_1.4.0-4_amd64.deb
sudo dpkg -i netavark_1.4.0-4_amd64.deb
- name: Upgrade Buildah
run: |
sudo apt-get update
sudo apt-get install -y libapparmor-dev libdevmapper-dev libglib2.0-dev libgpgme-dev libseccomp-dev libselinux1-dev
git clone -b v1.35.2 --depth=1 https://github.com/containers/buildah.git ~/go/src/github.com/containers/buildah
pushd ~/go/src/github.com/containers/buildah
make buildah docs
sudo make install
buildah version
popd
- name: Download youki
run: |
wget https://github.com/containers/youki/releases/download/v${VERSION}/youki-${VERSION}-x86_64-musl.tar.gz
tar xOf youki-${VERSION}-x86_64-musl.tar.gz youki > /opt/youki
rm -f youki-${VERSION}-x86_64-musl.tar.gz
chmod +x /opt/youki
env:
VERSION: 0.3.2
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Install Setuptools
run: pip install "setuptools==69.*"
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: artifact
- name: Extract source distribution
run: |
tar xvf *.tar.gz
rm -f *.tar.gz
- name: Build image
run: |
cd an-website*
sudo ./build-oci-image.sh -t an-website --timestamp 1651075200
cd ..
env:
BUILDAH_RUNTIME: /opt/youki
- name: Save image
run: sudo buildah push --all --format=oci --compression-format=zstd:chunked --compression-level=20 an-website oci-archive:oci-archive.tar
- name: Upload as build artifact
uses: actions/upload-artifact@v4
with:
name: oci-image
path: oci-archive.tar
test-running-oci-image:
name: Test running OCI image
runs-on: ubuntu-latest
needs:
- build-oci-image
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: oci-image
- name: Run image
timeout-minutes: 1
run: sudo podman run --network=host -t oci-archive:oci-archive.tar -c
run-tests-in-oci-image:
name: Run tests in OCI image
runs-on: ubuntu-latest
needs:
- build-oci-image
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: oci-image
- name: Run tests
timeout-minutes: 20
run: sudo podman run --network=host -t -v ./pip-constraints.txt:/pip-constraints.txt:z,ro -v ./tests:/tests:z,ro --entrypoint=/bin/sh oci-archive:oci-archive.tar -c "grep -P '^pytest-(?!cov)' /pip-constraints.txt | xargs /venv/bin/pip install --disable-pip-version-check -c /pip-constraints.txt html5lib pytest time-machine && /venv/bin/pytest --verbose /tests"
push-oci-image:
name: Push OCI image
runs-on: ubuntu-latest
needs:
- run-tests-in-oci-image
- test-running-oci-image
permissions:
packages: write
steps:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.20
- name: Upgrade Skopeo
run: |
sudo apt-get update
sudo apt-get install -y libdevmapper-dev libgpgme-dev
git clone -b v1.15.0 --depth=1 https://github.com/containers/skopeo.git ~/go/src/github.com/containers/skopeo
pushd ~/go/src/github.com/containers/skopeo
make bin/skopeo
sudo make install DISABLE_DOCS=1
skopeo --version
popd
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: oci-image
- name: Version
id: version
shell: python
run: |
import os
from pathlib import Path
from time import strftime, gmtime
path = Path(os.getenv("GITHUB_OUTPUT"))
if "${{ github.event_name }}" == "schedule":
path.write_text(f"version={strftime('v%y.%m', gmtime())}\n")
elif "${{ github.event_name }}" == "push" and "${{ github.ref_type }}" == "tag":
path.write_text("version=${{ github.ref_name }}\n")
else:
assert 6 * 9 == 42
- name: Log in to ghcr.io
uses: redhat-actions/podman-login@v1
with:
username: ${{ github.actor }}
password: ${{ github.token }}
registry: ghcr.io/${{ github.repository }}
- name: Push image to ghcr.io
run: skopeo copy --all --preserve-digests oci-archive:oci-archive.tar docker://ghcr.io/${{ github.repository }}:${{ steps.version.outputs.version }}
- name: Tag image as latest
run: skopeo copy --all --preserve-digests oci-archive:oci-archive.tar docker://ghcr.io/${{ github.repository }}:latest