Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions .github/workflows/add-submodules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,13 @@ jobs:
run: |
set -euo pipefail

# Summary buckets (doc metadata / skips); printed after Step 2.
META_MISSING=()
NO_DOC_PATHS=()
REPO_EXISTS_SKIP=()

# shellcheck source=assets/env.sh
source "$GITHUB_WORKSPACE/.github/workflows/assets/env.sh"
# shellcheck source=assets/lib.sh
source "$GITHUB_WORKSPACE/.github/workflows/assets/lib.sh"

init_translation_state
init_add_submodule_summary_buckets

begin_phase "$PHASE_SETUP" "Validate inputs and prepare workspace"
validate_secrets
Expand Down Expand Up @@ -193,24 +189,27 @@ jobs:
record_submodule_update "$sub" || true
else
rc=$?
[[ $rc -eq 2 ]] && submodule_fatal=$((submodule_fatal + 1))
if [[ $rc -eq 2 ]]; then
record_submodule_fatal "$sub"
submodule_fatal=$((submodule_fatal + 1))
fi
fi
done

echo "── Summary: Boost library documentation metadata ──" >&2
echo " Type 1 — Missing or unreadable meta/libraries.json (${#META_MISSING[@]}): $([[ ${#META_MISSING[@]} -eq 0 ]] && echo '(none)' || echo "${META_MISSING[*]}")" >&2
echo " Type 2 — No doc paths in meta/libraries.json (${#NO_DOC_PATHS[@]}): $([[ ${#NO_DOC_PATHS[@]} -eq 0 ]] && echo '(none)' || echo "${NO_DOC_PATHS[*]}")" >&2
echo " Type 3 — Target org repo already exists, skipped (${#REPO_EXISTS_SKIP[@]}): $([[ ${#REPO_EXISTS_SKIP[@]} -eq 0 ]] && echo '(none)' || echo "${REPO_EXISTS_SKIP[*]}")" >&2

[[ $submodule_fatal -gt 0 ]] && {
# Buckets filled by process_one_submodule.
print_submodule_processing_summary
Comment thread
AuraMindNest marked this conversation as resolved.
[[ $submodule_fatal -gt 0 ]] && \
phase_err "$submodule_fatal submodule(s) failed with errors."
end_phase
exit 1
}
end_phase

begin_phase "$PHASE_FINALIZE_TRANSLATIONS" "Finalize translations repo"
finalize_translations_repo "$TRANS_DIR" "$LIBS_REF" "${lang_codes_arr[@]}"
finalize_rc=0
finalize_translations_repo "$TRANS_DIR" "$LIBS_REF" "${lang_codes_arr[@]}" || finalize_rc=$?
end_phase

exit_rc=0
[[ $submodule_fatal -gt 0 ]] && exit_rc=1
[[ $finalize_rc -ne 0 ]] && exit_rc=$finalize_rc
[[ $exit_rc -ne 0 ]] && exit $exit_rc
Comment thread
AuraMindNest marked this conversation as resolved.

echo "Done." >&2
6 changes: 4 additions & 2 deletions .github/workflows/assets/env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ if [[ -z "${_ENV_SH_LOADED:-}" ]]; then
)
fi

ORG="${GITHUB_REPOSITORY%%/*}"
TRANSLATIONS_REPO="${GITHUB_REPOSITORY##*/}"
_repo="${GITHUB_REPOSITORY:-}"
ORG="${_repo%%/*}"
TRANSLATIONS_REPO="${_repo##*/}"
unset _repo

BOT_NAME="Boost-Translation-CI-Bot"
BOT_EMAIL="Boost-Translation-CI-Bot@$ORG.local"
Expand Down
89 changes: 86 additions & 3 deletions .github/workflows/assets/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ add_create_tag_workflow() {
"$wf_dir/create-tag.yml"
cp "$GITHUB_WORKSPACE/.github/workflows/assets/env.sh" \
"$wf_dir/assets/env.sh"
set_git_bot_config "$repo_dir"
git -C "$repo_dir" add ".github/workflows/create-tag.yml" ".github/workflows/assets/env.sh"
git -C "$repo_dir" commit -m "Add create-tag workflow"
}
Expand Down Expand Up @@ -240,10 +241,11 @@ finalize_translations_local() {
finalize_translations_repo() {
local dir="$1" libs_ref="$2"
shift 2
local lang_codes_arr=("$@")
finalize_translations_master "$dir" "$libs_ref"
local lang_codes_arr=("$@") lang_code

finalize_translations_master "$dir" "$libs_ref" || return $?
for lang_code in "${lang_codes_arr[@]}"; do
finalize_translations_local "$dir" "$libs_ref" "$lang_code"
finalize_translations_local "$dir" "$libs_ref" "$lang_code" || return $?
done
}

Expand All @@ -260,9 +262,17 @@ finalize_translations_repo() {
# Submodule names eligible for Weblate per language; only submodules that
# passed process_local_branch. Written via record_add_or_update_submodule;
# consumed by trigger_weblate (translation.sh).
#
# SUBMODULE_FATAL (indexed array)
# Submodule names that returned fatal (exit 2) from process_one_submodule.
#
# OPEN_PR_SKIP (indexed array)
# Submodule names skipped due to an open translation PR (start-translation local).

init_translation_state() {
UPDATES=()
SUBMODULE_FATAL=()
OPEN_PR_SKIP=()
declare -gA add_or_update=()
}

Expand Down Expand Up @@ -301,6 +311,63 @@ _submodule_in_add_or_update() {
return 1
}

_submodule_in_array() {
local name="$1"
shift
local item
for item in "$@"; do
[[ "$item" == "$name" ]] && return 0
done
return 1
}

# Append a fatal submodule name (idempotent on duplicate).
record_submodule_fatal() {
local sub_name="$1"
_submodule_in_array "$sub_name" "${SUBMODULE_FATAL[@]}" && return 0
SUBMODULE_FATAL+=("$sub_name")
}

# Summary bucket globals; filled by process_one_submodule before print_submodule_processing_summary.
init_submodule_summary_buckets() {
META_MISSING=()
NO_DOC_PATHS=()
ORG_REPO_MISSING=()
}

init_add_submodule_summary_buckets() {
META_MISSING=()
NO_DOC_PATHS=()
REPO_EXISTS_SKIP=()
}

# Print consolidated success / failure / skip summary after the per-submodule loop.
print_submodule_processing_summary() {
local -a processing_errors=() repo_exists_skip=()
local -a meta_missing=() org_repo_missing=() no_doc_paths=()
local sub

[[ ${META_MISSING+set} ]] && meta_missing=("${META_MISSING[@]}")
[[ ${ORG_REPO_MISSING+set} ]] && org_repo_missing=("${ORG_REPO_MISSING[@]}")
[[ ${NO_DOC_PATHS+set} ]] && no_doc_paths=("${NO_DOC_PATHS[@]}")
[[ ${REPO_EXISTS_SKIP+set} ]] && repo_exists_skip=("${REPO_EXISTS_SKIP[@]}")

for sub in "${SUBMODULE_FATAL[@]}"; do
_submodule_in_array "$sub" "${meta_missing[@]}" && continue
_submodule_in_array "$sub" "${org_repo_missing[@]}" && continue
processing_errors+=("$sub")
done

echo "── Submodule processing summary ──" >&2
echo " Successfully updated (${#UPDATES[@]}): $([[ ${#UPDATES[@]} -eq 0 ]] && echo '(none)' || echo "${UPDATES[*]}")" >&2
echo " Failed — Type 1, missing meta/libraries.json (${#meta_missing[@]}): $([[ ${#meta_missing[@]} -eq 0 ]] && echo '(none)' || echo "${meta_missing[*]}")" >&2
echo " Failed — Type 3, org repo missing (${#org_repo_missing[@]}): $([[ ${#org_repo_missing[@]} -eq 0 ]] && echo '(none)' || echo "${org_repo_missing[*]}")" >&2
echo " Failed — processing error (${#processing_errors[@]}): $([[ ${#processing_errors[@]} -eq 0 ]] && echo '(none)' || echo "${processing_errors[*]}")" >&2
echo " Skipped — Type 2, no doc paths (${#no_doc_paths[@]}): $([[ ${#no_doc_paths[@]} -eq 0 ]] && echo '(none)' || echo "${no_doc_paths[*]}")" >&2
echo " Skipped — org repo already exists (${#repo_exists_skip[@]}): $([[ ${#repo_exists_skip[@]} -eq 0 ]] && echo '(none)' || echo "${repo_exists_skip[*]}")" >&2
echo " Skipped — open translation PR (${#OPEN_PR_SKIP[@]}): $([[ ${#OPEN_PR_SKIP[@]} -eq 0 ]] && echo '(none)' || echo "${OPEN_PR_SKIP[*]}")" >&2
}

# Append a successfully processed submodule to UPDATES (idempotent on duplicate).
record_submodule_update() {
local sub_name="$1"
Expand Down Expand Up @@ -349,6 +416,22 @@ validate_add_or_update_entry() {

# ── Parsing helpers ───────────────────────────────────────────────────

# Emit a compact JSON array of submodule basenames (empty → []).
submodule_names_to_json() {
if [[ $# -eq 0 ]]; then
echo '[]'
return
fi
printf '%s\n' "$@" | jq -R . | jq -s -c .
}

# Parse JSON array of submodule basenames; one name per line (empty/no-op for []).
parse_submodule_names_json() {
local json="${1:-}"
[[ -z "$json" || "$json" == "[]" ]] && return 0
jq -r '.[]' <<< "$json"
}

# Parse "[zh_Hans, en]" or "zh_Hans,en" into one code per line.
parse_list() {
local s="$1"
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/assets/translation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ sync_repo_master() {
update_local_merge_from_master() {
local repo_dir="$1" lang_code="$2"
local local_br="${LOCAL_BRANCH_PREFIX}${lang_code}"
set_git_bot_config "$repo_dir"
git -C "$repo_dir" fetch origin "$MASTER_BRANCH" || return 2
git -C "$repo_dir" fetch origin "$local_br" || return 2
git -C "$repo_dir" checkout -B "$local_br" "origin/$local_br" || return 2
Expand All @@ -37,6 +38,7 @@ update_local_merge_from_master() {
ensure_local_branch_in_repo() {
local dest_repo="$1" sub_name="$2" lang_code="$3"
local local_br="${LOCAL_BRANCH_PREFIX}${lang_code}"
set_git_bot_config "$dest_repo"
if git -C "$dest_repo" ls-remote --exit-code --heads origin "$local_br" &>/dev/null; then
echo " Branch $local_br already exists in $sub_name." >&2
return 0
Expand All @@ -57,7 +59,11 @@ process_local_branch() {
if git -C "$dest_repo" ls-remote --exit-code --heads origin "$local_br" &>/dev/null; then
has_open_translation_pr "$MODULE_ORG" "$sub_name" "$lang_code"
case $? in
0) echo " Open translation PR found for $sub_name ($local_br), skipping." >&2; return 1 ;;
0)
OPEN_PR_SKIP+=("$sub_name")
echo " Open translation PR found for $sub_name ($local_br), skipping." >&2
return 1
;;
2) return 2 ;;
esac
update_local_merge_from_master "$dest_repo" "$lang_code" || return 2
Expand Down Expand Up @@ -119,6 +125,7 @@ process_one_submodule() {
clone_repo "$org_repo_url" "$MASTER_BRANCH" "$dest_repo" keep || {
echo " clone_repo failed." >&2; return 2
}
set_git_bot_config "$dest_repo"
fi

local any_added=0 rc
Expand Down
Loading
Loading