loading
Generated 2026-06-22T08:17:18+00:00

All Files ( 61.0% covered at 5.58 hits/line )

9 files in total.
418 relevant lines, 255 lines covered and 163 lines missed. ( 61.0% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line
scripts/check-version.sh 100.00 % 60 39 39 0 13.69
scripts/ci-report.sh 0.00 % 110 62 0 62 0.00
scripts/ci-validate.sh 95.24 % 31 21 20 1 9.86
scripts/dispatch-workflow.sh 81.82 % 93 66 54 12 10.59
scripts/gitops-dispatch.sh 0.00 % 47 36 0 36 0.00
scripts/gitops-update.sh 62.32 % 114 69 43 26 5.39
scripts/publish-git-pages.sh 78.05 % 117 82 64 18 2.88
scripts/publish.sh 70.00 % 16 10 7 3 3.50
scripts/report-status.sh 84.85 % 47 33 28 5 7.61

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

62 relevant lines. 0 lines covered and 62 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. STAGED="reports/${SHA8}/${SUITE}"
  70. mkdir -p "$STAGED"
  71. if [ "$TOTAL" -eq 1 ]; then
  72. cp -a "$REPORT_DIR/." "$STAGED/"
  73. sh .ci/scripts/publish-git-pages.sh "$SUITE"
  74. first_entry=$(echo "$ENTRIES" | head -1)
  75. first_type=$(echo "$first_entry" | cut -d: -f1)
  76. first_name=$(echo "$first_entry" | cut -d: -f2-)
  77. if [ "$first_type" = "file" ]; then
  78. SINGLE_ENTRY="$first_name"
  79. else
  80. SINGLE_ENTRY="${first_name}/index.html"
  81. fi
  82. URL="${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/reports/${SHA8}/${SUITE}/${SINGLE_ENTRY}"
  83. sh .ci/scripts/report-status.sh "$STATUS" "$DESCRIPTION" "$CONTEXT" "" "$URL"
  84. else
  85. generate_index
  86. cp -a "$REPORT_DIR/." "$STAGED/"
  87. sh .ci/scripts/publish-git-pages.sh "$SUITE"
  88. sh .ci/scripts/report-status.sh "$STATUS" "$DESCRIPTION" "$CONTEXT" "$SUITE"
  89. fi
  90. rm -rf "$STAGED"

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 "${GIT_PAGES_PUBLISH_TOKEN:-}" ] && echo "ERROR: GIT_PAGES_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. 23 while [ -z "$RUN_ID" ]; do
  38. 38 NOW=$(date +%s)
  39. 19 ELAPSED=$((NOW - START_TIME))
  40. 19 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. 34 -H "Authorization: token $GITEA_TOKEN")
  47. 51 RUN_ID=$(echo "$RUNS_RESP" | jq -r --arg id "$DISPATCH_ID" \
  48. 51 '[.workflow_runs[] | select(.display_title | contains($id))] | .[0].id // empty')
  49. 30 [ -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

36 relevant lines. 0 lines covered and 36 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. echo "gitops-dispatch: constructing inputs..."
  14. INPUTS=$(jq -nc \
  15. --arg file "$GITOPS_FILE" \
  16. --arg yq_tpl "$GITOPS_YQ_TPL" \
  17. --arg version "$GITOPS_VERSION" \
  18. --arg source_repo "$GITOPS_SOURCE_REPO" \
  19. --arg source_commit "$GITOPS_SOURCE_COMMIT" \
  20. --arg git_tag_prefix "${GITOPS_TAG_PREFIX:-}" \
  21. '{file: $file, yq_tpl: $yq_tpl, version: $version, source_repo: $source_repo, source_commit: $source_commit, git_tag_prefix: $git_tag_prefix}')
  22. DIR="$(cd "$(dirname "$0")" && pwd)"
  23. echo "gitops-dispatch: dispatching to $GITOPS_REPO/$GITOPS_WORKFLOW..."
  24. set +e
  25. OUTPUT=$(bash "$DIR/dispatch-workflow.sh" \
  26. "$GITOPS_REPO" "$GITOPS_WORKFLOW" "main" \
  27. "$INPUTS" "$GITEA_API_URL" "$GITEA_TOKEN" "$TIMEOUT" 2>&1)
  28. EXIT=$?
  29. set -e
  30. echo "=== DISPATCH OUTPUT (exit=$EXIT) ==="
  31. echo "$OUTPUT"
  32. echo "=== END DISPATCH ==="
  33. STATUS="failure"
  34. GITOPS_SHA=""
  35. if [ "$EXIT" = "0" ]; then
  36. STATUS="success"
  37. GITOPS_SHA=$(echo "$OUTPUT" | grep '^GITOPS_COMMIT=' | cut -d= -f2)
  38. fi
  39. COMPONENT="${GITOPS_TAG_PREFIX:-${GITOPS_FILE}}"
  40. echo "GITOPS_SUMMARY=${COMPONENT}|${GITOPS_VERSION}|${STATUS}|${GITOPS_SHA}|${GITOPS_REPO}"
  41. exit "$EXIT"

scripts/gitops-update.sh

62.32% lines covered

69 relevant lines. 43 lines covered and 26 lines missed.
    
  1. #!/usr/bin/env bash
  2. 13 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 git add "${INPUT_FILE}" || _gitops_fail "Failed to stage ${INPUT_FILE}"
  72. 2 if git diff --cached --quiet; then
  73. echo "No changes — ${INPUT_FILE} already at ${VERSION}"
  74. GITOPS_SHA="$(git rev-parse HEAD)"
  75. _gitops_nochange
  76. exit 0
  77. fi
  78. 2 git -c user.name="gitea-ci-bot" \
  79. -c user.email="ci@keskikuja.site" \
  80. commit -m "[skip ci] gitops: update version to ${VERSION}" || _gitops_fail "Failed to commit"
  81. 4 GITOPS_SHA="$(git rev-parse HEAD)"
  82. 2 git push || _gitops_fail "Failed to push"
  83. 2 _gitops_success
  84. }
  85. 14 _gitops_validate
  86. 12 YQ_EXPR=$(_gitops_substitute "${YQ_TPL}" "${VERSION}")
  87. 24 GITEA_HOST=$(echo "${GITEA_API_URL}" | sed 's|https://||' | sed 's|http://||')
  88. 6 CLONE_URL="${GITOPS_CLONE_URL:-https://${GITEA_TOKEN}@${GITEA_HOST}/${GITOPS_REPO}.git}"
  89. 6 if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
  90. 2 _gitops_update
  91. fi

scripts/publish-git-pages.sh

78.05% lines covered

82 relevant lines. 64 lines covered and 18 lines missed.
    
  1. 3 #!/usr/bin/env sh
  2. 9 set -eu
  3. 9 SUITE_PATH="${1:-}"
  4. 11 [ -n "$SUITE_PATH" ] || { echo "ERROR: suite_path argument required" >&2; exit 1; }
  5. 10 [ -n "${GITEA_API_URL:-}" ] || { echo "ERROR: GITEA_API_URL is not set" >&2; exit 1; }
  6. 9 [ -n "${GIT_PAGES_URL:-}" ] || { echo "ERROR: GIT_PAGES_URL is not set" >&2; exit 1; }
  7. 8 [ -n "${GIT_PAGES_PUBLISH_TOKEN:-}" ] || { echo "ERROR: GIT_PAGES_PUBLISH_TOKEN is not set" >&2; exit 1; }
  8. 7 [ -n "${GITHUB_REPOSITORY:-}" ] || { echo "ERROR: GITHUB_REPOSITORY is not set" >&2; exit 1; }
  9. 4 [ -n "${GITHUB_SHA:-}" ] || { echo "ERROR: GITHUB_SHA is not set" >&2; exit 1; }
  10. 4 OWNER="${GITHUB_REPOSITORY%%/*}"
  11. 4 REPO="${GITHUB_REPOSITORY##*/}"
  12. 12 SHA8=$(echo "$GITHUB_SHA" | cut -c1-8)
  13. 4 PAGES_USER="${GIT_PAGES_PUBLISH_USER:-publish}"
  14. 4 REPORT_DIR="reports/${SHA8}/${SUITE_PATH%/}"
  15. 4 REPORT_BASE="${GIT_PAGES_URL}/${OWNER}/${REPO}/reports/${SHA8}"
  16. 6 [ -d "$REPORT_DIR" ] || { echo "ERROR: not a directory: $REPORT_DIR" >&2; exit 1; }
  17. 3 PUBLISH_SITE_URL="${GIT_PAGES_URL}/"
  18. 6 WORK=$(mktemp -d)
  19. 6 TAR=$(mktemp)
  20. 3 trap 'rm -rf "$WORK" "$TAR"' EXIT
  21. 3 RELPATH="${REPORT_DIR#reports/${SHA8}/}"
  22. 6 if [ "$RELPATH" != "$REPORT_DIR" ] && [ -n "$RELPATH" ]; then
  23. 3 TARGET="$WORK/${OWNER}/${REPO}/reports/${SHA8}/${RELPATH}"
  24. else
  25. TARGET="$WORK/${OWNER}/${REPO}/reports/${SHA8}"
  26. fi
  27. 3 mkdir -p "$TARGET"
  28. 3 cp -a "$REPORT_DIR/." "$TARGET/"
  29. 3 if [ ! -f "$TARGET/index.html" ]; then
  30. 1 ITEM_LIST=""
  31. 1 ITEM_COUNT=0
  32. 1 for f in "$TARGET"/*; do
  33. 1 [ -f "$f" ] || continue
  34. 2 base=$(basename "$f")
  35. 1 [ "$base" = "index.html" ] && continue
  36. 1 ITEM_LIST="${ITEM_LIST}file:${base}
  37. 1 "
  38. 1 ITEM_COUNT=$((ITEM_COUNT + 1))
  39. 1 done
  40. 1
  41. 1 for d in "$TARGET"/*/; do
  42. 2 [ -d "$d" ] || continue
  43. base=$(basename "$d")
  44. [ -f "$d/index.html" ] || continue
  45. 1 ITEM_LIST="${ITEM_LIST}dir:${base}
  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. } > "$TARGET/index.html"
  75. fi
  76. fi
  77. 6 cat > "$TARGET/.meta" <<EOF
  78. 6 {"branch":"${GITHUB_REF_NAME:-}","sha":"${GITHUB_SHA}","published_at":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"}
  79. 6 EOF
  80. 9 find "$WORK/$OWNER" \( -type f -o -type l \) -print | sed "s|^${WORK}/||" | tar -cf "$TAR" -C "$WORK" -T -
  81. publish() {
  82. 3 method="$1"
  83. 3 curl -sS -X "$method" "$PUBLISH_SITE_URL" \
  84. 3 -u "${PAGES_USER}:${GIT_PAGES_PUBLISH_TOKEN}" \
  85. 3 -H "Content-Type: application/x-tar" \
  86. 3 -H "Atomic: no" \
  87. 3 -H "Create-Parents: yes" \
  88. 3 --data-binary @"$TAR" \
  89. 3 -o /tmp/git-pages-publish-response.txt \
  90. 3 -w "%{http_code}"
  91. }
  92. 6 HTTP_CODE=$(publish PATCH)
  93. 3 case "$HTTP_CODE" in
  94. 200|201|204) ;;
  95. *)
  96. 1 echo "ERROR: git-pages publish HTTP ${HTTP_CODE}" >&2
  97. 1 cat /tmp/git-pages-publish-response.txt >&2
  98. 1 exit 1
  99. ;;
  100. esac
  101. 2 echo "$REPORT_BASE"

scripts/publish.sh

70.0% lines covered

10 relevant lines. 7 lines covered and 3 lines missed.
    
  1. #!/usr/bin/env bash
  2. 5 set -euo pipefail
  3. 5 SUITE_PATH="${1:-}"
  4. 7 [ -n "$SUITE_PATH" ] || { echo "ERROR: suite_path argument required" >&2; exit 1; }
  5. 6 [ -n "${GITEA_API_URL:-}" ] || { echo "ERROR: GITEA_API_URL is not set" >&2; exit 1; }
  6. 5 [ -n "${GITEA_TOKEN:-}" ] || { echo "ERROR: GITEA_TOKEN is not set" >&2; exit 1; }
  7. 4 [ -n "${GIT_PAGES_URL:-}" ] || { echo "ERROR: GIT_PAGES_URL is not set" >&2; exit 1; }
  8. 3 [ -n "${GIT_PAGES_PUBLISH_TOKEN:-}" ] || { echo "ERROR: GIT_PAGES_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. 12 set -eu
  3. 12 STATE="${1:-}"
  4. 12 DESCRIPTION="${2:-}"
  5. 36 SHA8=$(echo "${GITHUB_SHA:-}" | cut -c1-8)
  6. 12 KEY="${3:-commit-${SHA8}}"
  7. 12 SUITE="${4:-}"
  8. 12 CUSTOM_URL="${5:-}"
  9. 14 [ -z "$STATE" ] && echo "ERROR: state argument is required" >&2 && exit 1
  10. 13 [ -z "$DESCRIPTION" ] && echo "ERROR: description argument is required" >&2 && exit 1
  11. 12 [ -z "${GITEA_API_URL:-}" ] && echo "ERROR: GITEA_API_URL is not set" >&2 && exit 1
  12. 11 [ -z "${GITEA_TOKEN:-}" ] && echo "ERROR: GITEA_TOKEN is not set" >&2 && exit 1
  13. 8 if [ -n "$CUSTOM_URL" ]; then
  14. 2 URL="$CUSTOM_URL"
  15. 6 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}/reports/${SHA8_CUT}/${SUITE}"
  19. else
  20. 5 URL="${GITEA_API_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
  21. fi
  22. 8 REPO="${ROOT_REPO:-${GITHUB_REPOSITORY:-}}"
  23. 8 COMMIT="${ROOT_COMMIT:-${GITHUB_SHA:-}}"
  24. 8 [ -z "$REPO" ] && echo "ERROR: GITHUB_REPOSITORY is not set" >&2 && exit 1
  25. 8 [ -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. 16 -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