diff --git a/.github/workflows/build-and-push-docker-image.yml b/.github/workflows/build-and-push-docker-image.yml index cbd536f16..57fa3cc58 100644 --- a/.github/workflows/build-and-push-docker-image.yml +++ b/.github/workflows/build-and-push-docker-image.yml @@ -33,6 +33,51 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine fetch plan + id: fetch-plan + env: + EVENT_NAME: ${{ github.event_name }} + BEFORE_SHA: ${{ github.event.before }} + CURRENT_SHA: ${{ github.sha }} + INPUT_FETCH_ARGUMENTS: ${{ inputs.fetch_arguments }} + run: | + set -o errexit -o nounset -o pipefail + + fetch_arguments='--recent --attachments' + fetch_sync_codes='qm' + if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then + fetch_arguments="${INPUT_FETCH_ARGUMENTS:---recent --attachments}" + elif [[ "$EVENT_NAME" == "push" ]]; then + if git cat-file -e "${BEFORE_SHA}^{commit}" 2>/dev/null; then + changed_catalogs="$( + git diff --name-only "$BEFORE_SHA" "$CURRENT_SHA" -- \ + ':(glob)confluence-mdx/var/pages.*.yaml' + )" + else + changed_catalogs="$( + find confluence-mdx/var -maxdepth 1 -type f \ + -name 'pages.*.yaml' -print + )" + fi + + if [[ -n "$changed_catalogs" ]]; then + fetch_arguments='--remote --attachments' + fetch_sync_codes="$( + printf '%s\n' "$changed_catalogs" | + sed -E 's#^confluence-mdx/var/pages\.([a-z0-9_-]+)\.yaml$#\1#' | + sort -u | + paste -sd ' ' - + )" + fi + fi + + echo "arguments=$fetch_arguments" >> "$GITHUB_OUTPUT" + echo "sync-codes=$fetch_sync_codes" >> "$GITHUB_OUTPUT" + echo "Fetch arguments: $fetch_arguments" + echo "Fetch sync codes: $fetch_sync_codes" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -55,7 +100,8 @@ jobs: run: | set -o errexit -o nounset -o pipefail -o xtrace docker compose --progress=plain build \ - --build-arg "FETCH_ARGS=${{ inputs.fetch_arguments || '--recent --attachments' }}" + --build-arg "FETCH_ARGS=${{ steps.fetch-plan.outputs.arguments }}" \ + --build-arg "FETCH_SYNC_CODES=${{ steps.fetch-plan.outputs.sync-codes }}" - name: Push Docker image if: github.event_name != 'pull_request' @@ -73,4 +119,3 @@ jobs: DOCKERHUB_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }} DOCKERHUB_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_CREDENTIAL }} run: python3 bin/dockerhub-cleanup.py - diff --git a/confluence-mdx/Dockerfile b/confluence-mdx/Dockerfile index 58e2da5ce..78e35d4ea 100644 --- a/confluence-mdx/Dockerfile +++ b/confluence-mdx/Dockerfile @@ -19,16 +19,23 @@ RUN pip install --no-cache-dir -r requirements.txt COPY bin/ ./bin/ RUN chmod +x bin/*.py bin/*.sh COPY etc/ ./etc/ +COPY var/pages.*.yaml ./var/ # Restore cache at its expected path (for Stage 3 attachment fallback) COPY cache/ ./cache/ # Populate var/ baseline from cache and fetch updates in one step. -# cp -a creates var/ with all cached YAML/content/attachment files, -# then fetch_cli.py downloads pages according to FETCH_ARGS. -# Default: --recent --attachments (incremental). Use --remote --attachments for full fetch. +# The tracked catalogs preserve Spaces that are not part of this fetch plan. +# cp -a adds all cached YAML/content/attachment files, +# then fetch_cli.py downloads each Space according to FETCH_ARGS. +# Defaults: qm with --recent --attachments (incremental). +# Use FETCH_SYNC_CODES="qm qcp" and --remote --attachments for multiple full fetches. ARG FETCH_ARGS="--recent --attachments" -RUN cp -a cache/. var/ && python3 bin/fetch_cli.py ${FETCH_ARGS} +ARG FETCH_SYNC_CODES="qm" +RUN cp -a cache/. var/ && \ + for sync_code in ${FETCH_SYNC_CODES}; do \ + python3 bin/fetch_cli.py --sync-code "${sync_code}" ${FETCH_ARGS}; \ + done # ── Stage 2: Final image ──────────────────────────── FROM python:3.12-slim diff --git a/confluence-mdx/bin/convert_all.py b/confluence-mdx/bin/convert_all.py index e536e3cd0..4168dda80 100755 --- a/confluence-mdx/bin/convert_all.py +++ b/confluence-mdx/bin/convert_all.py @@ -615,6 +615,7 @@ def finalize_manifest( sort_keys=False, ) temp_path = Path(temp_file.name) + temp_path.chmod(0o644) os.replace(temp_path, manifest_path) diff --git a/confluence-mdx/tests/test_convert_all_folders.py b/confluence-mdx/tests/test_convert_all_folders.py index 2bdebab30..41d28a5e5 100644 --- a/confluence-mdx/tests/test_convert_all_folders.py +++ b/confluence-mdx/tests/test_convert_all_folders.py @@ -244,6 +244,7 @@ def test_manifest_removes_only_previous_owned_outputs(tmp_path): assert manual.read_text() == "manual" assert current.read_text() == "new" assert yaml.safe_load(manifest_path.read_text())["outputs"] == current_outputs + assert manifest_path.stat().st_mode & 0o777 == 0o644 def test_manifest_preserves_stale_output_owned_by_another_profile(tmp_path): diff --git a/confluence-mdx/var/pages.qcp.yaml b/confluence-mdx/var/pages.qcp.yaml index e69de29bb..fe51488c7 100644 --- a/confluence-mdx/var/pages.qcp.yaml +++ b/confluence-mdx/var/pages.qcp.yaml @@ -0,0 +1 @@ +[]