diff --git a/did/plugins/github.py b/did/plugins/github.py index f6f85cc0..e269df1c 100644 --- a/did/plugins/github.py +++ b/did/plugins/github.py @@ -9,6 +9,19 @@ token = login = +Optionally the search query can be limited to repositories owned +by the given user or organization. You can also use the full name +of the project to only search in the given repository:: + + user = + org = + repo = + +Multiple users, organization or repositories can be searched as +well. Use ``,`` as the separator, for example:: + + org = one,two,three + The authentication token is optional. However, unauthenticated queries are limited. For more details see `GitHub API`__ docs. Use ``login`` to override the default email address for searching. @@ -45,7 +58,7 @@ class GitHub(object): """ GitHub Investigator """ - def __init__(self, url, token): + def __init__(self, url, token=None, user=None, org=None, repo=None): """ Initialize url and headers """ self.url = url.rstrip("/") if token is not None: @@ -53,12 +66,22 @@ def __init__(self, url, token): else: self.headers = {} - self.token = token + # Prepare the org, user, repo filter + def condition(key: str, names: str) -> list[str]: + """ Prepare one or more conditions for given key & names """ + if not names: + return [] + return [f"+{key}:{name}" for name in re.split(r"\s*,\s*", names)] + + self.filter = "".join( + condition("user", user) + + condition("org", org) + + condition("repo", repo)) def search(self, query): """ Perform GitHub query """ result = [] - url = self.url + "/" + query + f"&per_page={PER_PAGE}" + url = self.url + "/" + query + self.filter + f"&per_page={PER_PAGE}" while True: # Fetch the query @@ -255,15 +278,23 @@ class GitHubStats(StatsGroup): def __init__(self, option, name=None, parent=None, user=None): StatsGroup.__init__(self, option, name, parent, user) config = dict(Config().section(option)) + # Check server url try: self.url = config["url"] except KeyError: raise ReportError( "No github url set in the [{0}] section".format(option)) + # Check authorization token self.token = get_token(config) - self.github = GitHub(self.url, self.token) + self.github = GitHub( + url=self.url, + token=self.token, + org=config.get("org"), + user=config.get("user"), + repo=config.get("repo")) + # Create the list of stats self.stats = [ IssuesCreated( diff --git a/plans/main.fmf b/plans/main.fmf new file mode 100644 index 00000000..855940de --- /dev/null +++ b/plans/main.fmf @@ -0,0 +1,18 @@ +discover: + how: fmf +provision: + how: local +execute: + how: tmt + +/basic: + summary: + Basic functionality + discover+: + filter: "tier:0" + +/plugins: + summary: + Plugin features + discover+: + filter: "tier:1" diff --git a/plans/smoke.fmf b/plans/smoke.fmf deleted file mode 100644 index 0bd2f54f..00000000 --- a/plans/smoke.fmf +++ /dev/null @@ -1,8 +0,0 @@ -summary: - Basic smoke test -discover: - how: fmf -provision: - how: local -execute: - how: tmt diff --git a/tests/docs/main.fmf b/tests/basic/docs/main.fmf similarity index 92% rename from tests/docs/main.fmf rename to tests/basic/docs/main.fmf index 2d4af28f..75600124 100644 --- a/tests/docs/main.fmf +++ b/tests/basic/docs/main.fmf @@ -3,3 +3,4 @@ summary: description: Create a minimal config file. Check help message and man page. +tag: basic diff --git a/tests/docs/test.sh b/tests/basic/docs/test.sh similarity index 100% rename from tests/docs/test.sh rename to tests/basic/docs/test.sh diff --git a/tests/basic/main.fmf b/tests/basic/main.fmf new file mode 100644 index 00000000..3f36070f --- /dev/null +++ b/tests/basic/main.fmf @@ -0,0 +1 @@ +tier: 0 diff --git a/tests/smoke/main.fmf b/tests/basic/smoke/main.fmf similarity index 78% rename from tests/smoke/main.fmf rename to tests/basic/smoke/main.fmf index fadd74c1..4069541f 100644 --- a/tests/smoke/main.fmf +++ b/tests/basic/smoke/main.fmf @@ -1 +1,2 @@ summary: Basic smoke test against github +tag: basic diff --git a/tests/smoke/test.sh b/tests/basic/smoke/test.sh similarity index 100% rename from tests/smoke/test.sh rename to tests/basic/smoke/test.sh diff --git a/tests/github/config-default.ini b/tests/github/config-default.ini new file mode 100644 index 00000000..d433ccd5 --- /dev/null +++ b/tests/github/config-default.ini @@ -0,0 +1,7 @@ +[general] +email = "Petr Šplíchal" + +[gh] +type = github +url = https://api.github.com/ +login = psss diff --git a/tests/github/config-more.ini b/tests/github/config-more.ini new file mode 100644 index 00000000..e1a8badb --- /dev/null +++ b/tests/github/config-more.ini @@ -0,0 +1,10 @@ +[general] +email = "Petr Šplíchal" + +[gh] +type = github +url = https://api.github.com/ +login = psss + +# Limit to multiple organizations +org = teemtee,packit diff --git a/tests/github/config-org.ini b/tests/github/config-org.ini new file mode 100644 index 00000000..adb29b03 --- /dev/null +++ b/tests/github/config-org.ini @@ -0,0 +1,10 @@ +[general] +email = "Petr Šplíchal" + +[gh] +type = github +url = https://api.github.com/ +login = psss + +# Limit to issues & pull request under the 'teemtee' organization +org = teemtee diff --git a/tests/github/config-repo.ini b/tests/github/config-repo.ini new file mode 100644 index 00000000..3884a65c --- /dev/null +++ b/tests/github/config-repo.ini @@ -0,0 +1,10 @@ +[general] +email = "Petr Šplíchal" + +[gh] +type = github +url = https://api.github.com/ +login = psss + +# Limit to issues & pull request under the 'teemtee/fmf' repository +repo = teemtee/fmf diff --git a/tests/github/config-user.ini b/tests/github/config-user.ini new file mode 100644 index 00000000..efdbdd47 --- /dev/null +++ b/tests/github/config-user.ini @@ -0,0 +1,10 @@ +[general] +email = "Petr Šplíchal" + +[gh] +type = github +url = https://api.github.com/ +login = psss + +# Limit to issues & pull request under user 'psss' +user = psss diff --git a/tests/github/help.sh b/tests/github/help.sh new file mode 100755 index 00000000..af7a8e35 --- /dev/null +++ b/tests/github/help.sh @@ -0,0 +1,14 @@ +#!/bin/bash +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +rlJournalStart + rlPhaseStartTest "Help" + rlRun -s "did --config ./config-default.ini --help" + rlAssertGrep "GitHub work" $rlRun_LOG + for what in issues pull-requests; do + for action in created commented closed; do + rlAssertGrep "--gh-$what-$action" $rlRun_LOG + done + done + rlPhaseEnd +rlJournalEnd diff --git a/tests/github/issues.sh b/tests/github/issues.sh new file mode 100755 index 00000000..7653d54b --- /dev/null +++ b/tests/github/issues.sh @@ -0,0 +1,86 @@ +#!/bin/bash +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +YEAR_2021="--since 2021-01-01 --until 2021-12-31" +YEAR_2022="--since 2022-01-01 --until 2022-12-31" +YEAR_2023="--since 2023-01-01 --until 2023-12-31" + +rlJournalStart + + # Issues Created + + rlPhaseStartTest "Issues Created" + rlRun -s "did --config ./config-default.ini --gh-issues-created $YEAR_2022" + rlAssertGrep "Issues created on gh: 31$" $rlRun_LOG + rlAssertGrep "teemtee/tmt#1737 - Introduce a new step for cleanup tasks" $rlRun_LOG + rlAssertGrep "teemtee/fmf#149 - Checkout of the default branch fails" $rlRun_LOG + rlAssertGrep "packit/packit-service#1645 - Manually trigger internal jobs" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Issues Created (org:teemtee)" + rlRun -s "did --config ./config-org.ini --gh-issues-created $YEAR_2022" + rlAssertGrep "Issues created on gh: 30$" $rlRun_LOG + rlAssertGrep "teemtee/tmt#1737 - Introduce a new step for cleanup tasks" $rlRun_LOG + rlAssertGrep "teemtee/fmf#149 - Checkout of the default branch fails" $rlRun_LOG + rlAssertNotGrep "packit/packit-service#1645 - Manually trigger internal jobs" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Issues Created (org:teemtee,packit)" + rlRun -s "did --config ./config-more.ini --gh-issues-created $YEAR_2023" + rlAssertGrep "Issues created on gh: 33$" $rlRun_LOG + rlAssertGrep "teemtee/tmt#2493 - Implement retry functionality" $rlRun_LOG + rlAssertGrep "packit/packit#1989 - Mention branch name" $rlRun_LOG + rlAssertNotGrep "readthedocs/sphinx_rtd_theme#1525 - Left menu" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Issues Created (repo:teemtee/fmf)" + rlRun -s "did --config ./config-repo.ini --gh-issues-created $YEAR_2022" + rlAssertGrep "Issues created on gh: 2$" $rlRun_LOG + rlAssertNotGrep "teemtee/tmt#1737 - Introduce a new step for cleanup tasks" $rlRun_LOG + rlAssertGrep "teemtee/fmf#149 - Checkout of the default branch fails" $rlRun_LOG + rlAssertNotGrep "packit/packit-service#1645 - Manually trigger internal jobs" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Issues Created (user:psss)" + rlRun -s "did --config ./config-user.ini --gh-issues-created $YEAR_2021" + rlAssertGrep "Issues created on gh: 1$" $rlRun_LOG + rlAssertGrep "psss/did#247 - Implement pagination for the GitHub plugin" $rlRun_LOG + rlAssertNotGrep "packit/packit#1386 - Allow to disable web access" $rlRun_LOG + rlAssertNotGrep "teemtee/tmt#910 - Shall we introduce a uuid for tests?" $rlRun_LOG + rlPhaseEnd + + # Issues Closed + + rlPhaseStartTest "Issues Closed" + rlRun -s "did --config ./config-default.ini --gh-issues-closed $YEAR_2022" + rlAssertGrep "Issues closed on gh: 17$" $rlRun_LOG + rlAssertGrep "teemtee/fmf#014 - Define a way how to undefine an attribute" $rlRun_LOG + rlAssertGrep "teemtee/tmt#991 - Incompatible environment variable name" $rlRun_LOG + rlAssertGrep "psss/did#269 - Invalid plugin type 'google'" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Issues Closed (org:teemtee)" + rlRun -s "did --config ./config-org.ini --gh-issues-closed $YEAR_2022" + rlAssertGrep "Issues closed on gh: 15$" $rlRun_LOG + rlAssertGrep "teemtee/fmf#014 - Define a way how to undefine an attribute" $rlRun_LOG + rlAssertGrep "teemtee/tmt#991 - Incompatible environment variable name" $rlRun_LOG + rlAssertNotGrep "psss/did#269 - Invalid plugin type 'google'" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Issues Closed (repo:teemtee/fmf)" + rlRun -s "did --config ./config-repo.ini --gh-issues-closed $YEAR_2022" + rlAssertGrep "Issues closed on gh: 3$" $rlRun_LOG + rlAssertGrep "teemtee/fmf#014 - Define a way how to undefine an attribute" $rlRun_LOG + rlAssertNotGrep "teemtee/tmt#991 - Incompatible environment variable name" $rlRun_LOG + rlAssertNotGrep "psss/did#269 - Invalid plugin type 'google'" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Issues Closed (user:psss)" + rlRun -s "did --config ./config-user.ini --gh-issues-closed $YEAR_2022" + rlAssertGrep "Issues closed on gh: 1$" $rlRun_LOG + rlAssertNotGrep "teemtee/fmf#014 - Define a way how to undefine an attribute" $rlRun_LOG + rlAssertNotGrep "teemtee/tmt#991 - Incompatible environment variable name" $rlRun_LOG + rlAssertGrep "psss/did#269 - Invalid plugin type 'google'" $rlRun_LOG + rlPhaseEnd + +rlJournalEnd diff --git a/tests/github/main.fmf b/tests/github/main.fmf new file mode 100644 index 00000000..8b6f21f3 --- /dev/null +++ b/tests/github/main.fmf @@ -0,0 +1,11 @@ +/help: + summary: Check the help message and option sanity + test: ./help.sh + +/pulls: + summary: Verify pull request stats + test: ./pulls.sh + +/issues: + summary: Verify issue stats + test: ./issues.sh diff --git a/tests/github/pulls.sh b/tests/github/pulls.sh new file mode 100755 index 00000000..2d984730 --- /dev/null +++ b/tests/github/pulls.sh @@ -0,0 +1,108 @@ +#!/bin/bash +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +YEAR_2022="--since 2022-01-01 --until 2022-12-31" +YEAR_2021="--since 2021-01-01 --until 2021-12-31" + +rlJournalStart + + # Pull Requests Created + + rlPhaseStartTest "Pull Requests Created" + rlRun -s "did --config ./config-default.ini --gh-pull-requests-created $YEAR_2022" + rlAssertGrep "Pull requests created on gh: 94$" $rlRun_LOG + rlAssertGrep "teemtee/tmt#1750 - Include the new web link in verbose" $rlRun_LOG + rlAssertGrep "teemtee/fmf#170 - Implement a directive for disabling inheritance" $rlRun_LOG + rlAssertGrep "teemtee/try#002 - Check logs for test with a hash sign in" $rlRun_LOG + rlAssertGrep "psss/did#275 - Speed up local testing" $rlRun_LOG + rlAssertGrep "psss/python-nitrate#039 - Enable basic sanity" $rlRun_LOG + rlAssertGrep "packit/packit.dev#399 - Update \`tmt\` examples" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Pull Requests Created (org:teemtee)" + rlRun -s "did --config ./config-org.ini --gh-pull-requests-created $YEAR_2022" + rlAssertGrep "Pull requests created on gh: 85$" $rlRun_LOG + rlAssertGrep "teemtee/tmt#1750 - Include the new web link in verbose" $rlRun_LOG + rlAssertGrep "teemtee/fmf#170 - Implement a directive for disabling inheritance" $rlRun_LOG + rlAssertGrep "teemtee/try#002 - Check logs for test with a hash sign in" $rlRun_LOG + rlAssertNotGrep "psss/did#275 - Speed up local testing" $rlRun_LOG + rlAssertNotGrep "psss/python-nitrate#039 - Enable basic sanity" $rlRun_LOG + rlAssertNotGrep "packit/packit.dev#399 - Update \`tmt\` examples" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Pull Requests Created (org:teemtee,packit)" + rlRun -s "did --config ./config-more.ini --gh-pull-requests-created $YEAR_2022" + rlAssertGrep "Pull requests created on gh: 86$" $rlRun_LOG + rlAssertGrep "teemtee/tmt#1750 - Include the new web link in verbose" $rlRun_LOG + rlAssertGrep "teemtee/fmf#170 - Implement a directive for disabling inheritance" $rlRun_LOG + rlAssertGrep "teemtee/try#002 - Check logs for test with a hash sign in" $rlRun_LOG + rlAssertNotGrep "psss/did#275 - Speed up local testing" $rlRun_LOG + rlAssertNotGrep "psss/python-nitrate#039 - Enable basic sanity" $rlRun_LOG + rlAssertGrep "packit/packit.dev#399 - Update \`tmt\` examples" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Pull Requests Created (repo:teemtee/fmf)" + rlRun -s "did --config ./config-repo.ini --gh-pull-requests-created $YEAR_2022" + rlAssertGrep "Pull requests created on gh: 7$" $rlRun_LOG + rlAssertNotGrep "teemtee/tmt#1750 - Include the new web link in verbose" $rlRun_LOG + rlAssertGrep "teemtee/fmf#170 - Implement a directive for disabling inheritance" $rlRun_LOG + rlAssertNotGrep "teemtee/try#002 - Check logs for test with a hash sign in" $rlRun_LOG + rlAssertNotGrep "psss/did#275 - Speed up local testing" $rlRun_LOG + rlAssertNotGrep "psss/python-nitrate#039 - Enable basic sanity" $rlRun_LOG + rlAssertNotGrep "packit/packit.dev#399 - Update \`tmt\` examples" $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Pull Requests Created (user:psss)" + rlRun -s "did --config ./config-user.ini --gh-pull-requests-created $YEAR_2022" + rlAssertGrep "Pull requests created on gh: 7$" $rlRun_LOG + rlAssertNotGrep "teemtee/tmt#1750 - Include the new web link in verbose" $rlRun_LOG + rlAssertNotGrep "teemtee/fmf#170 - Implement a directive for disabling inheritance" $rlRun_LOG + rlAssertNotGrep "teemtee/try#002 - Check logs for test with a hash sign in" $rlRun_LOG + rlAssertGrep "psss/did#275 - Speed up local testing" $rlRun_LOG + rlAssertGrep "psss/python-nitrate#039 - Enable basic sanity" $rlRun_LOG + rlAssertNotGrep "packit/packit.dev#399 - Update \`tmt\` examples" $rlRun_LOG + rlPhaseEnd + + # Pull Requests Closed + + rlPhaseStartTest "Pull Requests Closed" + rlRun -s "did --config ./config-default.ini --gh-pull-requests-closed $YEAR_2022" + rlAssertGrep "Pull requests closed on gh: 315$" $rlRun_LOG + rlAssertGrep "psss/did#272 - Koji plugin" $rlRun_LOG + rlAssertGrep "psss/python-nitrate#038 - Properly handle string" $rlRun_LOG + rlAssertGrep "teemtee/fmf#177 - Shallow git clone if no reference" $rlRun_LOG + rlAssertGrep "teemtee/tmt#1050 - Run commands via bash" $rlRun_LOG + rlAssertGrep "teemtee/upgrade#006 - Store the old packages " $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Pull Requests Closed (org:teemtee)" + rlRun -s "did --config ./config-org.ini --gh-pull-requests-closed $YEAR_2022" + rlAssertGrep "Pull requests closed on gh: 305$" $rlRun_LOG + rlAssertNotGrep "psss/did#272 - Koji plugin" $rlRun_LOG + rlAssertNotGrep "psss/python-nitrate#038 - Properly handle string" $rlRun_LOG + rlAssertGrep "teemtee/fmf#177 - Shallow git clone if no reference" $rlRun_LOG + rlAssertGrep "teemtee/tmt#1050 - Run commands via bash" $rlRun_LOG + rlAssertGrep "teemtee/upgrade#006 - Store the old packages " $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Pull Requests Closed (repo:teemtee/fmf)" + rlRun -s "did --config ./config-repo.ini --gh-pull-requests-closed $YEAR_2022" + rlAssertGrep "Pull requests closed on gh: 13$" $rlRun_LOG + rlAssertNotGrep "psss/did#272 - Koji plugin" $rlRun_LOG + rlAssertNotGrep "psss/python-nitrate#038 - Properly handle string" $rlRun_LOG + rlAssertGrep "teemtee/fmf#177 - Shallow git clone if no reference" $rlRun_LOG + rlAssertNotGrep "teemtee/tmt#1050 - Run commands via bash" $rlRun_LOG + rlAssertNotGrep "teemtee/upgrade#006 - Store the old packages " $rlRun_LOG + rlPhaseEnd + + rlPhaseStartTest "Pull Requests Closed (user:psss)" + rlRun -s "did --config ./config-user.ini --gh-pull-requests-closed $YEAR_2022" + rlAssertGrep "Pull requests closed on gh: 10$" $rlRun_LOG + rlAssertGrep "psss/did#272 - Koji plugin" $rlRun_LOG + rlAssertGrep "psss/python-nitrate#038 - Properly handle string" $rlRun_LOG + rlAssertNotGrep "teemtee/fmf#177 - Shallow git clone if no reference" $rlRun_LOG + rlAssertNotGrep "teemtee/tmt#1050 - Run commands via bash" $rlRun_LOG + rlAssertNotGrep "teemtee/upgrade#006 - Store the old packages " $rlRun_LOG + rlPhaseEnd + +rlJournalEnd diff --git a/tests/main.fmf b/tests/main.fmf index 9b544fa9..f2445c56 100644 --- a/tests/main.fmf +++ b/tests/main.fmf @@ -1,3 +1,4 @@ test: ./test.sh framework: beakerlib require: did +tier: 1