-
Notifications
You must be signed in to change notification settings - Fork 183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add support for new staging api. (command osc ps) #631
base: master
Are you sure you want to change the base?
Conversation
6963bda
to
14ade36
Compare
@marcus-h: This is a beta version of the new staging command. Can we please merge this, so that the release engineers have something to test and do the refactoring aftwerwards? Thanks and cheers, |
Just a very, very quick and high-level review:
On 2019-09-12 03:17:13 -0700, Marco Strigl wrote:
diff --git a/osc/commandline.py b/osc/commandline.py
index 2eea1e8e..3e1e538e 100644
--- a/osc/commandline.py
+++ b/osc/commandline.py
@@ -9245,6 +9245,225 @@ def do_comment(self, subcmd, opts, *args):
result = delete_comment(apiurl, args[1])
print(result)
+ @cmdln.option('-g', '--group',
+ help='group', metavar='GROUP')
+ @cmdln.option('-s', '--staging',
+ help='staging project', metavar='STAGING')
Hmm what about
@cmdln.option('-s', '--staging', action='append', default=[], ...)
Then, we could use "-s foo -s bar -s xyz" instead of "-s foo,bar,xyz".
+ @cmdln.option('-r', '--requests',
+ help='request(s)', metavar='REQUESTS')
As above.
+ @cmdln.option('-v', '--verbose', action='store_true',
+ help='print extra information')
+ @cmdln.alias('ps')
+ def do_projectstaging(self, subcmd, opts, *args):
We could do
def do_projectstaging(self, subcmd, opts, cmd, *args):
to get rid of the initial args[0] handling (use cmd instead).
+ """${cmd_name}: Handle staging
+
+ Create, Add, Delete staging projects
+ Add requests to staging
+
+ This can be issued within a project directory or with the
+ project as the first argument.
+
+ If you operate on a staging project or with requests the
+ staging project has to be given with -s and the request has
+ to be given with -r
+
+ You can add multiple requests / stagings comma serparated.
Typo: separated
+ For example:
+ -s myprj:Staging:A, myprj:Staging:B
+ -r 1234, 12345
Both arguments should be quoted "-s myprj:Staging:A, myprj:Staging:B".
Note that the whitespace would be part of the project name (I'm not sure
if a user would expect this). Maybe it is a bit more "natural" to
specify the option several times (see above).
+
+ osc ps
+
+ For example:
+ linux:~/myproject/> osc ps create
+ or
+ osc ps create myproject
+
+ subcommands:
+ create Create a staging workflow for the project
+ add Add a staging project to a staging workflow
+ using -s <staging project>
+ list List all staging project associated to this
+ workflow
+ show Show information to one specific staging project
+ using -s <staging project>
+ delete
+ Delete complete staging workflow from project
+ accept
+ Accept the staging given with -s. All requests in
+ the staging project will be accepted
+
+
+ osc ps request
+
+ subcommands:
+ add Add requests given with -r to a staging given with -s
+ delete Delete requests given with -r from a staging given with -s
+ list List all requests in a staging given with -s
+
+
+
+ Example Workflow:
+ osc ps create myprj -g group_for_review
+ osc ps add myprj -s myprj:Staging:A
+ osc ps request add myprj -s myprj:Staging:A -r 1234, 4567
+ osc ps request delete myprj -s myprj:Staging:A -r 1234
+ osc ps request list -s myprj:Staging:A
+ osc ps accept myprj -s myprj:Staging:A
+ osc ps show myprj -s myprj:Staging:A
+
+
+ """
+
+ args = slash_split(args)
+
+ subcmdlist = ['create', 'add', 'delete', 'show', 'request', 'rq', 'list', 'accept']
+ rqcmdlist = ['add', 'delete', 'list']
+
+ if not args or args[0] not in subcmdlist:
+ raise oscerr.WrongArgs('Unknown operation. Choose one of %s.' \
+ % ', '.join(subcmdlist))
+
+ has_staging_opt = None
+ if opts.staging:
+ staging_list = []
+ st = opts.staging.split(',')
+ staging_list.extend(st)
What about
staging_list = opts.staging.split(',')
+ has_staging_opt = True
+
Hmm instead of has_staging_opt, we could use staging_list (just define
"staging_list = []" before the if statement).
<SNIP>
+ if cmd == 'create':
+ if not opts.group:
+ raise oscerr.WrongArgs('Please specify a group for the staging with -g <groupname>')
+ ret = ps.create(project, opts.group)
+ root = ET.fromstring(ret.read())
+ summary = root.find('summary')
+ if summary.text == 'Ok':
+ print('Staging workflow for %s created!' % project)
+ create_sub = input('Do you want to automatically create staging projects? [Y|n]: ') or 'y'
raw_input.
<SNIP>
+ elif cmd == 'delete':
+ res = ps.list(project)
+ root = ET.parse(res).getroot()
+ staging_list = []
+ for stage in root.findall('staging_project'):
+ staging_list.append(stage.get('name'))
+ ret = ps.delete(project)
+ if ret:
+ print('Staging workflow for %s deleted!' % project)
+ if len(staging_list) >= 1:
Hmm simply: if staging_list:
+ print('Staging projects:')
+ for stage in staging_list:
+ print(stage)
+ delete_subs = input('Do you want to delete all staging projects for this workflow? [Y|n]: ') or 'y'
raw_input
+ if delete_subs in ['y', 'Y']:
+ delete_msg = 'Deleted by staging workflow'
+ for stage in staging_list:
+ delete_project(apiurl, stage, msg=delete_msg)
+ elif cmd == 'show':
+ for st in opts.staging.split(','):
Minor: Iterate over staging_list?
<SNIP>
+ elif cmd in ['rq', 'request']:
+ if rqcmd == 'add':
+ rqlist = []
+ rq = opts.requests.split(',')
+ rqlist.extend(rq)
+ ret = ps.add_request(project, staging_list[0], rqlist)
+ root = ET.fromstring(ret.read())
+ summary = root.find('summary')
+ if summary.text == 'Ok':
+ for rq in rqlist:
+ print('Request %s added to %s' % (rq, staging_list[0]))
Hmm what about the other potential items in staging_list? (Note: I have
no clue about the staging workflow... so the code is probably right...).
+ elif rqcmd == 'list':
+ for st in staging_list:
+ print('Requests in %s', st)
+ ret = ps.list_requests(project, st)
+ root = ET.fromstring(ret.read())
+ for rq in root.findall('request'):
+ rq_id = rq.get('id')
+ creator = rq.get('creator')
+ state = rq.get('state')
+ pkg = rq.get('package')
+ print('%s\t\t%s\t\t%s\t\t%s' % (rq_id, creator, state, pkg))
+ elif rqcmd == 'delete':
+ rqlist = []
+ rq = opts.requests.split(',')
+ rqlist.extend(rq)
+ ret = ps.delete_requests(project, staging_list[0], rqlist)
+ root = ET.fromstring(ret.read())
+ summary = root.find('summary')
+ if summary.text == 'Ok':
+ for rq in rqlist:
+ print('Request %s deleted from %s' % (rq, staging_list[0]))
Same question as in the "rqcmd == 'add'" case.
diff --git a/osc/core.py b/osc/core.py
index b7d097db..2500da99 100644
--- a/osc/core.py
+++ b/osc/core.py
@@ -484,6 +484,79 @@ def execute(self, dir, callmode = None, singleservice = None, verbose = None):
return 0
+class ProjectStaging:
+ """ProjectStaging actions and information
+ """
<SNIP>
+ def list(self, project):
+ try:
+ u = makeurl(self.apiurl, ['staging', project, 'staging_projects'])
+ f = http_GET(u)
+ except HTTPError as e:
+ if e.code == 400:
+ return None
Hmm in which case does the API return a 400?
+ raise e
+ return f
+
+ def add(self, project, staging_list):
+ stagingxml = "<workflow>"
+ for stage in staging_list:
+ stagingxml += ("<staging_project>%s</staging_project>" % stage)
Unnecessary parentheses.
|
On 2019-09-12 03:20:43 -0700, Marco Strigl wrote:
@marcus-h: This is a beta version of the new staging command. Can we please merge this, so that the release engineers have something to test and do the refactoring aftwerwards?
Hmm I somehow fear that this will eventually result in a similar
"bloated" command (code-wise) as do_request:/
If a refactoring would "block" people, I'm fine with merging it [1],
but let's at least do the "input" -> "raw_input" change and let's
try to "fix" the UI ("-s foo,bar" vs. "-s foo -s bar").
[1] at least I have no objections from a high-level POV
|
14ade36
to
ecb82cc
Compare
I have done all your requested changes. You are right. Setting the
option multiple times is better.
* switched to raw_input
* used cmd in function call
*
On 9/12/19 1:23 PM, Marcus Hüwe wrote:
Just a very, very quick and high-level review:
<SNIP>
Hmm what about the other potential items in staging_list? (Note: I have
no clue about the staging workflow... so the code is probably right...).
> + elif rqcmd == 'list':
> + for st in staging_list:
> + print('Requests in %s', st)
> + ret = ps.list_requests(project, st)
> + root = ET.fromstring(ret.read())
> + for rq in root.findall('request'):
> + rq_id = rq.get('id')
> + creator = rq.get('creator')
> + state = rq.get('state')
> + pkg = rq.get('package')
> + print('%s\t\t%s\t\t%s\t\t%s' % (rq_id, creator, state, pkg))
> + elif rqcmd == 'delete':
> + rqlist = []
> + rq = opts.requests.split(',')
> + rqlist.extend(rq)
> + ret = ps.delete_requests(project, staging_list[0], rqlist)
> + root = ET.fromstring(ret.read())
> + summary = root.find('summary')
> + if summary.text == 'Ok':
> + for rq in rqlist:
> + print('Request %s deleted from %s' % (rq, staging_list[0]))
Same question as in the "rqcmd == 'add'" case.
Becasue a request can only be added to one staging. Also it can only be deleted from one staging.
> diff --git a/osc/core.py b/osc/core.py
> index b7d097db..2500da99 100644
> --- a/osc/core.py
> +++ b/osc/core.py
> @@ -484,6 +484,79 @@ def execute(self, dir, callmode = None, singleservice = None, verbose = None):
>
> return 0
>
> +class ProjectStaging:
> + """ProjectStaging actions and information
> + """
<SNIP>
> + def list(self, project):
> + try:
> + u = makeurl(self.apiurl, ['staging', project, 'staging_projects'])
> + f = http_GET(u)
> + except HTTPError as e:
> + if e.code == 400:
> + return None
Hmm in which case does the API return a 400?
If you want to get a list of staging projects for a staging project that
is not created. There is also a bug for this in open-build-service:
openSUSE/open-build-service#8298
> + raise e
> + return f
> +
> + def add(self, project, staging_list):
> + stagingxml = "<workflow>"
> + for stage in staging_list:
> + stagingxml += ("<staging_project>%s</staging_project>" % stage)
Unnecessary parentheses.
removed.
|
ecb82cc
to
a83d1e8
Compare
|
Because the http_request to remove a sr is:
and expects a xml with the requests to delete. osc does not know which request is in I would have to iterate over all stagings and search for the request to build the url |
So you let the user do it instead? |
But if that's the API, the API sucks - easy as that :) |
Just explaining why I did it this way :-) I will implement that osc determines the staging for the request when no staging is given with -s |
I think the API should handle this, really. |
Create, Add, Delete staging projects Add requests to staging It can be issued within a project directory or with the project as the first argument. If you operate on a staging project or with requests the staging project has to be given with -s and the request has to be given with -r You can add multiple requests / stagings. For example: "-s myprj:Staging:A -s myprj:Staging:B" "-r 1234 -r 12345" osc ps For example: linux:~/myproject/> osc ps create or osc ps create myproject
a83d1e8
to
96e8c9c
Compare
fixed |
@lethliel whatever you need, please file issues, we want to make this work for you 🤠 |
I put a work around in osc. osc now determines in which staging project the request is, when omitting the -s option |
I'm not sure, but why asking the user to provide the staging workflow project, if it could be inferred from the staging project, why not use it? i.e:
|
How to retrieve the staging workflow for a project through API? |
Nothing is set in stone. The API is under development and should and will be adapted if necessary. The question should be always if the design make sense or not. Do you need an endpoint for that? Couldn't we solve it with one extra request?
|
The question is basically: does it make sense at all that the route is |
It is a good question.. I think we were following the rails convention and the route ended up like that.. we can file an issue for that. How should the osc command look like for you @coolo ? |
|
If in the server side we had something like |
I really see no point in typing the extra :Staging: - it's a convention we will stick to |
That's a requirement from our PO. The Staging projects are just projects. No special names or hierarchy (i.e sub-projects) |
Yeah, then just don't ask me. Because I can only tell you what users want not what POs want. |
right @coolo but thinking about the user point of view, would it make sense to have something like |
No, because in my world |
@lethliel I see some difference between the example workflows given my the i.e:
but what really works is:
|
As it is today, this command is broken. The XML format that we should send while staging a new request is similar with:
Today we are sending something like:
Please update it @lethliel |
This will be closed.. Nobody seems to be using it.. |
I think after 3 years, people that need it, just gave up of using |
We still want this... |
There is also a staging plugin in osc-relese-tools. But I guess this is for the old staging API? |
@hennevogel Then I will rebase and commit what I have so far.. So that the people can use it and report bugs ;-) |
This pull request has been in a draft state for quite some time. |
Since this new command has subcommands, it might be good to rewrite it to use the new code from #1285 once it gets merged. |
Create, Add, Delete staging projects
Add requests to staging
It can be issued within a project directory or with the
project as the first argument.
If you operate on a staging project or with requests the
staging project has to be given with
-s
and the request hasto be given with
-r
You can add multiple requests / stagings comma serparated.
For example:
osc ps
For example:
linux:~/myproject/> osc ps create
or
osc ps create myproject
STILL IN BETA
This fixes #583