commit 05037199e1cfccac33ee32549b0f31c597596aac Author: dresber Date: Sat May 9 10:17:29 2026 +0200 Initial commit diff --git a/.gitea/workflows/docker-publish.yml b/.gitea/workflows/docker-publish.yml new file mode 100644 index 0000000..6d0ea09 --- /dev/null +++ b/.gitea/workflows/docker-publish.yml @@ -0,0 +1,66 @@ +name: Reusable Docker Publish + +on: + workflow_call: + inputs: + image_name: + required: true + type: string + dockerfile_path: + type: string + default: "." + secrets: + REGISTRY_USERNAME: { required: true } + REGISTRY_PASSWORD: { required: true } + DOCKER_REGISTRY: { required: true } + NTFY_TOPIC: { required: true } + NTFY_TOKEN: { required: true } + NTFY_SERVER: { required: true } + +jobs: + publish: + runs-on: docker + container: + image: gitea.tech-buddy.at/bitbuddydev/gitea_runner_python314:dev-bda315b82bb23d83065b77d91fedf0e20d9accf1 + credentials: + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract Tags + id: vars + shell: bash + run: | + SHA_SHORT="$(git rev-parse --short HEAD)" + FULL_IMAGE="${{ secrets.DOCKER_REGISTRY }}/${{ inputs.image_name }}" + TAGS="-t ${FULL_IMAGE}:${SHA_SHORT}" + + if echo "${{ gitea.ref }}" | grep -q '^refs/tags/v'; then + VERSION="${{ gitea.ref_name }}" + VERSION="${VERSION#v}" + MAJOR="$(echo "$VERSION" | cut -d. -f1)" + MINOR="$(echo "$VERSION" | cut -d. -f1,2)" + TAGS="${TAGS} -t ${FULL_IMAGE}:latest -t ${FULL_IMAGE}:${VERSION} -t ${FULL_IMAGE}:${MINOR} -t ${FULL_IMAGE}:${MAJOR}" + fi + + echo "docker_tags=${TAGS}" >> "$GITEA_OUTPUT" + echo "full_image=${FULL_IMAGE}" >> "$GITEA_OUTPUT" + + - name: Docker Login + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login "${{ secrets.DOCKER_REGISTRY }}" -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build and Push + run: | + export DOCKER_BUILDKIT=1 + docker build ${{ steps.vars.outputs.docker_tags }} ${{ inputs.dockerfile_path }} + + IMAGE="${{ steps.vars.outputs.full_image }}" + for part in ${{ steps.vars.outputs.docker_tags }}; do + if [[ "$part" == "${IMAGE}:"* ]]; then + docker push "$part" + fi + done \ No newline at end of file diff --git a/.gitea/workflows/notifications.yml b/.gitea/workflows/notifications.yml new file mode 100644 index 0000000..0c1d8f4 --- /dev/null +++ b/.gitea/workflows/notifications.yml @@ -0,0 +1,52 @@ +name: Notification + +on: + workflow_call: + inputs: + job_status: + required: true + type: string + job_name: + required: true + type: string + secrets: + NTFY_TOPIC: { required: true } + NTFY_TOKEN: { required: true } + NTFY_SERVER: { required: true } + +jobs: + notify: + runs-on: docker + steps: + - name: Send Notification + shell: bash + run: | + # Icon und Titel basierend auf Status + if [ "${{ inputs.job_status }}" == "success" ]; then + ICON="✅" + TITLE="Fixed: ${{ inputs.job_name }} for ${{ gitea.repository }}" + else + ICON="❌" + TITLE="Failed: ${{ inputs.job_name }} for ${{ gitea.repository }}" + fi + + COMMIT_SUBJECT="$(git log -1 --pretty=%s || echo 'Commit info unavailable')" + RUN_URL="${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_number }}" + + cat </tmp/ntfy-payload.json + { + "topic": "${{ secrets.NTFY_TOPIC }}", + "title": "${ICON} ${TITLE}", + "message": "Ref: ${{ gitea.ref_name }}\nCommit: ${COMMIT_SUBJECT}\n\nRun URL: ${RUN_URL}", + "click": "${RUN_URL}", + "actions": [ + { "action": "view", "label": "Open Run", "url": "${RUN_URL}" } + ] + } + EOF + + curl -fsS \ + -H "Authorization: Bearer ${{ secrets.NTFY_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d @/tmp/ntfy-payload.json \ + "${{ secrets.NTFY_SERVER }}" \ No newline at end of file diff --git a/.gitea/workflows/python-checks.yml b/.gitea/workflows/python-checks.yml new file mode 100644 index 0000000..710629e --- /dev/null +++ b/.gitea/workflows/python-checks.yml @@ -0,0 +1,60 @@ +name: Reusable Python Checks + +on: + workflow_call: + inputs: + python_version: + type: string + default: "3.14" + test_command: + type: string + default: "coverage run -m pytest" + +jobs: + check: + runs-on: docker + container: + image: gitea.tech-buddy.at/bitbuddydev/gitea_runner_python314:dev-bda315b82bb23d83065b77d91fedf0e20d9accf1 + credentials: + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Tools & Deps + run: | + python -m pip install --upgrade pip setuptools wheel + pip install -e .[dev] || pip install -e .[test] || pip install -e . + pip install ruff coverage pip-audit bandit + + - name: Linting + run: ruff check app tests + + - name: Tests + run: | + ${{ inputs.test_command }} + coverage report --fail-under=60 + coverage xml + coverage html + + - name: Security Scan + run: | + pip freeze | grep -v "git+" > req.txt + pip-audit -r req.txt + bandit -r app/ + + - name: Upload Coverage + if: always() + uses: actions/upload-artifact@v3 + with: + name: coverage-report + path: | + htmlcov/ + coverage.xml + + - name: Notify on Failure + if: failure() + run: | + # (Deine ntfy-Logik hier einfügen) \ No newline at end of file