Skip to content

Commit e679e1d

Browse files
committed
calculate_github_issue_for_commenting.py added (incomplete)
1 parent 2c0d3d7 commit e679e1d

File tree

3 files changed

+167
-73
lines changed

3 files changed

+167
-73
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from __future__ import annotations
16+
17+
import argparse
18+
import dataclasses
19+
import logging
20+
import sys
21+
import typing
22+
from typing import override
23+
24+
if typing.TYPE_CHECKING:
25+
from collections.abc import Sequence
26+
from typing import Never, TextIO
27+
28+
from _typeshed import SupportsWrite
29+
30+
type ExitCode = int
31+
32+
33+
def main(args: Sequence[str], stdout: TextIO, stderr: TextIO) -> ExitCode:
34+
try:
35+
parsed_args = parse_args(args[0], args[1:], stdout)
36+
except MyArgumentParser.Error as e:
37+
if e.exit_code != 0:
38+
print(f"ERROR: invalid command-line arguments: {e}", file=stderr)
39+
print("Run with --help for help", file=stderr)
40+
return e.exit_code
41+
42+
print(f"Successfully parsed arguments: {parsed_args!r}")
43+
return 0
44+
45+
46+
@dataclasses.dataclass(frozen=True)
47+
class GetIssueNumberCommand:
48+
github_ref: str
49+
github_event_name: str
50+
default_github_issue: int
51+
52+
53+
@dataclasses.dataclass(frozen=True)
54+
class ParsedArgs:
55+
log_level: int
56+
command: GetIssueNumberCommand
57+
58+
59+
class MyArgumentParser(argparse.ArgumentParser):
60+
def __init__(self, prog: str, stdout: SupportsWrite[str]) -> None:
61+
super().__init__(prog=prog, usage="%(prog)s <command> [options]")
62+
self.stdout = stdout
63+
64+
@override
65+
def exit(self, status: int = 0, message: str | None = None) -> Never:
66+
raise self.Error(exit_code=status, message=message)
67+
68+
@override
69+
def error(self, message: str) -> Never:
70+
self.exit(2, message)
71+
72+
@override
73+
def print_usage(self, file: SupportsWrite[str] | None = None) -> None:
74+
file = file if file is not None else self.stdout
75+
super().print_usage(file)
76+
77+
@override
78+
def print_help(self, file: SupportsWrite[str] | None = None) -> None:
79+
file = file if file is not None else self.stdout
80+
super().print_help(file)
81+
82+
class Error(Exception):
83+
def __init__(self, exit_code: ExitCode, message: str | None) -> None:
84+
super().__init__(message)
85+
self.exit_code = exit_code
86+
87+
88+
def parse_args(prog: str, args: Sequence[str], stdout: TextIO) -> ParsedArgs:
89+
arg_parser = MyArgumentParser(prog, stdout)
90+
parsed_args = arg_parser.parse_args(args)
91+
print(f"parsed_args: {parsed_args!r}")
92+
return ParsedArgs(
93+
log_level=logging.INFO,
94+
command=GetIssueNumberCommand(
95+
github_ref="sample_github_ref",
96+
github_event_name="sample_github_event_name",
97+
default_github_issue=123456,
98+
),
99+
)
100+
101+
102+
if __name__ == "__main__":
103+
try:
104+
exit_code = main(sys.argv, sys.stdout, sys.stderr)
105+
except KeyboardInterrupt:
106+
print("ERROR: application terminated by keyboard interrupt", file=sys.stderr)
107+
exit_code = 1
108+
109+
sys.exit(exit_code)

firebase-dataconnect/ci/notify_issue.py

Lines changed: 55 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -15,95 +15,77 @@
1515
from __future__ import annotations
1616

1717
import argparse
18-
import dataclasses
1918
import logging
19+
import re
2020
import sys
2121
import typing
22-
from typing import override
2322

2423
if typing.TYPE_CHECKING:
25-
from collections.abc import Sequence
26-
from typing import Never, TextIO
27-
2824
from _typeshed import SupportsWrite
2925

3026
type ExitCode = int
3127

3228

33-
def main(args: Sequence[str], stdout: TextIO, stderr: TextIO) -> ExitCode:
34-
try:
35-
parsed_args = parse_args(args[0], args[1:], stdout)
36-
except MyArgumentParser.Error as e:
37-
if e.exit_code != 0:
38-
print(f"ERROR: invalid command-line arguments: {e}", file=stderr)
39-
print("Run with --help for help", file=stderr)
40-
return e.exit_code
29+
def main() -> None:
30+
args = parse_args()
31+
logging.basicConfig(format="%(message)s", level=logging.INFO)
32+
run(args, sys.stdout)
33+
34+
35+
def run(args: ParsedArgs, stdout: SupportsWrite[str]) -> None:
36+
37+
# Determine the number of the pull request triggering this job, if any.
4138

42-
print(f"Successfully parsed arguments: {parsed_args!r}")
43-
return 0
4439

40+
def parse_github_ref(github_ref: str) -> int | None:
41+
logging.info("Checking the value of github_ref for a PR number: %s", args.github_ref)
42+
match = re.fullmatch("refs/pull/([0-9]+)/merge", args.github_ref)
43+
if not match:
44+
return None
4545

46-
@dataclasses.dataclass(frozen=True)
47-
class GetIssueNumberCommand:
46+
47+
48+
class ParsedArgs(typing.Protocol):
4849
github_ref: str
50+
github_repository: str
4951
github_event_name: str
50-
default_github_issue: int
51-
52-
53-
@dataclasses.dataclass(frozen=True)
54-
class ParsedArgs:
55-
log_level: int
56-
command: GetIssueNumberCommand
57-
58-
59-
class MyArgumentParser(argparse.ArgumentParser):
60-
def __init__(self, prog: str, stdout: SupportsWrite[str]) -> None:
61-
super().__init__(prog=prog, usage="%(prog)s <command> [options]")
62-
self.stdout = stdout
63-
64-
@override
65-
def exit(self, status: int = 0, message: str | None = None) -> Never:
66-
raise self.Error(exit_code=status, message=message)
67-
68-
@override
69-
def error(self, message: str) -> Never:
70-
self.exit(2, message)
71-
72-
@override
73-
def print_usage(self, file: SupportsWrite[str] | None = None) -> None:
74-
file = file if file is not None else self.stdout
75-
super().print_usage(file)
76-
77-
@override
78-
def print_help(self, file: SupportsWrite[str] | None = None) -> None:
79-
file = file if file is not None else self.stdout
80-
super().print_help(file)
81-
82-
class Error(Exception):
83-
def __init__(self, exit_code: ExitCode, message: str | None) -> None:
84-
super().__init__(message)
85-
self.exit_code = exit_code
86-
87-
88-
def parse_args(prog: str, args: Sequence[str], stdout: TextIO) -> ParsedArgs:
89-
arg_parser = MyArgumentParser(prog, stdout)
90-
parsed_args = arg_parser.parse_args(args)
91-
print(f"parsed_args: {parsed_args!r}")
92-
return ParsedArgs(
93-
log_level=logging.INFO,
94-
command=GetIssueNumberCommand(
95-
github_ref="sample_github_ref",
96-
github_event_name="sample_github_event_name",
97-
default_github_issue=123456,
98-
),
52+
pr_body_github_issue_key: str
53+
github_issue_for_scheduled_run: str
54+
55+
56+
def parse_args() -> ParsedArgs:
57+
arg_parser = argparse.ArgumentParser()
58+
arg_parser.add_argument(
59+
"--github-ref",
60+
required=True,
61+
help="The value of ${{ github.ref }} in the workflow",
62+
)
63+
arg_parser.add_argument(
64+
"--github-repository",
65+
required=True,
66+
help="The value of ${{ github.repository }} in the workflow",
67+
)
68+
arg_parser.add_argument(
69+
"--github-event-name",
70+
required=True,
71+
help="The value of ${{ github.event_name }} in the workflow",
72+
)
73+
arg_parser.add_argument(
74+
"--pr-body-github-issue-key",
75+
required=True,
76+
help="The string to search for in a Pull Request body to determine the GitHub Issue number "
77+
"for commenting. For example, if the value is 'foobar' then this script searched a PR "
78+
"body for a line of the form 'foobar=NNNN' where 'NNNN' is the GitHub issue number",
79+
)
80+
arg_parser.add_argument(
81+
"--github-issue-for-scheduled-run",
82+
required=True,
83+
help="The GitHub Issue number to use for commenting when --github-event-name is 'schedule'",
9984
)
10085

86+
parse_result = arg_parser.parse_args()
87+
return typing.cast("ParsedArgs", parse_result)
10188

102-
if __name__ == "__main__":
103-
try:
104-
exit_code = main(sys.argv, sys.stdout, sys.stderr)
105-
except KeyboardInterrupt:
106-
print("ERROR: application terminated by keyboard interrupt", file=sys.stderr)
107-
exit_code = 1
10889

109-
sys.exit(exit_code)
90+
if __name__ == "__main__":
91+
main()

firebase-dataconnect/ci/pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ indent-width = 2
1313
[tool.ruff.lint]
1414
select = ["ALL"]
1515
ignore = [
16+
"COM812", # missing-trailing-comma
1617
"D100", # Missing docstring in public module
1718
"D101", # Missing docstring in public class
19+
"D102", # Missing docstring in public method
1820
"D103", # Missing docstring in public function
1921
"D106", # Missing docstring in public nested class
2022
"D107", # Missing docstring in `__init__`
23+
"D203", # incorrect-blank-line-before-class
2124
"D211", # no-blank-line-before-class
2225
"D212", # multi-line-summary-second-line
2326
"T201", # print` found

0 commit comments

Comments
 (0)