From cbd63b7581bf291962e624e6778730aa5fc83ce1 Mon Sep 17 00:00:00 2001 From: moilanik Date: Mon, 15 Jun 2026 05:06:20 +0300 Subject: [PATCH] google ai kanssa katstottu pipeline --- .gitea/workflows/build_publish-artifact.yml | 297 +++++++++++++------- scripts/report-status.sh | 4 +- 2 files changed, 191 insertions(+), 110 deletions(-) diff --git a/.gitea/workflows/build_publish-artifact.yml b/.gitea/workflows/build_publish-artifact.yml index e3d34d8..b76f9c8 100644 --- a/.gitea/workflows/build_publish-artifact.yml +++ b/.gitea/workflows/build_publish-artifact.yml @@ -24,63 +24,89 @@ env: GIT_PAGES_PUBLISH_TOKEN: ${{ secrets.GIT_PAGES_PUBLISH_TOKEN }} REPO: ${{ github.repository }} +# CONCURRENCY ESTO: Vain yksi ajo kerrallaan per branch. +# Jos uusi commit työnnetään ennen kuin vanha valmistuu, vanha ajo perutaan (cancel-in-progress). +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: check: runs-on: ubuntu-latest outputs: artifact_exists: ${{ steps.check.outputs.artifact_exists }} - version: ${{ steps.check.outputs.version }} + next_version: ${{ steps.check.outputs.next_version }} steps: - uses: actions/checkout@v4 - - name: Pending - run: bash scripts/report-status.sh pending "Checking version..." ci-check + - name: Set Gitea status to PENDING + run: | + echo "===== gitea-ci-library - Check existing artifact | begin =====" + bash scripts/report-status.sh pending "Checking version..." ci-check - - name: Check existing artifact + - name: Check existing artifact and calculate version id: check run: | - VERSION=$(jq -r '.version' package.json) - echo "version=$VERSION" >> "$GITHUB_OUTPUT" + # 1. Luetaan versio ja pakotetaan se muotoon X.Y (katkaistaan mahdollinen .Z pois) + RAW_VERSION=$(jq -r '.version' package.json) + BASE_VERSION=$(echo "$RAW_VERSION" | cut -d'.' -f1-2) + echo "gitea-ci-library - Tunnistettu Major.Minor versio: $BASE_VERSION" - TAGS_JSON=$(curl -s -H "Authorization: token $GITEA_TOKEN" \ - "$GITEA_API_URL/api/v1/repos/$REPO/tags" 2>&1) - CURL_EXIT=$? + # 2. Haetaan tagit Gitean APIsta + TAGS_JSON=$(curl -s -f -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ + "${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}/tags") - if [ "${CURL_EXIT}" != "0" ]; then - echo "ERROR: curl failed with exit code ${CURL_EXIT}" >&2 - echo "artifact_exists=false" >> "$GITHUB_OUTPUT" - exit ${CURL_EXIT} - fi + # 3. Etsitään täsmääkö nykyinen commit (SHA) johonkin tagiin + TAG=$(echo "$TAGS_JSON" | jq -r 'if type == "array" then .[] | select(.commit.sha == "${{ github.sha }}") | .name else empty end' | head -1) - TAG=$(echo "$TAGS_JSON" | jq -r 'if type == "array" then .[] | select(.commit.sha == "'"$GITHUB_SHA"'") | .name else empty end' | head -1) if [ -n "$TAG" ]; then + # Tagi löytyi -> ohitetaan kaikki tuleva echo "artifact_exists=true" >> "$GITHUB_OUTPUT" - echo "artifact_tag=$TAG" >> "$GITHUB_OUTPUT" - echo "Build skipped: commit already tagged as $TAG" + echo "next_version=$TAG" >> "$GITHUB_OUTPUT" + echo "gitea-ci-library - Artefakti löytyi jo tagilla: $TAG." else + # Tagiä ei löytynyt -> lasketaan seuraava vapaa patch-numero echo "artifact_exists=false" >> "$GITHUB_OUTPUT" - echo "Build required: no tag for this commit" - fi + + HIGHEST_PATCH=$(echo "$TAGS_JSON" | jq -r --arg bv "$BASE_VERSION." ' + if type == "array" then + .[ ] | .name | select(startswith($bv)) | sub($bv; "") | tonumber + else empty end' | sort -rn | head -1) - - name: Report status - if: always() - run: | - VERSION="${{ steps.check.outputs.version }}" - ARTIFACT_EXISTS="${{ steps.check.outputs.artifact_exists }}" - ARTIFACT_TAG="${{ steps.check.outputs.artifact_tag }}" - if [ "${{ steps.check.outcome }}" = "success" ]; then - if [ "${ARTIFACT_EXISTS}" = "true" ]; then - bash scripts/report-status.sh success "Skip build: version $VERSION exists as $ARTIFACT_TAG" ci-check + if [ -z "$HIGHEST_PATCH" ]; then + NEXT_PATCH=0 else - bash scripts/report-status.sh success "Build version $VERSION required" ci-check + NEXT_PATCH=$((HIGHEST_PATCH + 1)) fi - else - bash scripts/report-status.sh failure "Check version $VERSION FAILED" ci-check - exit 1 + + FULL_VERSION="${BASE_VERSION}.${NEXT_PATCH}" + echo "next_version=$FULL_VERSION" >> "$GITHUB_OUTPUT" + echo "gitea-ci-library - Uusi vapaa versio: $FULL_VERSION" fi + - name: Set Gitea status to SUCCESS + if: success() + env: + EXISTS: ${{ steps.check.outputs.artifact_exists }} + VERSION: ${{ steps.check.outputs.next_version }} + run: | + echo "===== gitea-ci-library - Check existing artifact | success =====" + if [ "${EXISTS}" = "true" ]; then + bash scripts/report-status.sh success "Skip build: version $VERSION exists" ci-check + else + bash scripts/report-status.sh success "Build version $VERSION required" ci-check + fi + + - name: Set Gitea status to FAILURE + if: failure() + run: | + echo "===== gitea-ci-library - Check existing artifact | fail =====" + bash scripts/report-status.sh failure "Check version FAILED" ci-check + + # SINUN REUSABLE WORKFLOW KUTSUSI quality-gate: needs: [check] + # Ajetaan vain jos check-job totesi, että artefaktia ei ole olemassa if: needs.check.outputs.artifact_exists == 'false' uses: niko/gitea-ci-library/.gitea/workflows/quality-gate.yml@main secrets: inherit @@ -90,59 +116,75 @@ jobs: cucumber-node-image: ${{ inputs.cucumber-node-image }} build: - needs: [check, quality-gate] - if: | - needs.check.outputs.artifact_exists == 'false' && - needs.quality-gate.result == 'success' runs-on: ubuntu-latest + # Vaaditaan molemmat edelliset jobit + needs: [check, quality-gate] + # TÄRKEÄÄ: Gitea ajaa tämän VAIN jos check totesi 'false' JA quality-gate ONNISTUI. + # Jos quality-gate skipattiin, tämäkin skipataan automaattisesti ilman monimutkaisia result-tarkistuksia. + if: needs.check.outputs.artifact_exists == 'false' + steps: - uses: actions/checkout@v4 - - name: Pending - run: bash scripts/report-status.sh pending "Building Docker image..." ci-docker-build + - name: Set Gitea status to PENDING + run: | + echo "===== gitea-ci-library - Docker Build | begin =====" + bash scripts/report-status.sh pending "Building Docker image..." ci-docker-build - name: Build container - shell: bash id: build + # Tuodaan laskettu versio turvallisesti ympäristömuuttujaksi bashille + env: + VERSION: ${{ needs.check.outputs.next_version }} run: | - VERSION="${{ needs.check.outputs.version }}" NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ) + + # Jos tämä komento epäonnistuu, bash pysähtyy heti ja Gitea siirtyy FAILURE-steppiin docker build \ - --label "git.commit=${GITHUB_SHA:0:8}" \ - --label "git.commitBy=${GITHUB_ACTOR}" \ + --label "git.commit=${{ github.sha }}" \ + --label "git.commitBy=${{ github.actor }}" \ --label "build.date=${NOW}" \ -t "minimal:${VERSION}" . - echo "exit-code=$?" >> "$GITHUB_OUTPUT" - - name: Report status - if: always() - run: | - VERSION="${{ needs.check.outputs.version }}" - BUILD_EXIT="${{ steps.build.outputs.exit-code }}" - if [ "${BUILD_EXIT}" = "0" ]; then - bash scripts/report-status.sh success "Docker build $VERSION OK" ci-docker-build - else - bash scripts/report-status.sh failure "Docker build $VERSION FAILED" ci-docker-build - fi - exit ${BUILD_EXIT} - - - name: Save Docker image + # SUCCESS: Ajetaan vain jos Docker-build onnistui + - name: Report status SUCCESS if: success() + env: + VERSION: ${{ needs.check.outputs.next_version }} + run: | + echo "===== gitea-ci-library - Docker Build | success =====" + bash scripts/report-status.sh success "Docker build $VERSION OK" ci-docker-build + + # FAILURE: Ajetaan jos Docker-build (tai jokin muu aiempi steppi tässä jobissa) epäonnistui + - name: Report status FAILURE + if: failure() + env: + VERSION: ${{ needs.check.outputs.next_version }} + run: | + echo "===== gitea-ci-library - Docker Build | fail =====" + bash scripts/report-status.sh failure "Docker build $VERSION FAILED" ci-docker-build + + # Tallennus ja upotus ajetaan vain jos kaikki tähän asti onnistui (implisiittisesti success) + - name: Save Docker image + env: + VERSION: ${{ needs.check.outputs.next_version }} run: | - VERSION="${{ needs.check.outputs.version }}" mkdir -p /tmp/image docker save "minimal:${VERSION}" -o /tmp/image/artifact.tar - name: Upload Docker image artifact - if: success() uses: actions/upload-artifact@v4 with: name: docker-image path: /tmp/image/artifact.tar push: - needs: [check, build] runs-on: ubuntu-latest + # Vaaditaan check ja build. + needs: [check, build] + # TÄRKEÄÄ: Ajetaan VAIN jos build-job suoritettiin onnistuneesti (eikä sitä skipattu) + if: needs.check.outputs.artifact_exists == 'false' + steps: - uses: actions/checkout@v4 @@ -152,82 +194,121 @@ jobs: name: docker-image path: /tmp/image - - name: Pending - run: bash scripts/report-status.sh pending "Pushing to registry..." ci-docker-push + - name: Set Gitea status to PENDING + run: | + echo "===== gitea-ci-library - Docker Push | begin =====" + bash scripts/report-status.sh pending "Pushing to registry..." ci-docker-push - name: Push to Gitea Packages - shell: bash id: push + # Tuodaan versio ja tokenit turvallisesti ympäristömuuttujiksi bashille + env: + VERSION: ${{ needs.check.outputs.next_version }} + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} run: | - VERSION="${{ needs.check.outputs.version }}" docker load -i /tmp/image/artifact.tar - REGISTRY=$(echo "$GITEA_API_URL" | sed 's|https://||') - IMAGE="$REGISTRY/niko/minimal:$VERSION" - docker tag "minimal:$VERSION" "$IMAGE" - docker login "$REGISTRY" -u niko -p "$GITEA_TOKEN" - docker push "$IMAGE" - PUSH_EXIT=$? - docker logout "$REGISTRY" > /dev/null 2>&1 - echo "exit-code=$PUSH_EXIT" >> "$GITHUB_OUTPUT" - - name: Report status - if: always() + # Haetaan rekisterin osoite Gitean omasta muuttujasta (esim. ://example.com) + # Poistetaan mahdollinen https:// tai http:// alusta sedillä + REGISTRY=$(echo "${{ gitea.server_url }}" | sed -e 's|^https://||' -e 's|^http://||') + + IMAGE="$REGISTRY/${{ gitea.repository }}:$VERSION" + + echo "Tagging image: $IMAGE" + docker tag "minimal:$VERSION" "$IMAGE" + + # Kirjaudutaan sisään käyttäen Gitean automaattista ajonaikaista toimijaa (github.actor) + echo "$GITEA_TOKEN" | docker login "$REGISTRY" -u "${{ github.actor }}" --password-stdin + + # Työnnetään kontti rekisteriin. Jos tämä epäonnistuu, bash pysähtyy heti. + docker push "$IMAGE" + + # Kirjaudutaan ulos turvallisesti + docker logout "$REGISTRY" + + # SUCCESS: Raportoidaan onnistuminen + - name: Report status SUCCESS + if: success() + env: + VERSION: ${{ needs.check.outputs.next_version }} run: | - VERSION="${{ needs.check.outputs.version }}" - PUSH_EXIT="${{ steps.push.outputs.exit-code }}" - if [ "${PUSH_EXIT}" = "0" ]; then - bash scripts/report-status.sh success "Docker push $VERSION OK" ci-docker-push - else - bash scripts/report-status.sh failure "Docker push $VERSION FAILED" ci-docker-push - fi - exit ${PUSH_EXIT} + echo "===== gitea-ci-library - Docker Push | success =====" + bash scripts/report-status.sh success "Docker push $VERSION OK" ci-docker-push + + # FAILURE: Raportoidaan epäonnistuminen jos push kaatui + - name: Report status FAILURE + if: failure() + env: + VERSION: ${{ needs.check.outputs.next_version }} + run: | + echo "===== gitea-ci-library - Docker Push | fail =====" + bash scripts/report-status.sh failure "Docker push $VERSION FAILED" ci-docker-push tag-commit: - needs: [check, push] runs-on: ubuntu-latest + # Vaaditaan check (version saamiseksi) ja push (varmistetaan että kontti on rekisterissä) + needs: [check, push] + # TÄRKEÄÄ: Tämä ajetaan vain, jos uusi kontti todella rakennettiin ja pushattiin. + # Jos artefakti oli jo olemassa, tämäkin skipataan automaattisesti. + if: needs.check.outputs.artifact_exists == 'false' + steps: - uses: actions/checkout@v4 - - name: Pending - run: bash scripts/report-status.sh pending "Creating tag..." ci-docker-tag + - name: Set Gitea status to PENDING + run: | + echo "===== gitea-ci-library - Create Tag | begin =====" + bash scripts/report-status.sh pending "Creating tag..." ci-docker-tag - name: Create git tag - shell: bash id: tag + # Tuodaan kaikki tarvittavat muuttujat Gitean kontekstista suoraan Bashille env: + VERSION: ${{ needs.check.outputs.next_version }} + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} REPO: ${{ github.repository }} + SERVER_URL: ${{ gitea.server_url }} + RUN_NUMBER: ${{ github.run_number }} + SHA: ${{ github.sha }} run: | - VERSION="${{ needs.check.outputs.version }}" + # Tehdään API-kutsu ja napataan HTTP-statuskoodi talteen HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ - "$GITEA_API_URL/api/v1/repos/$REPO/tags" \ + "$SERVER_URL/api/v1/repos/$REPO/tags" \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{ \"tag_name\": \"$VERSION\", - \"message\": \"Build #$GITHUB_RUN_NUMBER\", - \"target\": \"$GITHUB_SHA\" + \"message\": \"Build #$RUN_NUMBER\", + \"target\": \"$SHA\" }") - if [ "$HTTP_CODE" = "201" ]; then - echo "Tag $VERSION created" - echo "status=success" >> "$GITHUB_OUTPUT" - elif [ "$HTTP_CODE" = "409" ]; then - echo "Tag $VERSION already exists (parallel build won), skipping" - echo "status=success" >> "$GITHUB_OUTPUT" + echo "gitea-ci-library - Gitea API palautti statuskoodin: $HTTP_CODE" + + # 201 = Luotu onnistuneesti, 409 = Tagi on jo olemassa (esim. rinnakkainen ajo ehti ensin) + if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "409" ]; then + echo "Tag $VERSION OK" + # Tämä asettaa stepin onnistuneeksi (Gitea Actions tulkitsee tämän automaattisesti) + exit 0 else - echo "status=failure" >> "$GITHUB_OUTPUT" - echo "exit-code=$HTTP_CODE" >> "$GITHUB_OUTPUT" + echo "Tagging failed with HTTP $HTTP_CODE" >&2 + # Jos koodi on jotain muuta (esim 401 tai 404), kaadetaan steppi exit 1:llä + exit 1 fi - - name: Report status - if: always() + # SUCCESS: Ajetaan vain jos tagitus onnistui (eli API antoi 201 tai 409) + - name: Report status SUCCESS + if: success() + env: + VERSION: ${{ needs.check.outputs.next_version }} run: | - VERSION="${{ needs.check.outputs.version }}" - TAG_STATUS="${{ steps.tag.outputs.status }}" - if [ "${TAG_STATUS}" = "success" ]; then - bash scripts/report-status.sh success "Tag $VERSION OK" ci-docker-tag - else - TAG_EXIT="${{ steps.tag.outputs.exit-code }}" - bash scripts/report-status.sh failure "Tag $VERSION FAILED" ci-docker-tag - exit ${TAG_EXIT} - fi + echo "===== gitea-ci-library - Create Tag | success =====" + bash scripts/report-status.sh success "Tag $VERSION OK" ci-docker-tag + + # FAILURE: Ajetaan jos API-kutsu palautti virheen ja skripti teki 'exit 1' + - name: Report status FAILURE + if: failure() + env: + VERSION: ${{ needs.check.outputs.next_version }} + run: | + echo "===== gitea-ci-library - Create Tag | fail =====" + bash scripts/report-status.sh failure "Tag $VERSION FAILED" ci-docker-tag diff --git a/scripts/report-status.sh b/scripts/report-status.sh index abf7455..a907208 100755 --- a/scripts/report-status.sh +++ b/scripts/report-status.sh @@ -37,8 +37,8 @@ if [ "$HTTP_CODE" = "201" ]; then fi if [ -z "$HTTP_CODE" ]; then - echo "ERROR: Failed to connect to Gitea API at $GITEA_API_URL" >&2 + echo "gitea-ci-library - ERROR: Failed to connect to Gitea API at $GITEA_API_URL" >&2 else - echo "ERROR: API returned HTTP $HTTP_CODE" >&2 + echo "gitea-ci-library - ERROR: gitea-ci-library, API returned HTTP $HTTP_CODE" >&2 fi exit 1