sync-packages #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |