Skip to content

Commit 191622e

Browse files
authored
Merge pull request #1 from pyTooling/claude/synchronize-forks-action
Add the 'SynchronizeForks' composite action
2 parents 8542632 + 3aa6ae5 commit 191622e

15 files changed

Lines changed: 775 additions & 5 deletions

File tree

‎.editorconfig‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
# end_of_line = lf
6+
insert_final_newline = true
7+
trim_trailing_whitespace = true
8+
indent_style = tab
9+
indent_size = 2
10+
tab_width = 2
11+
12+
[*.{yml,yaml}]
13+
indent_style = space
14+
indent_size = 2
15+
16+
[*.md]
17+
trim_trailing_whitespace = false

‎.github/CODEOWNERS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* @Paebbels
2+
3+
/.github/ @Paebbels
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright © 2024-2026 Patrick Lehmann
4+
# Copyright © 2026 The pyTooling Authors
5+
#
6+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7+
# documentation files (the “Software”), to deal in the Software without restriction, including without limitation the
8+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
9+
# persons to whom the Software is furnished to do so, subject to the following conditions:
10+
#
11+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
12+
# Software.
13+
#
14+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
15+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18+
name: Check-Outputs
19+
description: Check the output parameters of the 'SynchronizeForks' action against their expected values.
20+
inputs:
21+
synchronized:
22+
description: Actual number of synchronized branches.
23+
type: string
24+
required: true
25+
skipped:
26+
description: Actual number of skipped entries.
27+
type: string
28+
required: true
29+
errors:
30+
description: Actual number of errors.
31+
type: string
32+
required: true
33+
expected-synchronized:
34+
description: Expected number of synchronized branches.
35+
type: string
36+
required: true
37+
expected-skipped:
38+
description: Expected number of skipped entries.
39+
type: string
40+
required: true
41+
expected-errors:
42+
description: Expected number of errors.
43+
type: string
44+
required: true
45+
46+
runs:
47+
using: composite
48+
steps:
49+
- name: 📋 Verify output parameters
50+
shell: bash
51+
env:
52+
SYNCHRONIZED: ${{ inputs.synchronized }}
53+
SKIPPED: ${{ inputs.skipped }}
54+
ERRORS: ${{ inputs.errors }}
55+
EXPECTED_SYNCHRONIZED: ${{ inputs.expected-synchronized }}
56+
EXPECTED_SKIPPED: ${{ inputs.expected-skipped }}
57+
EXPECTED_ERRORS: ${{ inputs.expected-errors }}
58+
run: |
59+
# 📋 Verify output parameters
60+
set +e
61+
62+
ANSI_LIGHT_RED=$'\x1b[91m'
63+
ANSI_LIGHT_GREEN=$'\x1b[92m'
64+
ANSI_NOCOLOR=$'\x1b[0m'
65+
66+
errors=0
67+
checkOutput() {
68+
local name="${1}" actual="${2}" expected="${3}"
69+
70+
printf "%s" "Checking output parameter '${name}' ... "
71+
if [[ "${actual}" == "${expected}" ]]; then
72+
printf "%s\n" "${ANSI_LIGHT_GREEN}[PASSED]${ANSI_NOCOLOR} (${actual})"
73+
else
74+
printf "%s\n" "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR} (expected '${expected}', got '${actual}')"
75+
printf "::error title=%s::%s\n" "check-outputs" "Output parameter '${name}' is '${actual}', but '${expected}' was expected."
76+
errors=$((errors + 1))
77+
fi
78+
}
79+
80+
checkOutput "synchronized" "${SYNCHRONIZED}" "${EXPECTED_SYNCHRONIZED}"
81+
checkOutput "skipped" "${SKIPPED}" "${EXPECTED_SKIPPED}"
82+
checkOutput "errors" "${ERRORS}" "${EXPECTED_ERRORS}"
83+
84+
printf "%s\n" ""
85+
if [[ ${errors} -ne 0 ]]; then
86+
printf "%s\n" "${ANSI_LIGHT_RED}Counted ${errors} errors.${ANSI_NOCOLOR}"
87+
exit 1
88+
else
89+
printf "%s\n" "${ANSI_LIGHT_GREEN}No errors found.${ANSI_NOCOLOR}"
90+
fi

‎.github/dependabot.yml‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: 2
2+
updates:
3+
# Maintain GitHub Action runners
4+
- package-ecosystem: "github-actions"
5+
directory: "/"
6+
target-branch: dev
7+
commit-message:
8+
prefix: "[Dependabot]"
9+
labels:
10+
- Dependencies
11+
assignees:
12+
- Paebbels
13+
schedule:
14+
interval: "daily" # Checks on Monday trough Friday.

‎.github/pull_request_template.md‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# New Features
2+
3+
* tbd
4+
* tbd
5+
6+
# Changes
7+
8+
* tbd
9+
* tbd
10+
11+
# Bug Fixes
12+
13+
* tbd
14+
* tbd
15+
16+
# Documentation
17+
18+
* tbd
19+
* tbd
20+
21+
# Unit Tests
22+
23+
* tbd
24+
* tbd
25+
26+
----------
27+
# Related Issues and Pull-Requests
28+
29+
* tbd
30+
* tbd

‎.github/workflows/Verification.yml‎

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright © 2024-2026 Patrick Lehmann
4+
# Copyright © 2026 The pyTooling Authors
5+
#
6+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7+
# documentation files (the “Software”), to deal in the Software without restriction, including without limitation the
8+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
9+
# persons to whom the Software is furnished to do so, subject to the following conditions:
10+
#
11+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
12+
# Software.
13+
#
14+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
15+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18+
name: Verification of the Synchronize Forks Action
19+
20+
on:
21+
push:
22+
workflow_dispatch:
23+
24+
jobs:
25+
DryRun:
26+
name: 🐧 Dry-run with a valid configuration
27+
runs-on: ubuntu-26.04
28+
29+
steps:
30+
- name: ⏬ Checkout repository to use the local action
31+
uses: actions/checkout@v7
32+
33+
- name: 🔄 Synchronize forked repositories
34+
id: synchronize
35+
uses: ./
36+
with:
37+
github-token: ${{ github.token }}
38+
target-organisation: Paebbels
39+
directory: tests/Valid
40+
dry-run: true
41+
42+
- name: 📋 Verify output parameters
43+
uses: ./.github/actions/check-outputs
44+
with:
45+
synchronized: ${{ steps.synchronize.outputs.synchronized }}
46+
skipped: ${{ steps.synchronize.outputs.skipped }}
47+
errors: ${{ steps.synchronize.outputs.errors }}
48+
# 1 branch of 'ghdl' + 1 branch of 'progit2' + 2 branches of 'itertree'
49+
expected-synchronized: 4
50+
# 1 commented out organisation + 1 commented out repository
51+
expected-skipped: 2
52+
expected-errors: 0
53+
54+
ErrorHandling:
55+
name: 🐧 Error handling with an invalid configuration
56+
runs-on: ubuntu-26.04
57+
58+
steps:
59+
- name: ⏬ Checkout repository to use the local action
60+
uses: actions/checkout@v7
61+
62+
- name: 🔄 Synchronize forked repositories
63+
id: synchronize
64+
uses: ./
65+
with:
66+
github-token: ${{ github.token }}
67+
target-organisation: Paebbels
68+
directory: tests/Invalid
69+
dry-run: true
70+
fail-on-error: false
71+
72+
- name: 📋 Verify output parameters
73+
uses: ./.github/actions/check-outputs
74+
with:
75+
synchronized: ${{ steps.synchronize.outputs.synchronized }}
76+
skipped: ${{ steps.synchronize.outputs.skipped }}
77+
errors: ${{ steps.synchronize.outputs.errors }}
78+
expected-synchronized: 1
79+
expected-skipped: 0
80+
# 1 missing 'Missing.repos' + 4 malformed lines in 'ghdl.repos'
81+
expected-errors: 5
82+
83+
FailOnError:
84+
name: 🐧 Counted errors let the action fail
85+
runs-on: ubuntu-26.04
86+
87+
steps:
88+
- name: ⏬ Checkout repository to use the local action
89+
uses: actions/checkout@v7
90+
91+
- name: 🔄 Synchronize forked repositories
92+
id: synchronize
93+
continue-on-error: true
94+
uses: ./
95+
with:
96+
github-token: ${{ github.token }}
97+
target-organisation: Paebbels
98+
directory: tests/Invalid
99+
dry-run: true
100+
101+
- name: 📋 Verify the action failed
102+
shell: bash
103+
env:
104+
OUTCOME: ${{ steps.synchronize.outcome }}
105+
run: |
106+
# 📋 Verify the action failed
107+
set +e
108+
109+
ANSI_LIGHT_RED=$'\x1b[91m'
110+
ANSI_LIGHT_GREEN=$'\x1b[92m'
111+
ANSI_NOCOLOR=$'\x1b[0m'
112+
113+
printf "%s" "Checking the action's outcome ... "
114+
if [[ "${OUTCOME}" == "failure" ]]; then
115+
printf "%s\n" "${ANSI_LIGHT_GREEN}[PASSED]${ANSI_NOCOLOR} (failure)"
116+
else
117+
printf "%s\n" "${ANSI_LIGHT_RED}[FAILED]${ANSI_NOCOLOR} (expected 'failure', got '${OUTCOME}')"
118+
printf "::error title=%s::%s\n" "FailOnError" "The action's outcome is '${OUTCOME}', but 'failure' was expected."
119+
exit 1
120+
fi

‎LICENSE.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# The MIT License (MIT)
2+
3+
Copyright © 2024-2026 Patrick Lehmann
4+
Copyright © 2026 The pyTooling Authors
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7+
documentation files (the “Software”), to deal in the Software without restriction, including without limitation the
8+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
9+
persons to whom the Software is furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
12+
Software.
13+
14+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
15+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

0 commit comments

Comments
 (0)