Skip to content

sync-packages

sync-packages #64

Workflow file for this run

name: Sync Packages
on:
repository_dispatch:
types: [sync-packages]
permissions:
contents: read
jobs:
settings:
name: Settings
uses: ./.github/workflows/settings.yml
sync:
name: "Sync package: ${{ matrix.package }}"
runs-on: ubuntu-latest
needs:
- settings
strategy:
fail-fast: false
matrix:
package: ${{ fromJson(needs.settings.outputs.packages-names) }}
environment:
name: trusted
deployment: false
steps:
# Dependencies
- name: Install git-filter-repo
run: sudo -H pip3 install git-filter-repo
- name: Detect SSH Key name
id: secret
run: |
echo "name=$(echo "PKG_${{ matrix.package }}" | sed 's/-/_/g')" >> $GITHUB_OUTPUT
- name: Setup SSH Key
run: |
mkdir -p ~/.ssh/
echo "${{ secrets[steps.secret.outputs.name] }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
# Checkout source repo
# Unfortunately I'm not sure how to use actions/checkout with `--no-single-branch`
# that is required to get all commits.
- name: Checkout src
run: |
git clone --no-single-branch "git@github.com:${{ github.repository }}.git" src
# Package
- name: Package name
id: package
run: |
echo "value=$(jq -r '.name' "src/${{ needs.settings.outputs.packages-directory }}/${{ matrix.package }}/composer.json")" >> $GITHUB_OUTPUT
# Checkout package repo
# Unfortunately I'm not sure how to use actions/checkout with `--no-single-branch`
# that is required to get all commits.
- name: Checkout package
run: |
git clone --no-single-branch "git@github.com:${{ steps.package.outputs.value }}.git" origin
# Create package repo
# Checkout is not used because `git-filter-repo` doesn't remove the old
# removed branches (which are not needed anymore) and I don't know how
# to fix it.
- name: Create package repo
run: |
git init package
- name: Configure package repo
working-directory: package
run: |
git remote add origin "git@github.com:${{ steps.package.outputs.value }}.git"
# Update package
#
# There is one known issue: if branch related only for one package it will
# be cloned into all other packages (and will be without commits).
#
# How to disable this behaviour?
- name: Extract commits
run: |
# Package directory can be renamed, so we are collecting all previous
# names to preserve the history.
NAMES=$( jq '(."extra"."project"."sync-packages"."${{ matrix.package }}" // []) | unique' "src/composer.json" | jq -c -r '.[]' | tr -d '\r')
FILTERS=()
FILTERS+=("--subdirectory-filter")
FILTERS+=("${{ needs.settings.outputs.packages-directory }}/${{ matrix.package }}")
while IFS= read -r NAME
do
if [[ -n "${NAME}" ]]; then
FILTERS+=("--subdirectory-filter")
FILTERS+=("${{ needs.settings.outputs.packages-directory }}/${NAME}")
fi
done <<< "${NAMES}"
git-filter-repo --source=src --target=package "${FILTERS[@]}"
# Before `push --mirror` we need enable track for all branches, or they will
# not be visible after `git clone` and on the Branches page on GitHub.
#
# Thanks to https://stackoverflow.com/a/379842/7511282
- name: Setup branches
working-directory: package
run: |
for i in `git branch -a | grep remotes/origin/`;
do
git branch --track ${i#remotes/origin/} $i \
|| git branch --track ${i#remotes/origin/} --set-upstream-to=$i
done
# The `git-filter-repo` may be dangerous (especially with directories renames)
# and may remove some tags/versions. As a safety check, we are comparing
# tags and fail if some of them were deleted. Commits are not too important
# and thus ignored.
#
# A partial update is probably a better approach, but I'm not sure how to
# implement it...
- name: Validate tags
run: |
(cd "origin" && git show-ref --tags -d) | grep "\^{}" | sed 's/\^{}//g' | sort > tags-origin.txt
(cd "package" && git show-ref --tags -d) | grep "\^{}" | sed 's/\^{}//g' | sort > tags-package.txt
MISSED_TAGS=$(comm -23 "tags-origin.txt" "tags-package.txt")
if [[ -n "${MISSED_TAGS}" ]]; then
echo "${MISSED_TAGS}" >> $GITHUB_STEP_SUMMARY
exit 1
fi
- name: Push package
working-directory: package
run: |
git push --mirror origin