Skip to content

sync-packages

sync-packages #32

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) }}
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
- name: Checkout package
working-directory: package
run: |
git checkout "${{ github.ref_name }}"
- name: Sync properties
env:
GITHUB_TOKEN: ${{ secrets.TOKEN_PACKAGE }}
run: |
# First we need to get current properties of repository
gh repo view "git@github.com:${{ steps.package.outputs.value }}.git" --json repositoryTopics --json description --json homepageUrl > repository.json
# Url & Description
PKG_URL="$(jq '.homepage // ""' -c -r package/composer.json)"
PKG_DESC="$(jq '.description // ""' -c -r package/composer.json)"
REPO_URL="$(jq '.homepageUrl // ""' -c -r repository.json)"
REPO_DESC="$(jq '.description // ""' -c -r repository.json)"
# Topics must be lowercase and without white-spaces. Unfortunately,
# `jq` doesn't have Unicode support to change case, so `sed` is used.
#
# - https://github.com/jqlang/jq/issues/492
jq '(.keywords // []) | unique | .[]' -c -r package/composer.json | sed -e 's/\s\+/-/g' | sed -e 's/\(.*\)/\L\1/' | sort > package-topics.txt
jq '(.repositoryTopics // []) | map(.name) | .[]' -c -r repository.json | sort > repository-topics.txt
TOPICS_REMOVE=$(comm -23 "repository-topics.txt" "package-topics.txt")
TOPICS_ADD=$(comm -13 "repository-topics.txt" "package-topics.txt")
# Build the command
ARGUMENTS=()
if [[ "$PKG_URL" != "$REPO_URL" ]]; then
ARGUMENTS+=("--homepage")
ARGUMENTS+=("$PKG_URL")
fi
if [[ "$PKG_DESC" != "$REPO_DESC" ]]; then
ARGUMENTS+=("--description")
ARGUMENTS+=("$PKG_DESC")
fi
# Run
if [[ "${ARGUMENTS[@]}" ]]
then
gh repo edit "git@github.com:${{ steps.package.outputs.value }}.git" "${ARGUMENTS[@]}"
fi