ci: add GitHub Actions workflows mirroring Forgejo CI/CD
This commit is contained in:
parent
4d7a4810ff
commit
c94b2ed76c
2 changed files with 296 additions and 0 deletions
91
.github/workflows/dev.yml
vendored
Normal file
91
.github/workflows/dev.yml
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
name: Dev
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: python:3.13-slim
|
||||||
|
steps:
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update && apt-get install -y --no-install-recommends git ca-certificates
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- name: Configure git
|
||||||
|
run: |
|
||||||
|
git config user.name "GitHub Actions"
|
||||||
|
git config user.email "noreply@github.com"
|
||||||
|
|
||||||
|
- name: Install uv and dependencies
|
||||||
|
run: |
|
||||||
|
pip install uv
|
||||||
|
uv sync --group dev
|
||||||
|
|
||||||
|
- name: Semantic release (rc)
|
||||||
|
id: semrel
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
VERSION=$(uv run semantic-release version --print 2>/dev/null || echo "")
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "No release needed"
|
||||||
|
else
|
||||||
|
uv run semantic-release version
|
||||||
|
echo "skip=false" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "new_version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Released v${VERSION}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
new_version: ${{ steps.semrel.outputs.new_version }}
|
||||||
|
skip: ${{ steps.semrel.outputs.skip }}
|
||||||
|
|
||||||
|
docker:
|
||||||
|
needs: release
|
||||||
|
if: needs.release.outputs.skip != 'true'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: dev
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- name: Log in to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push pre-release image
|
||||||
|
run: |
|
||||||
|
VERSION="${{ needs.release.outputs.new_version }}"
|
||||||
|
IMAGE="ghcr.io/${{ github.repository_owner }}/wiregui"
|
||||||
|
|
||||||
|
echo "Building ${IMAGE}:v${VERSION}"
|
||||||
|
|
||||||
|
docker build --no-cache \
|
||||||
|
--build-arg "VERSION=${VERSION}" \
|
||||||
|
-t "${IMAGE}:v${VERSION}" \
|
||||||
|
-t "${IMAGE}:dev" \
|
||||||
|
.
|
||||||
|
|
||||||
|
docker push "${IMAGE}:v${VERSION}"
|
||||||
|
docker push "${IMAGE}:dev"
|
||||||
|
|
||||||
|
echo "Pushed ${IMAGE}:v${VERSION}, ${IMAGE}:dev"
|
||||||
205
.github/workflows/release.yml
vendored
Normal file
205
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: python:3.13-slim
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:17
|
||||||
|
env:
|
||||||
|
POSTGRES_USER: wiregui
|
||||||
|
POSTGRES_PASSWORD: wiregui
|
||||||
|
POSTGRES_DB: wiregui
|
||||||
|
options: >-
|
||||||
|
--health-cmd "pg_isready -U wiregui"
|
||||||
|
--health-interval 5s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
|
env:
|
||||||
|
CI: "true"
|
||||||
|
WG_DATABASE_URL: postgresql+asyncpg://wiregui:wiregui@postgres/wiregui
|
||||||
|
steps:
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
git wireguard-tools pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install uv
|
||||||
|
run: pip install uv
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: uv sync
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
run: uv run pytest tests/ --ignore=tests/e2e -v --tb=short
|
||||||
|
|
||||||
|
- name: Run E2E tests
|
||||||
|
run: |
|
||||||
|
uv run alembic upgrade head
|
||||||
|
uv run pytest tests/e2e/ -v --tb=short
|
||||||
|
|
||||||
|
release:
|
||||||
|
needs: test
|
||||||
|
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: node:20-slim
|
||||||
|
outputs:
|
||||||
|
new_tag: ${{ steps.version.outputs.new_tag }}
|
||||||
|
new_version: ${{ steps.version.outputs.new_version }}
|
||||||
|
skip: ${{ steps.version.outputs.skip }}
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update && apt-get install -y --no-install-recommends bash git python3 ca-certificates
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- name: Configure git
|
||||||
|
run: |
|
||||||
|
git config user.name "GitHub Actions"
|
||||||
|
git config user.email "noreply@github.com"
|
||||||
|
|
||||||
|
- name: Determine version bump
|
||||||
|
id: version
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
|
||||||
|
echo "latest_tag=${LATEST_TAG}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
CURRENT="${LATEST_TAG#v}"
|
||||||
|
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"
|
||||||
|
|
||||||
|
COMMITS=$(git log "${LATEST_TAG}..HEAD" --pretty=format:"%s" 2>/dev/null || git log --pretty=format:"%s")
|
||||||
|
|
||||||
|
BUMP="none"
|
||||||
|
while IFS= read -r msg; do
|
||||||
|
case "$msg" in
|
||||||
|
*"BREAKING CHANGE"*|*"!:"*)
|
||||||
|
BUMP="major"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
feat:*|feat\(*)
|
||||||
|
[ "$BUMP" != "major" ] && BUMP="minor"
|
||||||
|
;;
|
||||||
|
fix:*|fix\(*|perf:*|perf\(*|refactor:*|refactor\(*)
|
||||||
|
[ "$BUMP" = "none" ] && BUMP="patch"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done <<< "$COMMITS"
|
||||||
|
|
||||||
|
if [ "$BUMP" = "none" ]; then
|
||||||
|
echo "No version-relevant commits since ${LATEST_TAG}, skipping release"
|
||||||
|
echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$BUMP" in
|
||||||
|
major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
|
||||||
|
minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
|
||||||
|
patch) PATCH=$((PATCH + 1)) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
|
||||||
|
echo "new_version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "new_tag=v${NEW_VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "bump=${BUMP}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "skip=false" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Version bump: ${BUMP} -> v${NEW_VERSION}"
|
||||||
|
|
||||||
|
- name: Generate changelog
|
||||||
|
id: changelog
|
||||||
|
if: steps.version.outputs.skip != 'true'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
LATEST_TAG="${{ steps.version.outputs.latest_tag }}"
|
||||||
|
NEW_TAG="${{ steps.version.outputs.new_tag }}"
|
||||||
|
|
||||||
|
BODY="## ${NEW_TAG}"$'\n\n'
|
||||||
|
|
||||||
|
for type_label in "feat:Features" "fix:Bug Fixes" "refactor:Refactoring" "perf:Performance" "docs:Documentation" "chore:Maintenance"; do
|
||||||
|
prefix="${type_label%%:*}"
|
||||||
|
label="${type_label#*:}"
|
||||||
|
MATCHES=$(git log "${LATEST_TAG}..HEAD" --pretty=format:"%s" 2>/dev/null | grep -E "^${prefix}[:(]" || true)
|
||||||
|
if [ -n "$MATCHES" ]; then
|
||||||
|
BODY="${BODY}### ${label}"$'\n\n'
|
||||||
|
while IFS= read -r line; do
|
||||||
|
CLEAN=$(echo "$line" | sed -E "s/^${prefix}(\([^)]*\))?:\s*//")
|
||||||
|
BODY="${BODY}- ${CLEAN}"$'\n'
|
||||||
|
done <<< "$MATCHES"
|
||||||
|
BODY="${BODY}"$'\n'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${BODY}" > /tmp/changelog.md
|
||||||
|
echo "Generated changelog for ${NEW_TAG}"
|
||||||
|
|
||||||
|
- name: Create tag and release
|
||||||
|
if: steps.version.outputs.skip != 'true'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
NEW_TAG="${{ steps.version.outputs.new_tag }}"
|
||||||
|
|
||||||
|
git tag -a "${NEW_TAG}" -m "Release ${NEW_TAG}"
|
||||||
|
git push origin "${NEW_TAG}"
|
||||||
|
|
||||||
|
gh release create "${NEW_TAG}" \
|
||||||
|
--title "${NEW_TAG}" \
|
||||||
|
--notes-file /tmp/changelog.md
|
||||||
|
|
||||||
|
docker:
|
||||||
|
needs: release
|
||||||
|
if: needs.release.outputs.skip != 'true'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Log in to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push image
|
||||||
|
run: |
|
||||||
|
VERSION="${{ needs.release.outputs.new_version }}"
|
||||||
|
TAG="${{ needs.release.outputs.new_tag }}"
|
||||||
|
IMAGE="ghcr.io/${{ github.repository_owner }}/wiregui"
|
||||||
|
|
||||||
|
MAJOR=$(echo "$VERSION" | cut -d. -f1)
|
||||||
|
MINOR=$(echo "$VERSION" | cut -d. -f2)
|
||||||
|
|
||||||
|
echo "Building ${IMAGE}:${TAG}"
|
||||||
|
|
||||||
|
docker build --no-cache \
|
||||||
|
--build-arg "VERSION=${VERSION}" \
|
||||||
|
-t "${IMAGE}:${TAG}" \
|
||||||
|
-t "${IMAGE}:${MAJOR}.${MINOR}" \
|
||||||
|
-t "${IMAGE}:latest" \
|
||||||
|
.
|
||||||
|
|
||||||
|
docker push "${IMAGE}:${TAG}"
|
||||||
|
docker push "${IMAGE}:${MAJOR}.${MINOR}"
|
||||||
|
docker push "${IMAGE}:latest"
|
||||||
|
|
||||||
|
echo "Pushed ${IMAGE}:${TAG}, ${IMAGE}:${MAJOR}.${MINOR}, ${IMAGE}:latest"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue