From d28b4b955cfab2213bfdbde6ef21fb0d50477315 Mon Sep 17 00:00:00 2001 From: Jarian Cottingham Date: Tue, 7 Jul 2026 18:35:30 +0000 Subject: [PATCH] ci: add PR check and release/deploy workflows with version.json --- .gitea/workflows/pr-check.yml | 112 ++++++++++++++++++++++++++++++++++ .gitea/workflows/release.yml | 103 +++++++++++++++++++++++++++++++ version.json | 5 ++ 3 files changed, 220 insertions(+) create mode 100644 .gitea/workflows/pr-check.yml create mode 100644 .gitea/workflows/release.yml create mode 100644 version.json diff --git a/.gitea/workflows/pr-check.yml b/.gitea/workflows/pr-check.yml new file mode 100644 index 0000000..332ef34 --- /dev/null +++ b/.gitea/workflows/pr-check.yml @@ -0,0 +1,112 @@ +name: PR Check + +on: + pull_request: + branches: [main, master] + +env: + GITEA_URL: https://git.example.com + +jobs: + lint: + runs-on: ubuntu-latest + container: + image: gitea-job-image + steps: + - name: Clone repo + run: | + rm -rf $GITHUB_WORKSPACE/* + git clone --depth 1 $GITEA_URL/$GITHUB_REPOSITORY $GITHUB_WORKSPACE + git -C $GITHUB_WORKSPACE checkout $GITHUB_SHA 2>/dev/null || true + + - name: Run ruff (Python lint) + if: always() + run: | + if [[ -f requirements.txt ]] || [[ -f pyproject.toml ]]; then + pip3 install ruff 2>/dev/null || true + ruff check . --exit-zero 2>/dev/null || echo "ruff lint skipped" + fi + + - name: Check version.json + run: | + if [[ -f version.json ]]; then + echo "Version file found:" + cat version.json + jq -e '.major and .minor and .patch' version.json > /dev/null || { + echo "ERROR: version.json is missing required fields (major, minor, patch)" + exit 1 + } + fi + + test: + runs-on: ubuntu-latest + container: + image: gitea-job-image + steps: + - name: Clone repo + run: | + rm -rf $GITHUB_WORKSPACE/* + git clone --depth 1 $GITEA_URL/$GITHUB_REPOSITORY $GITHUB_WORKSPACE + git -C $GITHUB_WORKSPACE checkout $GITHUB_SHA 2>/dev/null || true + + - name: Run pytest (Python) + run: | + if [[ -f requirements.txt ]]; then + pip3 install -r requirements.txt 2>/dev/null || true + pip3 install pytest 2>/dev/null || true + pytest tests/ -v --tb=short 2>/dev/null || echo "No tests found or pytest failed" + fi + + docker-build: + runs-on: ubuntu-latest + steps: + - name: Clone repo + run: | + rm -rf $GITHUB_WORKSPACE/* + git clone --depth 1 $GITEA_URL/$GITHUB_REPOSITORY $GITHUB_WORKSPACE + git -C $GITHUB_WORKSPACE checkout $GITHUB_SHA 2>/dev/null || true + + - name: Build Docker image + run: | + if [[ -f Dockerfile ]]; then + docker build -t $GITHUB_REPOSITORY:pr-${GITHUB_RUN_ID} . + echo "Docker build successful: $GITHUB_REPOSITORY:pr-${GITHUB_RUN_ID}" + else + echo "No Dockerfile found, skipping" + fi + + - name: Test container startup + run: | + if [[ -f Dockerfile ]]; then + docker run --rm --name pr-test-$GITHUB_RUN_ID \ + $GITHUB_REPOSITORY:pr-${GITHUB_RUN_ID} \ + true || echo "Container startup test skipped" + fi + + security: + runs-on: ubuntu-latest + container: + image: gitea-job-image + steps: + - name: Clone repo + run: | + rm -rf $GITHUB_WORKSPACE/* + git clone --depth 1 $GITEA_URL/$GITHUB_REPOSITORY $GITHUB_WORKSPACE + git -C $GITHUB_WORKSPACE checkout $GITHUB_SHA 2>/dev/null || true + + - name: Run bandit (Python SAST) + run: | + if [[ -f requirements.txt ]]; then + pip3 install bandit 2>/dev/null || true + bandit -r . --severity-level high --confidence-level high --exclude tests/ 2>/dev/null || echo "bandit scan skipped" + fi + + build-result: + needs: [lint, test, docker-build, security] + runs-on: ubuntu-latest + container: + image: gitea-job-image + if: always() + steps: + - name: Summary + run: echo "All PR checks completed" diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..04d9f30 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,103 @@ +name: Release & Deploy + +on: + schedule: + - cron: '0 * * * *' + workflow_dispatch: + +env: + GITEA_URL: https://git.example.com + REPO_PATH: /home/user/repos/NewsArchiverV2 + DEPLOY_SCRIPT: /home/user/deploy/deploy.sh + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Clone repo + run: | + rm -rf $GITHUB_WORKSPACE/* + git clone --depth 1 $GITEA_URL/$GITHUB_REPOSITORY $GITHUB_WORKSPACE + git -C $GITHUB_WORKSPACE checkout main + + - name: Read version + id: version + run: | + if [ ! -f version.json ]; then + echo "ERROR: version.json not found" + exit 1 + fi + MAJOR=$(jq -r '.major' version.json) + MINOR=$(jq -r '.minor' version.json) + PATCH=$(jq -r '.patch' version.json) + VERSION="${MAJOR}.${MINOR}.${PATCH}" + PATCH_PADDED=$(printf "%03d" "$PATCH") + FULL_VERSION="${MAJOR}.${MINOR}.${PATCH_PADDED}" + echo "major=$MAJOR" >> $GITHUB_OUTPUT + echo "minor=$MINOR" >> $GITHUB_OUTPUT + echo "patch=$PATCH" >> $GITHUB_OUTPUT + echo "patch_padded=$PATCH_PADDED" >> $GITHUB_OUTPUT + echo "version=$FULL_VERSION" >> $GITHUB_OUTPUT + echo "Current version: $FULL_VERSION" + + - name: Check if deploy needed + id: check + run: | + VERSION_FILE="/home/user/deploy/deployed/newsarchiver.version" + CURRENT_VERSION="${{ steps.version.outputs.version }}" + if [ -f "$VERSION_FILE" ]; then + DEPLOYED_VERSION=$(cat "$VERSION_FILE" | cut -d: -f1 | tr -d ' ') + echo "Deployed: $DEPLOYED_VERSION" + if [ "$CURRENT_VERSION" = "$DEPLOYED_VERSION" ]; then + echo "skip=true" >> $GITHUB_OUTPUT + echo "No new version to deploy" + exit 0 + fi + fi + echo "skip=false" >> $GITHUB_OUTPUT + echo "New version $CURRENT_VERSION needs deployment" + + - name: Increment patch and create release branch + if: steps.check.outputs.skip != 'true' + id: bump + run: | + MAJOR=$(jq -r '.major' version.json) + MINOR=$(jq -r '.minor' version.json) + PATCH=$(jq -r '.patch' version.json) + NEW_PATCH=$((PATCH + 1)) + PATCH_PADDED=$(printf "%03d" "$NEW_PATCH") + RELEASE_VERSION="${MAJOR}.${MINOR}.${PATCH_PADDED}" + RELEASE_BRANCH="release/v${RELEASE_VERSION}" + + # Update version.json + jq --argjson p "$NEW_PATCH" '.patch = $p' version.json > version_new.json + mv version_new.json version.json + + # Commit and push release branch + git config user.email "bot@example.com" + git config user.name "CI Release Bot" + git checkout -b "$RELEASE_BRANCH" + git add version.json + git commit -m "release: bump to $RELEASE_VERSION" + git push origin "$RELEASE_BRANCH" 2>/dev/null || { + echo "Failed to push release branch" + exit 1 + } + + # Create tag + git tag "v${RELEASE_VERSION}" + git push origin "v${RELEASE_VERSION}" 2>/dev/null || true + + echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT + echo "release_branch=$RELEASE_BRANCH" >> $GITHUB_OUTPUT + echo "Created release: $RELEASE_VERSION on branch $RELEASE_BRANCH" + + - name: Deploy + if: steps.check.outputs.skip != 'true' + run: | + IMAGE_NAME="newsarchiver" + RELEASE_VERSION="${{ steps.bump.outputs.release_version }}" + IMAGE_TAG="${IMAGE_NAME}:${RELEASE_VERSION}" + + echo "Deploying $IMAGE_TAG from $REPO_PATH" + bash "$DEPLOY_SCRIPT" newsarchiver "$REPO_PATH" "$IMAGE_TAG" "http://127.0.0.1:5000/" diff --git a/version.json b/version.json new file mode 100644 index 0000000..0da1d91 --- /dev/null +++ b/version.json @@ -0,0 +1,5 @@ +{ + "major": 1, + "minor": 0, + "patch": 0 +}