diff --git a/.gitea/workflows/docker-build-push.yml b/.gitea/workflows/docker-build-push.yml index 230d328..f666f67 100644 --- a/.gitea/workflows/docker-build-push.yml +++ b/.gitea/workflows/docker-build-push.yml @@ -81,11 +81,12 @@ jobs: if [ -n "${DOCKER_UI_URL:-}" ] && [ -n "${VERSION:-}" ]; then CONTAINER_URL="${DOCKER_UI_URL}/${DOCKER_IMAGE_NAME}/${VERSION}" fi - bash .ci/scripts/report-status.sh success "Docker build & push ${VERSION} OK" ci-docker-build-push "" "$CONTAINER_URL" - - - name: Report status FAILURE - if: failure() - run: bash .ci/scripts/report-status.sh failure "Docker build & push ${VERSION} FAILED" ci-docker-build-push + DIR=$(dirname "${DOCKERFILE}") + if [ "$DIR" != "." ]; then + bash .ci/scripts/report-status.sh success "${DIR}: Docker push ${VERSION}" "${DIR}-ci-docker-build-push" "" "$CONTAINER_URL" + else + bash .ci/scripts/report-status.sh success "Docker push ${VERSION}" ci-docker-build-push "" "$CONTAINER_URL" + fi tag-commit: runs-on: ubuntu-latest diff --git a/.gitea/workflows/helm-build-push.yml b/.gitea/workflows/helm-build-push.yml index bec4aab..f6b7501 100644 --- a/.gitea/workflows/helm-build-push.yml +++ b/.gitea/workflows/helm-build-push.yml @@ -76,7 +76,11 @@ jobs: run: | CHART_NAME=$(grep '^name:' "${CHART_PATH}/Chart.yaml" | awk '{print $2}') UI_URL="${HELM_UI_URL}/${CHART_NAME}/${VERSION}" - bash .ci/scripts/report-status.sh success "Helm chart ${VERSION}" ci-helm-build-push "" "$UI_URL" + if [ "${CHART_PATH}" != "." ] && [ -n "${CHART_PATH}" ]; then + bash .ci/scripts/report-status.sh success "${CHART_PATH}: Helm push ${VERSION}" "${CHART_PATH}-ci-helm-build-push" "" "$UI_URL" + else + bash .ci/scripts/report-status.sh success "Helm push ${VERSION}" ci-helm-build-push "" "$UI_URL" + fi tag-commit: runs-on: ubuntu-latest diff --git a/git-pages/files/retention-cleanup.sh b/git-pages/files/retention-cleanup.sh index 82bb30b..653fd6b 100644 --- a/git-pages/files/retention-cleanup.sh +++ b/git-pages/files/retention-cleanup.sh @@ -176,46 +176,90 @@ if [ "${#TO_DELETE[@]}" -eq 0 ]; then fi echo "" -echo "=== Phase 4: whiteout deletion ===" -echo "Creating whiteout tar for ${#TO_DELETE[@]} report(s)..." +echo "=== Phase 4: full site rebuild ===" +echo "Rebuilding site (${#TO_DELETE[@]} report(s) to delete)..." -WHITEOUT_TAR=$(mktemp) -trap 'rm -f "$WHITEOUT_TAR"' EXIT +ARCHIVE_FILE=$(mktemp) +SITE_DIR=$(mktemp -d) +NEW_TAR=$(mktemp) +cleanup_phase4() { + rm -f "$ARCHIVE_FILE" "$NEW_TAR" + rm -rf "$SITE_DIR" +} +trap cleanup_phase4 EXIT -python3 -c " -import tarfile, sys +# Try archive.tar first +echo "Downloading archive.tar..." +HTTP_CODE=$(curl_with_host -o "$ARCHIVE_FILE" -w "%{http_code}" -sS "${PAGES_URL}/.git-pages/archive.tar") -tar = tarfile.open(name='${WHITEOUT_TAR}', mode='w') +if [ "$HTTP_CODE" = "200" ] && tar -tf "$ARCHIVE_FILE" >/dev/null 2>&1; then + echo "Extracting archive..." + tar -xf "$ARCHIVE_FILE" -C "$SITE_DIR" -dirs = set() -for d in sys.argv[1:]: - dirs.add(d.strip()) + for dir in "${TO_DELETE[@]}"; do + if [ -d "$SITE_DIR/$dir" ]; then + echo " Removing: $dir" + rm -rf "$SITE_DIR/$dir" + fi + done +else + echo "archive.tar failed (HTTP ${HTTP_CODE}) - falling back to manifest-based rebuild" -tarinfo = tarfile.TarInfo() -tarinfo.type = tarfile.CHRTYPE -tarinfo.devmajor = 0 -tarinfo.devminor = 0 + ALL_PATHS=$(echo "$MANIFEST" | jq -r '.contents | keys[]' 2>/dev/null || true) -for d in sorted(dirs, key=len, reverse=True): - info = tarinfo - info.name = d - tar.addfile(info) + if [ -z "$ALL_PATHS" ]; then + echo "ERROR: no files in manifest - cannot rebuild" >&2 + exit 1 + fi -tar.close() -" "${TO_DELETE[@]}" + EXCLUDE_GREP="" + for dir in "${TO_DELETE[@]}"; do + EXCLUDE_GREP="${EXCLUDE_GREP}${EXCLUDE_GREP:+|}^${dir}/" + done -echo "Patching ${PAGES_URL}/ with whiteout tar..." -HTTP_CODE=$(curl_with_host -X PATCH "${PAGES_URL}/" \ + if [ -n "$EXCLUDE_GREP" ]; then + KEEP_PATHS=$(echo "$ALL_PATHS" | grep -v -E "$EXCLUDE_GREP" || true) + else + KEEP_PATHS="$ALL_PATHS" + fi + + if [ -z "$KEEP_PATHS" ]; then + echo "No files to keep - site will be empty" + mkdir -p "$SITE_DIR/__placeholder__" + echo "placeholder" > "$SITE_DIR/__placeholder__/index.html" + else + FILE_COUNT=$(echo "$KEEP_PATHS" | wc -l | tr -d ' ') + echo "Downloading ${FILE_COUNT} file(s)..." + while IFS= read -r path; do + [ -z "$path" ] && continue + dir=$(dirname "$SITE_DIR/$path") + mkdir -p "$dir" + curl_with_host -o "$SITE_DIR/$path" -sS "${PAGES_URL}/${path}" || { + echo " WARN: failed to download ${path}" + } + done <<< "$KEEP_PATHS" + fi +fi + +if [ -z "$(ls -A "$SITE_DIR" 2>/dev/null)" ]; then + echo "Site is empty - creating placeholder" + mkdir -p "$SITE_DIR/__placeholder__" + echo "placeholder" > "$SITE_DIR/__placeholder__/index.html" +fi + +tar -cf "$NEW_TAR" -C "$SITE_DIR" . + +echo "PUT: replacing site contents..." +HTTP_CODE=$(curl_with_host -X PUT "${PAGES_URL}/" \ -H "Content-Type: application/x-tar" \ - -H "Atomic: no" \ - --data-binary @"${WHITEOUT_TAR}" \ + --data-binary @"${NEW_TAR}" \ -w "%{http_code}" \ -o /dev/null) -echo "HTTP $HTTP_CODE" -if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "204" ]; then - echo "Retention cleanup finished." +echo "HTTP ${HTTP_CODE}" +if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "204" ]; then + echo "Site rebuild completed." else - echo "ERROR: retention HTTP ${HTTP_CODE}" >&2 + echo "ERROR: PUT HTTP ${HTTP_CODE}" >&2 exit 1 fi diff --git a/git-pages/templates/init-job.yaml b/git-pages/templates/init-job.yaml index ef6403b..9cc1605 100644 --- a/git-pages/templates/init-job.yaml +++ b/git-pages/templates/init-job.yaml @@ -6,7 +6,7 @@ metadata: labels: {{- include "git-pages.componentLabels" . | nindent 4 }} annotations: - "helm.sh/hook": post-install, post-upgrade + "helm.sh/hook": post-install "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation spec: backoffLimit: 5 @@ -32,6 +32,16 @@ spec: -H "Host: {{ .Values.ingress.host }}" \ -o /dev/null "http://git-pages:3000/.git-pages/health" do sleep 2; done + echo "Init: checking if site already exists..." + MANIFEST=$(curl -sf \ + -H "Host: {{ .Values.ingress.host }}" \ + "http://git-pages:3000/.git-pages/manifest.json" 2>/dev/null || echo "") + + if echo "$MANIFEST" | grep -q '"contents"'; then + echo "Init: site already initialized, skipping" + exit 0 + fi + echo "Init: creating placeholder site..." WORK=$(mktemp -d) mkdir -p "$WORK/__init__" diff --git a/skills/consumer-pipelines/REFERENCE.md b/skills/consumer-pipelines/REFERENCE.md index 58ae7ce..9e11d46 100644 --- a/skills/consumer-pipelines/REFERENCE.md +++ b/skills/consumer-pipelines/REFERENCE.md @@ -202,7 +202,16 @@ jobs: - name: Report if: always() - run: bash .ci/scripts/ci-report.sh "" ${{ job.status }} + run: | + bash .ci/scripts/ci-report.sh " test report" ${{ job.status }} +``` + +Monorepossa context ja description sisältävät komponentin nimen: +```yaml + - name: Report + if: always() + run: | + bash .ci/scripts/ci-report.sh ": test report" . ${{ job.status }} ``` **Usean runnerin cache-ongelma:** Jos eri kerroilla käynnistyy eri runnereita, @@ -218,6 +227,7 @@ niillä voi olla eri versio `latest`-imagen digesteistä. Ratkaisuja: ### Taso 1: Ei jälkikäsittelyä +Single repo: ```yaml - name: Run tests shell: bash @@ -227,11 +237,27 @@ niillä voi olla eri versio `latest`-imagen digesteistä. Ratkaisuja: - name: Report if: always() - run: bash .ci/scripts/ci-report.sh "" ${{ job.status }} + run: | + bash .ci/scripts/ci-report.sh " test report" ${{ job.status }} +``` + +Monorepo: +```yaml +- name: Run tests + shell: bash + run: | + mkdir -p "reports/" + + +- name: Report + if: always() + run: | + bash .ci/scripts/ci-report.sh ": test report" . ${{ job.status }} ``` ### Taso 2: Jälkikäsittely tarvitaan +Single repo: ```yaml - name: Run tests shell: bash @@ -249,7 +275,30 @@ niillä voi olla eri versio `latest`-imagen digesteistä. Ratkaisuja: - name: Report if: always() - run: bash .ci/scripts/ci-report.sh "" ${{ job.status }} + run: | + bash .ci/scripts/ci-report.sh " test report" ${{ job.status }} +``` + +Monorepo: +```yaml +- name: Run tests + shell: bash + run: | + mkdir -p "reports/" + > "reports//results.txt" 2>&1 + +- name: Post-process coverage + if: always() + run: /coverage/-hakemistoon> + +- name: Post-process test report + if: always() + run: + +- name: Report + if: always() + run: | + bash .ci/scripts/ci-report.sh ": test report" . ${{ job.status }} ``` ### Väärin vs oikein — yksi asia per step @@ -273,7 +322,16 @@ niillä voi olla eri versio `latest`-imagen digesteistä. Ratkaisuja: - name: Report if: always() - run: bash .ci/scripts/ci-report.sh "Helm kubeconform" helm-test kubeconform ${{ job.status }} + run: | + bash .ci/scripts/ci-report.sh "Helm kubeconform" helm-test kubeconform ${{ job.status }} +``` + +Monorepossa: +```yaml +- name: Report + if: always() + run: | + bash .ci/scripts/ci-report.sh ": Helm kubeconform" .helm-test kubeconform ${{ job.status }} ``` ### Väärin vs oikein — post-process @@ -509,6 +567,15 @@ jobs: suites: ' ' ``` +**Commit status -kontekstit monorepossa:** Testiraporttien `ci-report.sh`-kutsussa +context ja description sisältävät komponentin nimen: +```yaml + - name: Report + if: always() + run: | + bash .ci/scripts/ci-report.sh ": Unit test report" .unit-tests bats ${{ job.status }} +``` + ### Version elinkaari per komponentti `GIT_TAG_PREFIX` takaa että eri komponenttien versiohistoria pysyy erillään. diff --git a/skills/consumer-pipelines/SKILL.md b/skills/consumer-pipelines/SKILL.md index 542fc0c..e860a50 100644 --- a/skills/consumer-pipelines/SKILL.md +++ b/skills/consumer-pipelines/SKILL.md @@ -158,6 +158,35 @@ Tiedostonimet `.gitea/workflows/`-kansiossa noudattavat yhtenäistä rakennetta: Single repossa `` jätetään pois. Monorepossa prefiksi pitää komponentin tiedostot yhdessä. +### 6.1 Commit status -nimeäminen + +`ci-report.sh`-kutsun `description` (2. argumentti) ja `context` (3. argumentti) +noudattavat seuraavaa kaavaa: + +**Single repo:** +``` +context: (esim. unit-tests, acc-tests) +description: test report (esim. Unit test report) +``` + +**Monorepo:** +``` +context: . (esim. library.unit-tests) +description: : test report (esim. Library: Unit test report) +``` + +> Gitea YAML: `run:` laita lainausmerkeillä `run: |`-blockiin — Gitea ei tue lainausmerkkejä yhden rivin `run:`-komennoissa. +> +> ```yaml +> - name: Report +> if: always() +> run: | +> bash .ci/scripts/ci-report.sh ": test report" . ${{ job.status }} +> ``` + +Build/push-status (Docker, Helm) on providerin hallussa — consumer ei vaikuta +niiden nimeämiseen. + ## 7. Artifact-kuri Gitea Actionsin `upload-artifact` jättää pysyvän tiedoston. Artifakteja ei käytetä