loading
Generated 2026-06-28T10:07:31+00:00

All Files ( 52.33% covered at 4.69 hits/line )

12 files in total.
472 relevant lines, 247 lines covered and 225 lines missed. ( 52.33% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
gitea-reports/files/retention-cleanup.sh 0.00 % 66 35 0 35 0.00
gitea-reports/files/retention-lib.sh 0.00 % 32 12 0 12 0.00
gitea-reports/files/retention-run.sh 0.00 % 6 3 0 3 0.00
scripts/check-version.sh 100.00 % 60 39 39 0 13.69
scripts/ci-report.sh 0.00 % 109 61 0 61 0.00
scripts/ci-validate.sh 95.24 % 31 21 20 1 9.86
scripts/dispatch-workflow.sh 81.82 % 93 66 54 12 9.68
scripts/gitops-dispatch.sh 0.00 % 52 40 0 40 0.00
scripts/gitops-update.sh 61.11 % 119 72 44 28 5.21
scripts/publish-git-pages.sh 71.25 % 117 80 57 23 3.03
scripts/publish.sh 50.00 % 16 10 5 5 0.90
scripts/report-status.sh 84.85 % 47 33 28 5 6.36

gitea-reports/files/retention-cleanup.sh

0.0% lines covered

35 relevant lines. 0 lines covered and 35 lines missed.
    
  1. #!/usr/bin/env bash
  2. # Retention cleanup: read PV directly, no git-pages API.
  3. # Removes old commit-level report dirs based on branch existence + age rules.
  4. set -euo pipefail
  5. DATA_ROOT="${DATA_ROOT:-/app/data}"
  6. CONFIG="${RETENTION_CONFIG:-/etc/retention/retention.json}"
  7. GITEA_API_URL="${GITEA_API_URL:-}"
  8. GITEA_TOKEN="${GITEA_TOKEN:-}"
  9. [ -f "$CONFIG" ] || { echo "ERROR: config missing: $CONFIG" >&2; exit 1; }
  10. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  11. source "$SCRIPT_DIR/retention-lib.sh"
  12. DELETED_COUNT=0
  13. ERROR_COUNT=0
  14. for owner_dir in "$DATA_ROOT"/*/; do
  15. [ -d "$owner_dir" ] || continue
  16. owner=$(basename "$owner_dir")
  17. for repo_dir in "$owner_dir"*/; do
  18. [ -d "$repo_dir" ] || continue
  19. repo=$(basename "$repo_dir")
  20. for branch_dir in "$repo_dir"*/; do
  21. [ -d "$branch_dir" ] || continue
  22. branch=$(basename "$branch_dir")
  23. echo "=== ${owner}/${repo}/${branch} ==="
  24. if ! branch_exists "$owner" "$repo" "$branch"; then
  25. echo " Branch does not exist in Gitea -> DELETE ALL"
  26. rm -rf "$branch_dir"
  27. DELETED_COUNT=$((DELETED_COUNT + 1))
  28. continue
  29. fi
  30. rules=$(jq -r ".branches.\"$branch\" // .branches.default" "$CONFIG")
  31. keep_min=$(echo "$rules" | jq -r '.keepMin // 5')
  32. min_age=$(echo "$rules" | jq -r '.minAgeDays // 7')
  33. commits=$(ls -1t "$branch_dir" 2>/dev/null || true)
  34. count=0
  35. for sha8 in $commits; do
  36. [ -d "$branch_dir/$sha8" ] || continue
  37. count=$((count + 1))
  38. [ "$count" -le "$keep_min" ] && continue
  39. age=$(age_days_from_stat "$branch_dir/$sha8")
  40. [ "$age" -lt "$min_age" ] && continue
  41. echo " DELETE: ${owner}/${repo}/${branch}/${sha8} (age=${age}d, keepMin=${keep_min})"
  42. rm -rf "$branch_dir/$sha8"
  43. DELETED_COUNT=$((DELETED_COUNT + 1))
  44. done
  45. done
  46. done
  47. done
  48. echo ""
  49. echo "=== Summary ==="
  50. echo " Deleted: ${DELETED_COUNT}"
  51. echo " Errors: ${ERROR_COUNT}"

gitea-reports/files/retention-lib.sh

0.0% lines covered

12 relevant lines. 0 lines covered and 12 lines missed.
    
  1. #!/usr/bin/env bash
  2. # Shared functions for retention-cleanup.sh
  3. # Can be sourced by tests for unit testing
  4. age_days_from_stat() {
  5. local dir="$1" epoch_dir now
  6. epoch_dir=$(stat -c %Y "$dir" 2>/dev/null || stat -f %m "$dir" 2>/dev/null || echo 0)
  7. [ "$epoch_dir" -eq 0 ] && echo 99999 && return
  8. now=$(date +%s)
  9. echo $(( (now - epoch_dir) / 86400 ))
  10. }
  11. read_rule() {
  12. local config="$1" branch="$2" key="$3" default="$4"
  13. v=$(jq -r --arg b "$branch" --arg k "$key" '.branches[$b][$k] // empty' "$config")
  14. [ -n "$v" ] && echo "$v" || echo "$default"
  15. }
  16. branch_exists() {
  17. local owner="$1" repo="$2" branch="$3"
  18. local branch_urlenc code
  19. [ -z "$GITEA_API_URL" ] && return 0
  20. [ -z "$GITEA_TOKEN" ] && return 0
  21. branch_urlenc=$(echo "$branch" | sed 's/\//%2F/g')
  22. code=$(curl -s -o /dev/null -w "%{http_code}" \
  23. -H "Authorization: token $GITEA_TOKEN" \
  24. "$GITEA_API_URL/api/v1/repos/$owner/$repo/branches/$branch_urlenc" 2>/dev/null || echo "000")
  25. [ "$code" = "200" ]
  26. }

gitea-reports/files/retention-run.sh

0.0% lines covered

3 relevant lines. 0 lines covered and 3 lines missed.
    
  1. #!/usr/bin/env bash
  2. # Run retention cleanup on PVC directly (no git-pages API).
  3. set -euo pipefail
  4. /scripts/retention-cleanup.sh
  5. echo "Retention job done."

scripts/check-version.sh

100.0% lines covered

39 relevant lines. 39 lines covered and 0 lines missed.
    
  1. #!/usr/bin/env bash
  2. 12 set -e
  3. 12 RAW_VERSION=""
  4. 21 if [ -n "${VERSION_FILE-}" ] && [ -f "${VERSION_FILE-}" ]; then
  5. 36 RAW_VERSION=$(tr -d "$(printf '\xef\xbb\xbf')" < "${VERSION_FILE}" | sed -n 's/^version:[[:space:]]*\([^[:space:]]*\).*/\1/p')
  6. 9 if [ -z "${RAW_VERSION}" ]; then
  7. 12 if echo "${VERSION_FILE}" | grep -q -E '\.json$'; then
  8. 2 RAW_VERSION=$(jq -r '.version' "${VERSION_FILE}")
  9. else
  10. 15 RAW_VERSION=$(cat "${VERSION_FILE}" | tr -d '[:space:]')
  11. fi
  12. fi
  13. fi
  14. 12 if [ -z "${RAW_VERSION}" ]; then
  15. 3 if [ -f VERSION ]; then
  16. 3 RAW_VERSION=$(cat VERSION | tr -d '[:space:]')
  17. 2 elif [ -f package.json ]; then
  18. RAW_VERSION=$(jq -r '.version' package.json)
  19. 2 elif [ -f pom.xml ]; then
  20. RAW_VERSION=$(grep -oP '<version>\K[^<]+' pom.xml | head -1)
  21. 2 elif [ -f Chart.yaml ]; then
  22. 4 RAW_VERSION=$(tr -d "$(printf '\xef\xbb\xbf')" < Chart.yaml | sed -n 's/^version:[[:space:]]*\([^[:space:]]*\).*/\1/p')
  23. else
  24. 1 echo "ERROR: No version source found (VERSION_FILE, VERSION, package.json, pom.xml, Chart.yaml)" >&2
  25. 1 exit 1
  26. fi
  27. fi
  28. 33 BASE_VERSION=$(echo "$RAW_VERSION" | cut -d'.' -f1-2)
  29. 11 echo "gitea-ci-library - Tunnistettu Major.Minor versio: $BASE_VERSION"
  30. 22 TAGS_JSON=$(curl -s -f -H "Authorization: token ${GITEA_TOKEN}" \
  31. 22 "${SERVER_URL}/api/v1/repos/${REPO}/tags")
  32. 33 TAG=$(echo "$TAGS_JSON" | jq -r --arg prefix "${GIT_TAG_PREFIX-}" --arg sha "${SHA}" '
  33. 33 if type == "array" then
  34. 33 .[] | select(.commit.sha == $sha and (.name | startswith($prefix))) | .name
  35. 33 else empty end' | head -1)
  36. 11 mkdir -p /tmp/build-ctx
  37. 11
  38. 11 if [ -n "$TAG" ]; then
  39. 2 echo "ARTIFACT_EXISTS=true" > /tmp/build-ctx/build.env
  40. 2 echo "NEXT_VERSION=$TAG" >> /tmp/build-ctx/build.env
  41. 2 echo "gitea-ci-library - Artefakti löytyi jo tagilla: $TAG."
  42. else
  43. 9 echo "ARTIFACT_EXISTS=false" > /tmp/build-ctx/build.env
  44. 27 HIGHEST_PATCH=$(echo "$TAGS_JSON" | jq -r --arg prefix "${GIT_TAG_PREFIX-}" --arg bv "${GIT_TAG_PREFIX-}${BASE_VERSION}." '
  45. 27 if type == "array" then .[] | .name | select(startswith($bv)) | sub($bv; "") | tonumber else empty end' | sort -rn | head -1)
  46. 18
  47. 18 if [ -z "$HIGHEST_PATCH" ]; then NEXT_PATCH=0; else NEXT_PATCH=$((HIGHEST_PATCH + 1)); fi
  48. 9 FULL_VERSION="${BASE_VERSION}.${NEXT_PATCH}"
  49. 9 echo "NEXT_VERSION=$FULL_VERSION" >> /tmp/build-ctx/build.env
  50. 9 echo "gitea-ci-library - Uusi vapaa versio: $FULL_VERSION"
  51. fi

scripts/ci-report.sh

0.0% lines covered

61 relevant lines. 0 lines covered and 61 lines missed.
    
  1. #!/usr/bin/env sh
  2. set -eu
  3. DESCRIPTION="${1:-}"
  4. CONTEXT="${2:-}"
  5. SUITE="${3:-}"
  6. STATUS="${4:-success}"
  7. [ -n "$DESCRIPTION" ] || { echo "ERROR: description argument required" >&2; exit 1; }
  8. [ -n "$CONTEXT" ] || { echo "ERROR: context argument required" >&2; exit 1; }
  9. [ -n "$SUITE" ] || { echo "ERROR: suite argument required" >&2; exit 1; }
  10. REPORT_DIR="reports/${SUITE}"
  11. if [ ! -d "$REPORT_DIR" ]; then
  12. echo "ERROR: $REPORT_DIR not found" >&2
  13. sh .ci/scripts/report-status.sh failure "$DESCRIPTION" "$CONTEXT"
  14. exit 1
  15. fi
  16. FILE_COUNT=0
  17. SUBDIR_COUNT=0
  18. ENTRIES=""
  19. for f in "$REPORT_DIR"/*; do
  20. [ -f "$f" ] || continue
  21. base=$(basename "$f")
  22. [ "$base" = "index.html" ] && continue
  23. FILE_COUNT=$((FILE_COUNT + 1))
  24. ENTRIES="${ENTRIES}file:${base}
  25. "
  26. done
  27. for d in "$REPORT_DIR"/*/; do
  28. [ -d "$d" ] || continue
  29. base=$(basename "$d")
  30. [ -f "$d/index.html" ] || continue
  31. SUBDIR_COUNT=$((SUBDIR_COUNT + 1))
  32. ENTRIES="${ENTRIES}dir:${base}
  33. "
  34. done
  35. TOTAL=$((FILE_COUNT + SUBDIR_COUNT))
  36. if [ "$TOTAL" -eq 0 ]; then
  37. echo "ERROR: no reportable items in $REPORT_DIR" >&2
  38. sh .ci/scripts/report-status.sh failure "$DESCRIPTION" "$CONTEXT"
  39. exit 1
  40. fi
  41. SHA8=$(echo "${GITHUB_SHA:-xxxxxxxx}" | cut -c1-8)
  42. humanize() {
  43. name="$1"
  44. name=$(echo "$name" | sed -e 's/\.[^.]*$//' -e 's/[-_]/ /g')
  45. first=$(echo "$name" | cut -c1 | tr '[:lower:]' '[:upper:]')
  46. rest=$(echo "$name" | cut -c2-)
  47. echo "${first}${rest}"
  48. }
  49. generate_index() {
  50. {
  51. echo '<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">'
  52. echo "<title>$DESCRIPTION</title>"
  53. echo '<style>body{font-family:sans-serif;margin:2em;max-width:960px}h1{color:#1e293b}ul{list-style:none;padding:0}li{margin:.5em 0;padding:.5em;background:#f8fafc;border-radius:6px}a{color:#2563eb;text-decoration:none}a:hover{text-decoration:underline}</style>'
  54. echo "</head><body><h1>$DESCRIPTION</h1><ul>"
  55. echo "$ENTRIES" | while IFS= read -r entry; do
  56. [ -z "$entry" ] && continue
  57. entry_type=$(echo "$entry" | cut -d: -f1)
  58. entry_name=$(echo "$entry" | cut -d: -f2-)
  59. if [ "$entry_type" = "file" ]; then
  60. echo "<li><a href=\"$entry_name\">$(humanize "$entry_name")</a></li>"
  61. else
  62. cap=$(echo "$entry_name" | sed 's/\(.\).*/\1/' | tr '[:lower:]' '[:upper:]')$(echo "$entry_name" | sed 's/.//')
  63. echo "<li><a href=\"$entry_name/index.html\">${cap}</a></li>"
  64. fi
  65. done
  66. echo '</ul></body></html>'
  67. } > "$REPORT_DIR/index.html"
  68. }
  69. mkdir -p "$SUITE"
  70. if [ "$TOTAL" -eq 1 ]; then
  71. cp -a "$REPORT_DIR/." "$SUITE/"
  72. sh .ci/scripts/publish-git-pages.sh "$SUITE"
  73. first_entry=$(echo "$ENTRIES" | head -1)
  74. first_type=$(echo "$first_entry" | cut -d: -f1)
  75. first_name=$(echo "$first_entry" | cut -d: -f2-)
  76. if [ "$first_type" = "file" ]; then
  77. SINGLE_ENTRY="$first_name"
  78. else
  79. SINGLE_ENTRY="${first_name}/index.html"
  80. fi
  81. URL="${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/${GITHUB_REF_NAME}/${SHA8}/${SUITE}/${SINGLE_ENTRY}"
  82. sh .ci/scripts/report-status.sh "$STATUS" "$DESCRIPTION" "$CONTEXT" "" "$URL"
  83. else
  84. generate_index
  85. cp -a "$REPORT_DIR/." "$SUITE/"
  86. sh .ci/scripts/publish-git-pages.sh "$SUITE"
  87. sh .ci/scripts/report-status.sh "$STATUS" "$DESCRIPTION" "$CONTEXT" "$SUITE"
  88. fi
  89. rm -rf "$SUITE"

scripts/ci-validate.sh

95.24% lines covered

21 relevant lines. 20 lines covered and 1 lines missed.
    
  1. #!/usr/bin/env bash
  2. 7 set -euo pipefail
  3. 7 CONF_FILE="${CI_CONF_FILE:-.gitea/workflows/gitea-env.conf}"
  4. 7 ERRORS=0
  5. 9 [ -f "$CONF_FILE" ] || { echo "ERROR: $CONF_FILE not found — checkout missing?" >&2; exit 1; }
  6. 6 echo "Reading $CONF_FILE..."
  7. 36 while IFS='=' read -r key value || [ -n "$key" ]; do
  8. 27 key=$(echo "$key" | xargs)
  9. 27 value=$(echo "$value" | xargs)
  10. 10 [ -z "$key" ] && continue
  11. 9 [[ "$key" == "#"* ]] && continue
  12. 9 [ -z "$value" ] && echo "ERROR: $key is empty in $CONF_FILE" >&2 && ERRORS=1
  13. 19 if [ -n "$value" ] && [[ "$key" == *"URL"* ]] && [[ "$value" != http://* ]] && [[ "$value" != https://* ]]; then
  14. 1 echo "ERROR: $key should be a URL (http/https), got: $value" >&2
  15. 1 ERRORS=1
  16. fi
  17. done < "$CONF_FILE"
  18. 8 [ -z "${GITEA_TOKEN:-}" ] && echo "ERROR: GITEA_TOKEN secret is not set" >&2 && ERRORS=1
  19. 8 [ -z "${REPORTS_PUBLISH_TOKEN:-}" ] && echo "ERROR: REPORTS_PUBLISH_TOKEN secret is not set" >&2 && ERRORS=1
  20. 6 if [ "$ERRORS" -ne 0 ]; then
  21. 4 echo "FATAL: CI config validation failed" >&2
  22. 4 exit 1
  23. fi
  24. 2 echo "OK: all CI env vars validated"

scripts/dispatch-workflow.sh

81.82% lines covered

66 relevant lines. 54 lines covered and 12 lines missed.
    
  1. #!/usr/bin/env bash
  2. 13 set -euo pipefail
  3. 13 TARGET_REPO="${1:-}"
  4. 13 WORKFLOW_FILE="${2:-}"
  5. 13 REF="${3:-}"
  6. 13 INPUTS_JSON="${4:-}"
  7. 13 GITEA_API_URL="${5:-}"
  8. 13 GITEA_TOKEN="${6:-}"
  9. 13 TIMEOUT_MINUTES="${7:-360}"
  10. 13 POLL_INTERVAL="${DISPATCH_POLL_INTERVAL:-10}"
  11. 15 [ -z "$TARGET_REPO" ] && echo "ERROR: target_repo argument is required" >&2 && exit 1
  12. 14 [ -z "$WORKFLOW_FILE" ] && echo "ERROR: workflow_file argument is required" >&2 && exit 1
  13. 13 [ -z "$REF" ] && echo "ERROR: ref argument is required" >&2 && exit 1
  14. 12 [ -z "$INPUTS_JSON" ] && echo "ERROR: inputs_json argument is required" >&2 && exit 1
  15. 11 [ -z "$GITEA_API_URL" ] && echo "ERROR: gitea_api_url argument is required" >&2 && exit 1
  16. 10 [ -z "$GITEA_TOKEN" ] && echo "ERROR: gitea_token argument is required" >&2 && exit 1
  17. # Generate unique dispatch_id for display_title matching
  18. # Can be overridden via DISPATCH_ID env var (for tests)
  19. 7 DISPATCH_ID="${DISPATCH_ID:-$(xxd -l 4 -p /dev/urandom 2>/dev/null || openssl rand -hex 4 2>/dev/null || od -An -N4 -tx1 /dev/urandom | tr -d ' \n')}"
  20. 21 INPUTS_JSON=$(echo "$INPUTS_JSON" | jq --arg id "$DISPATCH_ID" '. + {dispatch_id: $id}')
  21. 7 DISPATCH_URL="$GITEA_API_URL/api/v1/repos/$TARGET_REPO/actions/workflows/$WORKFLOW_FILE/dispatches"
  22. 14 DISPATCH_BODY=$(jq -nc --arg ref "$REF" --argjson inputs "$INPUTS_JSON" '{ref: $ref, inputs: $inputs}')
  23. DISPATCH_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
  24. --connect-timeout 5 --max-time 10 \
  25. -X POST "$DISPATCH_URL" \
  26. -H "Authorization: token $GITEA_TOKEN" \
  27. -H "Content-Type: application/json" \
  28. 14 -d "$DISPATCH_BODY")
  29. 7 if [ "$DISPATCH_CODE" != "201" ]; then
  30. 1 echo "ERROR: Dispatch failed with HTTP $DISPATCH_CODE" >&2
  31. 1 exit 1
  32. fi
  33. # Poll: find dispatched run by display_title matching
  34. 6 RUN_ID=""
  35. 12 TIMEOUT_SECONDS=$(awk "BEGIN {printf \"%.3f\", $TIMEOUT_MINUTES * 60}")
  36. 12 START_TIME=$(date +%s)
  37. 19 while [ -z "$RUN_ID" ]; do
  38. 30 NOW=$(date +%s)
  39. 15 ELAPSED=$((NOW - START_TIME))
  40. 15 if awk -v e="$ELAPSED" -v t="$TIMEOUT_SECONDS" 'BEGIN { exit !(e >= t) }'; then
  41. 2 echo "ERROR: Timeout after ${TIMEOUT_MINUTES} minutes — run not found" >&2
  42. 2 exit 124
  43. fi
  44. RUNS_RESP=$(curl -s --connect-timeout 5 --max-time 10 \
  45. "$GITEA_API_URL/api/v1/repos/$TARGET_REPO/actions/runs?event=workflow_dispatch&limit=10" \
  46. 26 -H "Authorization: token $GITEA_TOKEN")
  47. 39 RUN_ID=$(echo "$RUNS_RESP" | jq -r --arg id "$DISPATCH_ID" \
  48. 39 '[.workflow_runs[] | select(.display_title | contains($id))] | .[0].id // empty')
  49. 22 [ -z "$RUN_ID" ] && sleep "$POLL_INTERVAL"
  50. done
  51. # Poll: wait for run to complete
  52. 8 while true; do
  53. 16 NOW=$(date +%s)
  54. 8 ELAPSED=$((NOW - START_TIME))
  55. 8 if awk -v e="$ELAPSED" -v t="$TIMEOUT_SECONDS" 'BEGIN { exit !(e >= t) }'; then
  56. echo "ERROR: Timeout after ${TIMEOUT_MINUTES} minutes" >&2
  57. exit 124
  58. fi
  59. 8 RUN_URL="$GITEA_API_URL/api/v1/repos/$TARGET_REPO/actions/runs/$RUN_ID"
  60. RUN_RESP=$(curl -s --connect-timeout 5 --max-time 10 \
  61. 16 -H "Authorization: token $GITEA_TOKEN" "$RUN_URL")
  62. 24 STATUS=$(echo "$RUN_RESP" | jq -r '.status // "running"')
  63. 8 if [ "$STATUS" = "completed" ]; then
  64. 12 CONCLUSION=$(echo "$RUN_RESP" | jq -r '.conclusion // "failure"')
  65. 4 if [ "$CONCLUSION" = "success" ]; then
  66. 2 GITOPS_COMMIT=""
  67. BRANCH_RESP=$(curl -s --connect-timeout 5 --max-time 10 \
  68. "$GITEA_API_URL/api/v1/repos/$TARGET_REPO/branches/$REF" \
  69. 4 -H "Authorization: token $GITEA_TOKEN") || true
  70. 6 GITOPS_COMMIT=$(echo "$BRANCH_RESP" | jq -r '.commit.id // empty')
  71. 2 echo "GITOPS_COMMIT=$GITOPS_COMMIT"
  72. 2 exit 0
  73. fi
  74. 2 echo "ERROR: Workflow completed with conclusion: $CONCLUSION" >&2
  75. 2 exit 1
  76. fi
  77. 4 sleep "$POLL_INTERVAL"
  78. done

scripts/gitops-dispatch.sh

0.0% lines covered

40 relevant lines. 0 lines covered and 40 lines missed.
    
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. echo "gitops-dispatch: validating env vars..."
  4. : "${GITOPS_FILE:?}"
  5. : "${GITOPS_YQ_TPL:?}"
  6. : "${GITOPS_VERSION:?}"
  7. : "${GITOPS_SOURCE_REPO:?}"
  8. : "${GITOPS_SOURCE_COMMIT:?}"
  9. : "${GITOPS_REPO:?}"
  10. : "${GITOPS_WORKFLOW:?}"
  11. : "${GITEA_API_URL:?}"
  12. : "${GITEA_TOKEN:?}"
  13. TIMEOUT="${GITOPS_DISPATCH_TIMEOUT:-30}"
  14. echo "gitops-dispatch: constructing inputs..."
  15. INPUTS=$(jq -nc \
  16. --arg file "$GITOPS_FILE" \
  17. --arg yq_tpl "$GITOPS_YQ_TPL" \
  18. --arg version "$GITOPS_VERSION" \
  19. --arg source_repo "$GITOPS_SOURCE_REPO" \
  20. --arg source_commit "$GITOPS_SOURCE_COMMIT" \
  21. --arg git_tag_prefix "${GITOPS_TAG_PREFIX:-}" \
  22. --arg extra_cmd "${GITOPS_EXTRA_CMD:-}" \
  23. --arg author_name "${GIT_USER_NAME:-}" \
  24. --arg author_email "${GIT_USER_EMAIL:-}" \
  25. '{file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit, git_tag_prefix: $git_tag_prefix, extra_cmd: $extra_cmd, author_name: $author_name, author_email: $author_email}')
  26. DIR="$(cd "$(dirname "$0")" && pwd)"
  27. echo "gitops-dispatch: dispatching to $GITOPS_REPO/$GITOPS_WORKFLOW..."
  28. set +e
  29. OUTPUT=$(bash "$DIR/dispatch-workflow.sh" \
  30. "$GITOPS_REPO" "$GITOPS_WORKFLOW" "main" \
  31. "$INPUTS" "$GITEA_API_URL" "$GITEA_TOKEN" "$TIMEOUT" 2>&1)
  32. EXIT=$?
  33. set -e
  34. echo "=== DISPATCH OUTPUT (exit=$EXIT) ==="
  35. echo "$OUTPUT"
  36. echo "=== END DISPATCH ==="
  37. STATUS="failure"
  38. GITOPS_SHA=""
  39. if [ "$EXIT" = "0" ]; then
  40. STATUS="success"
  41. GITOPS_SHA=$(echo "$OUTPUT" | grep '^GITOPS_COMMIT=' | cut -d= -f2)
  42. fi
  43. COMPONENT="${GITOPS_TAG_PREFIX:-${GITOPS_FILE}}"
  44. echo "GITOPS_SUMMARY=${COMPONENT}|${GITOPS_VERSION}|${STATUS}|${GITOPS_SHA}|${GITOPS_REPO}"
  45. exit "$EXIT"

scripts/gitops-update.sh

61.11% lines covered

72 relevant lines. 44 lines covered and 28 lines missed.
    
  1. #!/usr/bin/env bash
  2. 14 set -euo pipefail
  3. 56 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  4. _gitops_fail() {
  5. 8 local MSG="${1:-GitOps update failed}"
  6. 8 echo "[ERROR] ${MSG}" >&2
  7. 15 if [ -n "${GITOPS_REPO:-}" ] && [ -n "${GITOPS_SHA:-}" ] && \
  8. [ -n "${SOURCE_REPO:-}" ] && [ -n "${SOURCE_COMMIT:-}" ] && \
  9. [ -n "${GITEA_API_URL:-}" ] && [ -n "${GITEA_TOKEN:-}" ]; then
  10. local env repo context
  11. env=$(dirname "${INPUT_FILE}")
  12. repo=$(basename "${SOURCE_REPO}")
  13. context="${repo} ${GITHUB_RUN_ID:-unknown}"
  14. [ -n "${GIT_TAG_PREFIX:-}" ] && context="${repo}/${GIT_TAG_PREFIX} ${GITHUB_RUN_ID:-unknown}"
  15. local SOURCE_URL="${GITEA_API_URL}/${SOURCE_REPO}/commit/${SOURCE_COMMIT}"
  16. ROOT_REPO="${GITOPS_REPO}" ROOT_COMMIT="${GITOPS_SHA}" \
  17. GITEA_API_URL="${GITEA_API_URL}" GITEA_TOKEN="${GITEA_TOKEN}" \
  18. bash "${SCRIPT_DIR}/report-status.sh" failure "Install to ${env} ${VERSION}" \
  19. "${context}" "" "${SOURCE_URL}" 2>/dev/null || true
  20. fi
  21. 8 exit 1
  22. }
  23. _gitops_validate() {
  24. 15 [ -n "${INPUT_FILE:-}" ] || _gitops_fail "INPUT_FILE is required"
  25. 14 [ -n "${YQ_TPL:-}" ] || _gitops_fail "YQ_TPL is required"
  26. 13 [ -n "${VERSION:-}" ] || _gitops_fail "VERSION is required"
  27. 12 [ -n "${SOURCE_REPO:-}" ] || _gitops_fail "SOURCE_REPO is required"
  28. 11 [ -n "${SOURCE_COMMIT:-}" ] || _gitops_fail "SOURCE_COMMIT is required"
  29. 10 [ -n "${GITOPS_REPO:-}" ] || _gitops_fail "GITOPS_REPO is required"
  30. 9 [ -n "${GITEA_TOKEN:-}" ] || _gitops_fail "GITEA_TOKEN is required"
  31. 8 [ -n "${GITEA_API_URL:-}" ] || _gitops_fail "GITEA_API_URL is required"
  32. }
  33. _gitops_success() {
  34. 2 local env repo context
  35. 4 env=$(dirname "${INPUT_FILE}")
  36. 4 repo=$(basename "${SOURCE_REPO}")
  37. 2 context="${repo} ${GITHUB_RUN_ID:-unknown}"
  38. 2 [ -n "${GIT_TAG_PREFIX:-}" ] && context="${repo}/${GIT_TAG_PREFIX} ${GITHUB_RUN_ID:-unknown}"
  39. 2 local SOURCE_URL="${GITEA_API_URL}/${SOURCE_REPO}/commit/${SOURCE_COMMIT}"
  40. 10 ROOT_REPO="${GITOPS_REPO}" ROOT_COMMIT="${GITOPS_SHA}" \
  41. 10 GITEA_API_URL="${GITEA_API_URL}" GITEA_TOKEN="${GITEA_TOKEN}" \
  42. 10 bash "${SCRIPT_DIR}/report-status.sh" success \
  43. 10 "Install to ${env} ${VERSION}" \
  44. 10 "${context}" "" "${SOURCE_URL}"
  45. }
  46. _gitops_nochange() {
  47. local env repo context
  48. env=$(dirname "${INPUT_FILE}")
  49. repo=$(basename "${SOURCE_REPO}")
  50. context="${repo} ${GITHUB_RUN_ID:-unknown}"
  51. [ -n "${GIT_TAG_PREFIX:-}" ] && context="${repo}/${GIT_TAG_PREFIX} ${GITHUB_RUN_ID:-unknown}"
  52. local SOURCE_URL="${GITEA_API_URL}/${SOURCE_REPO}/commit/${SOURCE_COMMIT}"
  53. ROOT_REPO="${GITOPS_REPO}" ROOT_COMMIT="${GITOPS_SHA}" \
  54. GITEA_API_URL="${GITEA_API_URL}" GITEA_TOKEN="${GITEA_TOKEN}" \
  55. bash "${SCRIPT_DIR}/report-status.sh" success \
  56. "Install to ${env} ${VERSION} — no change" \
  57. "${context}" "" "${SOURCE_URL}"
  58. }
  59. _gitops_substitute() {
  60. 16 echo "$1" | sed "s/{{VERSION}}/$2/g"
  61. }
  62. _gitops_update() {
  63. 4 local CLONE_DIR="${GITOPS_TARGET_DIR:-$(mktemp -d)}"
  64. 2 if [ -n "${GITOPS_CLONE_URL:-}" ]; then
  65. git clone "${GITOPS_CLONE_URL}" "${CLONE_DIR}" || _gitops_fail "Failed to clone GitOps repo"
  66. else
  67. 2 git clone "${CLONE_URL}" "${CLONE_DIR}" || _gitops_fail "Failed to clone GitOps repo"
  68. fi
  69. 2 cd "${CLONE_DIR}" || _gitops_fail "Failed to enter clone directory"
  70. 2 yq eval -i "${YQ_EXPR}" "${INPUT_FILE}" || _gitops_fail "Failed to update ${INPUT_FILE}"
  71. 2 if [ -n "${GITOPS_EXTRA_CMD:-}" ]; then
  72. eval "${GITOPS_EXTRA_CMD}" || _gitops_fail "Extra command failed: ${GITOPS_EXTRA_CMD}"
  73. git add -A || _gitops_fail "Failed to stage all changes"
  74. else
  75. 2 git add "${INPUT_FILE}" || _gitops_fail "Failed to stage ${INPUT_FILE}"
  76. fi
  77. 2 if git diff --cached --quiet; then
  78. echo "No changes — ${INPUT_FILE} already at ${VERSION}"
  79. GITOPS_SHA="$(git rev-parse HEAD)"
  80. _gitops_nochange
  81. exit 0
  82. fi
  83. 2 git -c user.name="${GIT_USER_NAME:-gitea-ci-bot}" \
  84. -c user.email="${GIT_USER_EMAIL:-ci@keskikuja.site}" \
  85. commit -m "[skip ci] gitops: update version to ${VERSION}" || _gitops_fail "Failed to commit"
  86. 4 GITOPS_SHA="$(git rev-parse HEAD)"
  87. 2 git push || _gitops_fail "Failed to push"
  88. 2 _gitops_success
  89. }
  90. 14 _gitops_validate
  91. 12 YQ_EXPR=$(_gitops_substitute "${YQ_TPL}" "${VERSION}")
  92. 24 GITEA_HOST=$(echo "${GITEA_API_URL}" | sed 's|https://||' | sed 's|http://||')
  93. 6 CLONE_URL="${GITOPS_CLONE_URL:-https://${GITEA_TOKEN}@${GITEA_HOST}/${GITOPS_REPO}.git}"
  94. 6 if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
  95. 2 _gitops_update
  96. fi

scripts/publish-git-pages.sh

71.25% lines covered

80 relevant lines. 57 lines covered and 23 lines missed.
    
  1. 3 #!/usr/bin/env sh
  2. 10 set -eu
  3. 10 SUITE_PATH="${1:-}"
  4. 12 [ -n "$SUITE_PATH" ] || { echo "ERROR: suite_path argument required" >&2; exit 1; }
  5. 11 [ -n "${GIT_PAGES_URL:-}" ] || { echo "ERROR: GIT_PAGES_URL is not set" >&2; exit 1; }
  6. 10 [ -n "${REPORTS_PUBLISH_TOKEN:-}" ] || { echo "ERROR: REPORTS_PUBLISH_TOKEN is not set" >&2; exit 1; }
  7. 9 [ -n "${GITHUB_REPOSITORY:-}" ] || { echo "ERROR: GITHUB_REPOSITORY is not set" >&2; exit 1; }
  8. 6 [ -n "${GITHUB_SHA:-}" ] || { echo "ERROR: GITHUB_SHA is not set" >&2; exit 1; }
  9. 8 [ -n "${GITHUB_REF_NAME:-}" ] || { echo "ERROR: GITHUB_REF_NAME is not set" >&2; exit 1; }
  10. 5 OWNER="${GITHUB_REPOSITORY%%/*}"
  11. 5 REPO="${GITHUB_REPOSITORY##*/}"
  12. 15 SHA8=$(echo "$GITHUB_SHA" | cut -c1-8)
  13. 5 BRANCH="${GITHUB_REF_NAME}"
  14. 5 SUITE="${SUITE_PATH%/}"
  15. 5 PAGES_USER="${GIT_PAGES_PUBLISH_USER:-publish}"
  16. 7 [ -d "$SUITE" ] || { echo "ERROR: not a directory: $SUITE" >&2; exit 1; }
  17. 4 EMPTY=1
  18. 5 for _f in "$SUITE"/* "$SUITE"/.*; do
  19. 11 [ -e "$_f" ] && { EMPTY=0; break; }
  20. done
  21. 6 [ "$EMPTY" -eq 0 ] || { echo "ERROR: no files to publish in $SUITE" >&2; exit 1; }
  22. 6 WORK=$(mktemp -d)
  23. 6 TAR=$(mktemp)
  24. 3 trap 'rm -rf "$WORK" "$TAR"' EXIT
  25. # Kopioi raporttitiedostot
  26. 3 mkdir -p "$WORK/$SUITE"
  27. 3 cp -a "$SUITE/." "$WORK/$SUITE/"
  28. # Generoi index.html (sama logiikka kuin nykyään)
  29. 3 cd "$WORK/$SUITE"
  30. 3 if [ ! -f "index.html" ]; then
  31. 1 ITEM_LIST=""
  32. 1 ITEM_COUNT=0
  33. 1 for f in *; do
  34. 1 [ -f "$f" ] || continue
  35. 1 [ "$f" = "index.html" ] && continue
  36. 2 ITEM_LIST="${ITEM_LIST}file:${f}
  37. 1 "
  38. 1 ITEM_COUNT=$((ITEM_COUNT + 1))
  39. 2 done
  40. 2
  41. 1 for d in */; do
  42. 2 [ -d "$d" ] || continue
  43. d="${d%/}"
  44. [ -f "$d/index.html" ] || continue
  45. 1 ITEM_LIST="${ITEM_LIST}dir:${d}
  46. 1 "
  47. 1 ITEM_COUNT=$((ITEM_COUNT + 1))
  48. 1 done
  49. 1
  50. 1 if [ "$ITEM_COUNT" -gt 1 ]; then
  51. {
  52. echo '<!DOCTYPE html><html lang="en"><head><meta charset="utf-8">'
  53. echo "<title>Test report ${SHA8}</title>"
  54. echo '<style>body{font-family:sans-serif;margin:2em;max-width:960px}'
  55. echo 'h1{color:#1e293b}ul{list-style:none;padding:0}'
  56. echo 'li{margin:.5em 0;padding:.5em;background:#f8fafc;border-radius:6px}'
  57. echo 'a{color:#2563eb;text-decoration:none}a:hover{text-decoration:underline}'
  58. echo '</style></head><body>'
  59. echo "<h1>Test report <code>${SHA8}</code></h1><ul>"
  60. echo "$ITEM_LIST" | while IFS= read -r item; do
  61. [ -z "$item" ] && continue
  62. item_type=$(echo "$item" | cut -d: -f1)
  63. item_name=$(echo "$item" | cut -d: -f2-)
  64. label=$(echo "$item_name" | sed -e 's/\.[^.]*$//' -e 's/[-_]/ /g')
  65. first=$(echo "$label" | cut -c1 | tr '[:lower:]' '[:upper:]')
  66. rest=$(echo "$label" | cut -c2-)
  67. if [ "$item_type" = "file" ]; then
  68. echo "<li><a href=\"$item_name\">${first}${rest}</a></li>"
  69. else
  70. echo "<li><a href=\"$item_name/index.html\">${first}${rest}</a></li>"
  71. fi
  72. done
  73. echo '</ul></body></html>'
  74. } > "index.html"
  75. fi
  76. fi
  77. # .meta tiedosto retentionia varten
  78. 6 cat > ".meta" <<EOF
  79. 6 {"branch":"${BRANCH}","sha":"${GITHUB_SHA}","published_at":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"}
  80. 6 EOF
  81. 3 cd "$WORK"
  82. # Pakkaa: pelkät tiedostot ilman $SUITE-etuliitettä
  83. 3 tar czf "$TAR" -C "$WORK/$SUITE" .
  84. # PUT upload-sidecariin
  85. 3 PUBLISH_URL="${GIT_PAGES_URL}/${OWNER}/${REPO}/${BRANCH}/${SHA8}/${SUITE}/"
  86. HTTP_CODE=$(curl -sS -X PUT "$PUBLISH_URL" \
  87. -u "${PAGES_USER}:${REPORTS_PUBLISH_TOKEN}" \
  88. -H "Content-Type: application/tar+gz" \
  89. --data-binary @"$TAR" \
  90. -o /tmp/git-pages-publish-response.txt \
  91. 6 -w "%{http_code}")
  92. 3 case "$HTTP_CODE" in
  93. 200|201|204) ;;
  94. *)
  95. 1 echo "ERROR: publish HTTP ${HTTP_CODE}" >&2
  96. 1 cat /tmp/git-pages-publish-response.txt >&2
  97. 1 exit 1
  98. ;;
  99. esac
  100. 2 echo "${PUBLISH_URL}"

scripts/publish.sh

50.0% lines covered

10 relevant lines. 5 lines covered and 5 lines missed.
    
  1. #!/usr/bin/env bash
  2. 1 set -euo pipefail
  3. 1 SUITE_PATH="${1:-}"
  4. 1 [ -n "$SUITE_PATH" ] || { echo "ERROR: suite_path argument required" >&2; exit 1; }
  5. 3 [ -n "${GITEA_API_URL:-}" ] || { echo "ERROR: GITEA_API_URL is not set" >&2; exit 1; }
  6. 3 [ -n "${GITEA_TOKEN:-}" ] || { echo "ERROR: GITEA_TOKEN is not set" >&2; exit 1; }
  7. [ -n "${GIT_PAGES_URL:-}" ] || { echo "ERROR: GIT_PAGES_URL is not set" >&2; exit 1; }
  8. [ -n "${REPORTS_PUBLISH_TOKEN:-}" ] || { echo "ERROR: REPORTS_PUBLISH_TOKEN is not set" >&2; exit 1; }
  9. SCRIPT_DIR="$(dirname "$0")"
  10. REPORT_URL=$(bash "$SCRIPT_DIR/publish-git-pages.sh" "$SUITE_PATH")
  11. echo "Published: $REPORT_URL"
  12. bash "$SCRIPT_DIR/report-status.sh" success "Reports published" "ci-report"

scripts/report-status.sh

84.85% lines covered

33 relevant lines. 28 lines covered and 5 lines missed.
    
  1. #!/usr/bin/env sh
  2. 5 set -eu
  3. 5 STATE="${1:-}"
  4. 5 DESCRIPTION="${2:-}"
  5. 31 SHA8=$(echo "${GITHUB_SHA:-}" | cut -c1-8)
  6. 11 KEY="${3:-commit-${SHA8}}"
  7. 11 SUITE="${4:-}"
  8. 11 CUSTOM_URL="${5:-}"
  9. 13 [ -z "$STATE" ] && echo "ERROR: state argument is required" >&2 && exit 1
  10. 12 [ -z "$DESCRIPTION" ] && echo "ERROR: description argument is required" >&2 && exit 1
  11. 11 [ -z "${GITEA_API_URL:-}" ] && echo "ERROR: GITEA_API_URL is not set" >&2 && exit 1
  12. 10 [ -z "${GITEA_TOKEN:-}" ] && echo "ERROR: GITEA_TOKEN is not set" >&2 && exit 1
  13. 7 if [ -n "$CUSTOM_URL" ]; then
  14. 2 URL="$CUSTOM_URL"
  15. 5 elif [ -n "$SUITE" ]; then
  16. 1 SUITE="${SUITE%/}/"
  17. 3 SHA8_CUT=$(echo "$GITHUB_SHA" | cut -c1-8)
  18. 1 URL="${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/${GITHUB_REF_NAME}/${SHA8_CUT}/${SUITE}"
  19. else
  20. 4 URL="${GITEA_API_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
  21. fi
  22. 7 REPO="${ROOT_REPO:-${GITHUB_REPOSITORY:-}}"
  23. 7 COMMIT="${ROOT_COMMIT:-${GITHUB_SHA:-}}"
  24. 7 [ -z "$REPO" ] && echo "ERROR: GITHUB_REPOSITORY is not set" >&2 && exit 1
  25. 7 [ -z "$COMMIT" ] && echo "ERROR: GITHUB_SHA is not set" >&2 && exit 1
  26. HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
  27. -X POST "$GITEA_API_URL/api/v1/repos/$REPO/statuses/$COMMIT" \
  28. -H "Authorization: token $GITEA_TOKEN" \
  29. -H "Content-Type: application/json" \
  30. 15 -d "{\"state\":\"$STATE\",\"target_url\":\"$URL\",\"description\":\"$DESCRIPTION\",\"context\":\"$KEY\"}" || true)
  31. 8 if [ "$HTTP_CODE" = "201" ]; then
  32. 7 exit 0
  33. fi
  34. 2 if [ -z "$HTTP_CODE" ] || [ "$HTTP_CODE" = "000" ]; then
  35. echo "gitea-ci-library - ERROR: Failed to connect to Gitea API at $GITEA_API_URL" >&2
  36. else
  37. 1 echo "gitea-ci-library - ERROR: gitea-ci-library, API returned HTTP $HTTP_CODE" >&2
  38. fi
  39. 1 exit 1