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
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
groups:
github-actions:
patterns:
- "*"
79 changes: 8 additions & 71 deletions .github/workflows/add-submodules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
token: ${{ secrets.SYNC_TOKEN }}

Expand All @@ -45,6 +45,8 @@ jobs:
source "$GITHUB_WORKSPACE/.github/workflows/assets/env.sh"
# shellcheck source=assets/lib.sh
source "$GITHUB_WORKSPACE/.github/workflows/assets/lib.sh"
# shellcheck source=assets/add_submodules.sh
source "$GITHUB_WORKSPACE/.github/workflows/assets/add_submodules.sh"

init_translation_state
init_add_submodule_summary_buckets
Expand All @@ -64,78 +66,13 @@ jobs:
# without embedding tokens in remote URLs.
gh auth setup-git

# LIBS_REF: workflow env
# shellcheck disable=SC2153
# libs_ref and boost_org are read by add_submodules.sh (sourced).
# shellcheck disable=SC2153,SC2034
libs_ref="${LIBS_REF:?}"
# BOOST_ORG: env.sh
# shellcheck disable=SC2153
# shellcheck disable=SC2153,SC2034
boost_org="${BOOST_ORG:?}"
end_phase

# ── Organization repo helpers ────────────────────────────────────────

create_repo() {
gh repo create "$1/$2" --public > /dev/null \
|| { echo "Create repo $1/$2 failed" >&2; return 1; }
}

set_default_branch() {
gh api --method PATCH "repos/$1/$2" -f "default_branch=$3" \
|| { phase_err "set default branch to $3 failed for $1/$2."; return 1; }
}

create_new_repo_and_push() {
local org="$1" sub_name="$2" sub_clone="$3" repo_url="$4" libs_ref="$5"
create_repo "$org" "$sub_name" || return 2
git -C "$sub_clone" init || return 2
set_git_bot_config "$sub_clone"
git -C "$sub_clone" add -A || return 2
git -C "$sub_clone" commit -m "Create the original documentation of $libs_ref" || return 2
git -C "$sub_clone" branch -M "$MASTER_BRANCH" || return 2
git -C "$sub_clone" remote remove origin 2>/dev/null || true
git -C "$sub_clone" remote add origin "$repo_url" || return 2
git -C "$sub_clone" push -u origin "$MASTER_BRANCH" || return 2
git -C "$sub_clone" push origin "$MASTER_BRANCH" || return 2
for lang_code in "${lang_codes_arr[@]}"; do
local local_br="${LOCAL_BRANCH_PREFIX}${lang_code}"
git -C "$sub_clone" checkout -B "$local_br" "$MASTER_BRANCH" || return 2
add_create_tag_workflow "$sub_clone" || return 2
git -C "$sub_clone" push -u origin "$local_br" || return 2
done
set_default_branch "$org" "$sub_name" "$MASTER_BRANCH" || return 2
}

# ── Per-submodule processing ──────────────────────────────────────────

process_one_submodule() {
local sub_name="$1" doc_paths

if repo_exists "$MODULE_ORG" "$sub_name"; then
REPO_EXISTS_SKIP+=("$sub_name")
echo " Skipping: $MODULE_ORG/$sub_name already exists." >&2; return 1
fi

doc_paths=$(get_doc_paths "$sub_name" "$libs_ref") || {
META_MISSING+=("$sub_name")
echo " No libraries.json." >&2; return 2
}
[[ -z "$doc_paths" ]] && {
NO_DOC_PATHS+=("$sub_name")
echo " No doc paths in metadata, skipping." >&2; return 1
}

local sub_clone="$BOOST_WORK/$sub_name"
clone_repo "https://github.com/${boost_org}/${sub_name}.git" \
"$libs_ref" "$sub_clone" || { echo " Clone failed." >&2; return 2; }

local -a paths_arr
mapfile -t paths_arr <<< "$doc_paths"
prune_to_doc_only "$sub_clone" "${paths_arr[@]}"

local org_repo_url="https://github.com/${MODULE_ORG}/${sub_name}.git"
create_new_repo_and_push "$MODULE_ORG" "$sub_name" "$sub_clone" "$org_repo_url" "$libs_ref"
}

# ── Main ─────────────────────────────────────────────────────────────

begin_phase "$PHASE_ENSURE_BRANCHES" "Ensure local branches in translations repo"
Expand Down Expand Up @@ -185,7 +122,7 @@ jobs:
for i in "${!submodule_names[@]}"; do
sub="${submodule_names[$i]}"
echo "[$(( i + 1 ))/$total] $sub ..." >&2
if process_one_submodule "$sub"; then
if add_one_submodule "$sub"; then
record_submodule_update "$sub" || true
else
rc=$?
Expand All @@ -196,7 +133,7 @@ jobs:
fi
done

# Buckets filled by process_one_submodule.
# Buckets filled by add_one_submodule.
print_submodule_processing_summary
[[ $submodule_fatal -gt 0 ]] && \
phase_err "$submodule_fatal submodule(s) failed with errors."
Expand Down
68 changes: 68 additions & 0 deletions .github/workflows/assets/add_submodules.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# shellcheck shell=bash
# add-submodules orchestration helpers.
# Source after env.sh and lib.sh. Requires globals:
# MODULE_ORG, MASTER_BRANCH, BOOST_ORG, BOOST_WORK, libs_ref, boost_org,
# lang_codes_arr, REPO_EXISTS_SKIP, META_MISSING, NO_DOC_PATHS, GITHUB_WORKSPACE.
# shellcheck disable=SC2034,SC2154

create_repo() {
gh repo create "$1/$2" --public > /dev/null \
|| { echo "Create repo $1/$2 failed" >&2; return 2; }
}

set_default_branch() {
gh api --method PATCH "repos/$1/$2" -f "default_branch=$3" \
|| { phase_err "set default branch to $3 failed for $1/$2."; return 2; }
}

create_new_repo_and_push() {
local org="$1" sub_name="$2" sub_clone="$3" repo_url="$4" libs_ref="$5"
create_repo "$org" "$sub_name" || return 2
git -C "$sub_clone" init || return 2
set_git_bot_config "$sub_clone" || return 2
git -C "$sub_clone" add -A || return 2
git -C "$sub_clone" commit -m "Create the original documentation of $libs_ref" || return 2
git -C "$sub_clone" branch -M "$MASTER_BRANCH" || return 2
git -C "$sub_clone" remote remove origin 2>/dev/null || true
git -C "$sub_clone" remote add origin "$repo_url" || return 2
git -C "$sub_clone" push -u origin "$MASTER_BRANCH" || return 2
git -C "$sub_clone" push origin "$MASTER_BRANCH" || return 2
for lang_code in "${lang_codes_arr[@]}"; do
local local_br="${LOCAL_BRANCH_PREFIX}${lang_code}"
git -C "$sub_clone" checkout -B "$local_br" "$MASTER_BRANCH" || return 2
add_create_tag_workflow "$sub_clone" || return 2
git -C "$sub_clone" push -u origin "$local_br" || return 2
done
set_default_branch "$org" "$sub_name" "$MASTER_BRANCH" || return 2
}

# Create one MODULE_ORG mirror repo from a boostorg lib (add-submodules only).
add_one_submodule() {
local sub_name="$1" doc_paths

if repo_exists "$MODULE_ORG" "$sub_name"; then
REPO_EXISTS_SKIP+=("$sub_name")
echo " Skipping: $MODULE_ORG/$sub_name already exists." >&2; return 1
fi

doc_paths=$(get_doc_paths "$sub_name" "$libs_ref") || {
META_MISSING+=("$sub_name")
echo " No libraries.json." >&2; return 2
}
[[ -z "$doc_paths" ]] && {
NO_DOC_PATHS+=("$sub_name")
echo " No doc paths in metadata, skipping." >&2; return 1
}

local sub_clone="$BOOST_WORK/$sub_name"
clone_repo "https://github.com/${boost_org}/${sub_name}.git" \
"$libs_ref" "$sub_clone" || { echo " Clone failed." >&2; return 2; }

local -a paths_arr
mapfile -t paths_arr <<< "$doc_paths"
prune_to_doc_only "$sub_clone" "${paths_arr[@]}"

local org_repo_url="https://github.com/${MODULE_ORG}/${sub_name}.git"
create_new_repo_and_push "$MODULE_ORG" "$sub_name" "$sub_clone" "$org_repo_url" "$libs_ref" \
|| return 2
}
2 changes: 1 addition & 1 deletion .github/workflows/assets/create-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
echo "tagname=$TAGNAME" >> "$GITHUB_OUTPUT"

- name: Checkout local-{lang_code} branch with tags
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/assets/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ finalize_translations_repo() {
# consumed by trigger_weblate (translation.sh).
#
# SUBMODULE_FATAL (indexed array)
# Submodule names that returned fatal (exit 2) from process_one_submodule.
# Submodule names that returned fatal (exit 2) from add_one_submodule or sync_one_submodule.
#
# OPEN_PR_SKIP (indexed array)
# Submodule names skipped due to an open translation PR (start-translation local).
Expand Down Expand Up @@ -328,7 +328,8 @@ record_submodule_fatal() {
SUBMODULE_FATAL+=("$sub_name")
}

# Summary bucket globals; filled by process_one_submodule before print_submodule_processing_summary.
# Summary bucket globals; filled by sync_one_submodule before print_submodule_processing_summary.
# add-submodules uses init_add_submodule_summary_buckets for REPO_EXISTS_SKIP.
init_submodule_summary_buckets() {
META_MISSING=()
NO_DOC_PATHS=()
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/assets/translation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ process_local_branch() {
return 0
}

process_one_submodule() {
# Sync one existing MODULE_ORG mirror: mirror master and/or local branches.
sync_one_submodule() {
local sub_name="$1" doc_paths
local phase="${START_PHASE:-}"

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
persist-credentials: false

Expand All @@ -22,7 +22,7 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
persist-credentials: false

Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/start-translation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
json: ${{ steps.langs.outputs.json }}
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
token: ${{ secrets.SYNC_TOKEN }}
persist-credentials: false
Expand Down Expand Up @@ -74,7 +74,7 @@ jobs:
cancel-in-progress: false
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
token: ${{ secrets.SYNC_TOKEN }}
persist-credentials: false
Expand Down Expand Up @@ -163,7 +163,7 @@ jobs:
for i in "${!submodule_names[@]}"; do
sub="${submodule_names[$i]}"
echo "[$(( i + 1 ))/$total] $sub ..." >&2
if process_one_submodule "$sub"; then
if sync_one_submodule "$sub"; then
record_submodule_update "$sub" || true
else
rc=$?
Expand All @@ -174,7 +174,7 @@ jobs:
fi
done

# Buckets filled by process_one_submodule.
# Buckets filled by sync_one_submodule.
print_submodule_processing_summary
[[ $submodule_fatal -gt 0 ]] && \
phase_err "$submodule_fatal submodule(s) failed with errors."
Expand Down Expand Up @@ -211,7 +211,7 @@ jobs:
cancel-in-progress: false
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
token: ${{ secrets.SYNC_TOKEN }}
persist-credentials: false
Expand Down Expand Up @@ -268,7 +268,7 @@ jobs:

echo "Lang code: $LANG_CODE" >&2

# Read by process_one_submodule in translation.sh (sourced above).
# Read by sync_one_submodule in translation.sh (sourced above).
# shellcheck disable=SC2034
lang_codes_arr=("$LANG_CODE")
init_add_or_update_lang "$LANG_CODE"
Expand Down Expand Up @@ -300,7 +300,7 @@ jobs:
for i in "${!submodule_names[@]}"; do
sub="${submodule_names[$i]}"
echo "[$(( i + 1 ))/$total] $sub ..." >&2
if process_one_submodule "$sub"; then
if sync_one_submodule "$sub"; then
record_submodule_update "$sub" || true
else
rc=$?
Expand All @@ -311,7 +311,7 @@ jobs:
fi
done

# Buckets filled by process_one_submodule.
# Buckets filled by sync_one_submodule.
print_submodule_processing_summary
[[ $submodule_fatal -gt 0 ]] && \
phase_err "$submodule_fatal submodule(s) failed with errors."
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/sync-translation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
json: ${{ steps.branches.outputs.json }}
steps:
- name: Checkout repository (master)
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
token: ${{ secrets.SYNC_TOKEN }}
persist-credentials: false
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
cancel-in-progress: false
steps:
- name: Checkout repository (master)
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
token: ${{ secrets.SYNC_TOKEN }}
fetch-depth: 0
Expand Down
1 change: 1 addition & 0 deletions scripts/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ echo "lint: actionlint ${ACTIONLINT_VERSION} ($("$ACTIONLINT_BIN" -version | hea
.github/workflows/assets/env.sh \
.github/workflows/assets/lib.sh \
.github/workflows/assets/translation.sh \
.github/workflows/assets/add_submodules.sh \
scripts/*.sh \
tests/helpers/*.bash

Expand Down
13 changes: 13 additions & 0 deletions tests/helpers/common.bash
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ load_translation() {
source "$ASSETS_DIR/translation.sh"
}

load_add_submodules() {
load_lib
export GITHUB_WORKSPACE="$REPO_ROOT"
# shellcheck source=/dev/null
source "$ASSETS_DIR/add_submodules.sh"
}

# Run a function and capture its exit code (works under set -e in callers).
run_fn() {
local errexit_was_on=0
Expand Down Expand Up @@ -54,7 +61,13 @@ init_process_globals() {
# Fixed values so tests behave the same locally and in CI (GITHUB_REPOSITORY varies).
MODULE_ORG="testorg"
BOOST_ORG="boostorg"
boost_org="$BOOST_ORG"
libs_ref="develop"
lang_codes_arr=("en")
init_add_or_update_lang "en"
}

init_add_submodule_globals() {
init_process_globals
init_add_submodule_summary_buckets
}
Loading
Loading