Combine CI and publish workflows
ci / lint (push) Failing after 6s
ci / validate (push) Failing after 5s
ci / publish (push) Has been skipped

This commit is contained in:
2026-06-27 23:06:45 +02:00
parent ec4805f027
commit 662053d592
6 changed files with 337 additions and 135 deletions
+161
View File
@@ -0,0 +1,161 @@
name: ci
on:
push:
branches:
- "**"
pull_request:
workflow_dispatch:
env:
REGISTRY: gcr.forust.xyz
IMAGE_NAME: forust/telegram-scraper
jobs:
lint:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check formatting with Prettier
shell: bash
run: |
mapfile -t prettier_files < <(
git ls-files \
| grep -E '\.(md|json|ya?ml|html|css)$' \
| grep -Ev '^(\.docs/|\.zed/|errorpages/html/|homepages/(forust_files|xdfnx_files)/)'
)
if [ "${#prettier_files[@]}" -eq 0 ]; then
echo "No Prettier-managed files found."
exit 0
fi
docker run --rm \
-v "$PWD:/work" \
-w /work \
node:22-alpine \
sh -lc 'npx --yes prettier@3 --check --ignore-unknown "$@"' sh "${prettier_files[@]}"
- name: Lint Python with Ruff
shell: bash
run: |
docker run --rm \
-v "$PWD:/work" \
-w /work \
ghcr.io/astral-sh/ruff:latest \
check .
- name: Lint YAML syntax
shell: bash
run: |
docker run --rm \
-v "$PWD:/work" \
-w /work \
cytopia/yamllint:latest \
-c .yamllint .
- name: Lint Dockerfiles
shell: bash
run: |
mapfile -t dockerfiles < <(
git ls-files ':(glob)**/Dockerfile' ':(glob)**/Dockerfile.*'
)
if [ "${#dockerfiles[@]}" -eq 0 ]; then
echo "No Dockerfiles found."
exit 0
fi
docker run --rm \
-v "$PWD:/work" \
-w /work \
--entrypoint hadolint \
hadolint/hadolint:latest-debian \
-c .hadolint.yaml "${dockerfiles[@]}"
validate:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Lint YAML syntax
shell: bash
run: |
docker run --rm \
-v "$PWD:/work" \
-w /work \
cytopia/yamllint:latest \
-c .yamllint .
- name: Validate Kubernetes manifests
shell: bash
run: |
mapfile -t manifests < <(
git ls-files ':(glob)**/k8s/**/*.yaml' ':(glob)**/k8s/**/*.yml' \
| grep -Ev '(^|/)(kustomization\.ya?ml|.*\.example\.ya?ml|.*values\.ya?ml|patch-.*\.ya?ml)$'
)
if [ "${#manifests[@]}" -eq 0 ]; then
echo "No Kubernetes manifests found."
exit 0
fi
docker run --rm \
-v "$PWD:/work" \
-w /work \
ghcr.io/yannh/kubeconform:latest \
-strict \
-ignore-missing-schemas \
-summary \
"${manifests[@]}"
publish:
needs: [lint, validate]
if: github.event_name != 'pull_request'
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Read project version
id: version
shell: bash
run: |
version="$(python3 -c 'from pathlib import Path; import tomllib; print(tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"])')"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Log in to registry
shell: bash
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "${REGISTRY}" \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Build and push image
shell: bash
run: |
image="${REGISTRY}/${IMAGE_NAME}"
tags=("latest" "${{ steps.version.outputs.version }}")
case "${GITHUB_REF_NAME}" in
main)
tags+=("main" "prod")
;;
dev)
tags+=("dev")
;;
esac
build_args=()
for tag in "${tags[@]}"; do
build_args+=(-t "${image}:${tag}")
done
docker build "${build_args[@]}" .
for tag in "${tags[@]}"; do
docker push "${image}:${tag}"
done
-64
View File
@@ -1,64 +0,0 @@
name: publish
on:
push:
branches:
- "**"
workflow_dispatch:
env:
REGISTRY: gcr.forust.xyz
IMAGE_NAME: forust/telegram-scraper
jobs:
docker:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Read project version
id: version
shell: bash
run: |
version="$(python3 - <<'PY'
from pathlib import Path
import tomllib
print(tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"])
PY
)"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Log in to registry
shell: bash
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "${REGISTRY}" \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Build and push image
shell: bash
run: |
image="${REGISTRY}/${IMAGE_NAME}"
tags=("latest" "${{ steps.version.outputs.version }}")
case "${GITHUB_REF_NAME}" in
main)
tags+=("main" "prod")
;;
dev)
tags+=("dev")
;;
esac
build_args=()
for tag in "${tags[@]}"; do
build_args+=(-t "${image}:${tag}")
done
docker build "${build_args[@]}" .
for tag in "${tags[@]}"; do
docker push "${image}:${tag}"
done
+161
View File
@@ -0,0 +1,161 @@
name: ci
on:
push:
branches:
- "**"
pull_request:
workflow_dispatch:
env:
REGISTRY: gcr.forust.xyz
IMAGE_NAME: forust/telegram-scraper
jobs:
lint:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check formatting with Prettier
shell: bash
run: |
mapfile -t prettier_files < <(
git ls-files \
| grep -E '\.(md|json|ya?ml|html|css)$' \
| grep -Ev '^(\.docs/|\.zed/|errorpages/html/|homepages/(forust_files|xdfnx_files)/)'
)
if [ "${#prettier_files[@]}" -eq 0 ]; then
echo "No Prettier-managed files found."
exit 0
fi
docker run --rm \
-v "$PWD:/work" \
-w /work \
node:22-alpine \
sh -lc 'npx --yes prettier@3 --check --ignore-unknown "$@"' sh "${prettier_files[@]}"
- name: Lint Python with Ruff
shell: bash
run: |
docker run --rm \
-v "$PWD:/work" \
-w /work \
ghcr.io/astral-sh/ruff:latest \
check .
- name: Lint YAML syntax
shell: bash
run: |
docker run --rm \
-v "$PWD:/work" \
-w /work \
cytopia/yamllint:latest \
-c .yamllint .
- name: Lint Dockerfiles
shell: bash
run: |
mapfile -t dockerfiles < <(
git ls-files ':(glob)**/Dockerfile' ':(glob)**/Dockerfile.*'
)
if [ "${#dockerfiles[@]}" -eq 0 ]; then
echo "No Dockerfiles found."
exit 0
fi
docker run --rm \
-v "$PWD:/work" \
-w /work \
--entrypoint hadolint \
hadolint/hadolint:latest-debian \
-c .hadolint.yaml "${dockerfiles[@]}"
validate:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Lint YAML syntax
shell: bash
run: |
docker run --rm \
-v "$PWD:/work" \
-w /work \
cytopia/yamllint:latest \
-c .yamllint .
- name: Validate Kubernetes manifests
shell: bash
run: |
mapfile -t manifests < <(
git ls-files ':(glob)**/k8s/**/*.yaml' ':(glob)**/k8s/**/*.yml' \
| grep -Ev '(^|/)(kustomization\.ya?ml|.*\.example\.ya?ml|.*values\.ya?ml|patch-.*\.ya?ml)$'
)
if [ "${#manifests[@]}" -eq 0 ]; then
echo "No Kubernetes manifests found."
exit 0
fi
docker run --rm \
-v "$PWD:/work" \
-w /work \
ghcr.io/yannh/kubeconform:latest \
-strict \
-ignore-missing-schemas \
-summary \
"${manifests[@]}"
publish:
needs: [lint, validate]
if: github.event_name != 'pull_request'
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Read project version
id: version
shell: bash
run: |
version="$(python3 -c 'from pathlib import Path; import tomllib; print(tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"])')"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Log in to registry
shell: bash
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "${REGISTRY}" \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Build and push image
shell: bash
run: |
image="${REGISTRY}/${IMAGE_NAME}"
tags=("latest" "${{ steps.version.outputs.version }}")
case "${GITHUB_REF_NAME}" in
main)
tags+=("main" "prod")
;;
dev)
tags+=("dev")
;;
esac
build_args=()
for tag in "${tags[@]}"; do
build_args+=(-t "${image}:${tag}")
done
docker build "${build_args[@]}" .
for tag in "${tags[@]}"; do
docker push "${image}:${tag}"
done
-64
View File
@@ -1,64 +0,0 @@
name: publish
on:
push:
branches:
- "**"
workflow_dispatch:
env:
REGISTRY: gcr.forust.xyz
IMAGE_NAME: forust/telegram-scraper
jobs:
docker:
runs-on: [self-hosted, linux, arch, homelab]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Read project version
id: version
shell: bash
run: |
version="$(python3 - <<'PY'
from pathlib import Path
import tomllib
print(tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"])
PY
)"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Log in to registry
shell: bash
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "${REGISTRY}" \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Build and push image
shell: bash
run: |
image="${REGISTRY}/${IMAGE_NAME}"
tags=("latest" "${{ steps.version.outputs.version }}")
case "${GITHUB_REF_NAME}" in
main)
tags+=("main" "prod")
;;
dev)
tags+=("dev")
;;
esac
build_args=()
for tag in "${tags[@]}"; do
build_args+=(-t "${image}:${tag}")
done
docker build "${build_args[@]}" .
for tag in "${tags[@]}"; do
docker push "${image}:${tag}"
done
+10 -4
View File
@@ -5,13 +5,19 @@ services:
dockerfile: Dockerfile
container_name: telegram-scraper
image: gcr.forust.xyz/forust/telegram-scraper:latest
user: 1000:1000
restart: unless-stopped
tty: true
user: "1000:1000"
restart: unless-stopped
ports:
- "7887:8080"
- 7887:8080
healthcheck:
test: ["CMD", "python", "-c", "import http.client,json;c=http.client.HTTPConnection('localhost',8080);c.request('GET','/health');r=c.getresponse();exit(0)if json.loads(r.read()).get('ok')else exit(1)"]
test:
[
CMD,
python,
-c,
import http.client,json;c=http.client.HTTPConnection('localhost',8080);c.request('GET','/health');r=c.getresponse();exit(0)if json.loads(r.read()).get('ok')else exit(1),
]
interval: 30s
timeout: 10s
retries: 3
+5 -3
View File
@@ -34,8 +34,8 @@ spec:
containers:
- name: telegram-scraper
image: gcr.forust.xyz/forust/telegram-scraper:latest
tty: true
stdin: true
tty: true
ports:
- containerPort: 8080
livenessProbe:
@@ -59,14 +59,16 @@ spec:
- metadata:
name: telegram-scraper-data
spec:
accessModes: ["ReadWriteOnce"]
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
- metadata:
name: telegram-scraper-session
spec:
accessModes: ["ReadWriteOnce"]
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Mi