Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
b31cd05f
Unverified
Commit
b31cd05f
authored
Feb 19, 2020
by
Patrick Steinhardt
Committed by
GitHub
Feb 19, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5372 from pks-t/pks/release-script
Release script
parents
1256b462
2ae45bc3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
175 additions
and
0 deletions
+175
-0
.editorconfig
+4
-0
script/release.py
+171
-0
No files found.
.editorconfig
View file @
b31cd05f
...
@@ -15,3 +15,7 @@ indent_size = 2
...
@@ -15,3 +15,7 @@ indent_size = 2
indent_style = space
indent_style = space
indent_size = 4
indent_size = 4
trim_trailing_whitespace = false
trim_trailing_whitespace = false
[*.py]
indent_style = space
indent_size = 4
script/release.py
0 → 100755
View file @
b31cd05f
#!/usr/bin/env python
from
collections
import
namedtuple
import
argparse
import
base64
import
copy
import
json
import
subprocess
import
sys
import
urllib.parse
import
urllib.request
import
urllib.error
class
Error
(
Exception
):
pass
class
Version
(
object
):
def
__init__
(
self
,
version
):
versions
=
version
.
split
(
sep
=
'.'
)
if
len
(
versions
)
<
2
or
len
(
versions
)
>
3
:
raise
Error
(
"Invalid version string '{}'"
.
format
(
version
))
self
.
major
=
int
(
versions
[
0
])
self
.
minor
=
int
(
versions
[
1
])
self
.
revision
=
int
(
versions
[
2
])
if
len
(
versions
)
==
3
else
0
def
__str__
(
self
):
return
'{}.{}.{}'
.
format
(
self
.
major
,
self
.
minor
,
self
.
revision
)
def
__eq__
(
self
,
other
):
return
self
.
major
==
other
.
major
and
self
.
minor
==
other
.
minor
and
self
.
revision
==
other
.
revision
def
verify_version
(
version
):
expected
=
{
'VERSION'
:
[
'"{}"'
.
format
(
version
),
None
],
'VER_MAJOR'
:
[
str
(
version
.
major
),
None
],
'VER_MINOR'
:
[
str
(
version
.
minor
),
None
],
'VER_REVISION'
:
[
str
(
version
.
revision
),
None
],
'VER_PATCH'
:
[
'0'
,
None
],
'SOVERSION'
:
[
'"{}.{}"'
.
format
(
version
.
major
,
version
.
minor
),
None
],
}
with
open
(
'include/git2/version.h'
)
as
f
:
lines
=
f
.
readlines
()
for
key
in
expected
.
keys
():
define
=
'#define LIBGIT2_{} '
.
format
(
key
)
for
line
in
lines
:
if
line
.
startswith
(
define
):
expected
[
key
][
1
]
=
line
[
len
(
define
):]
.
strip
()
break
else
:
raise
Error
(
"version.h: missing define for '{}'"
.
format
(
key
))
for
k
,
v
in
expected
.
items
():
if
v
[
0
]
!=
v
[
1
]:
raise
Error
(
"version.h: define '{}' does not match (got '{}', expected '{}')"
.
format
(
k
,
v
[
0
],
v
[
1
]))
def
generate_relnotes
(
tree
,
version
):
with
open
(
'docs/changelog.md'
)
as
f
:
lines
=
f
.
readlines
()
if
not
lines
[
0
]
.
startswith
(
'v'
):
raise
Error
(
"changelog.md: missing section for v{}"
.
format
(
version
))
try
:
v
=
Version
(
lines
[
0
][
1
:]
.
strip
())
except
:
raise
Error
(
"changelog.md: invalid version string {}"
.
format
(
lines
[
0
]
.
strip
()))
if
v
!=
version
:
raise
Error
(
"changelog.md: changelog version doesn't match (got {}, expected {})"
.
format
(
v
,
version
))
if
not
lines
[
1
]
.
startswith
(
'----'
):
raise
Error
(
"changelog.md: missing version header"
)
if
lines
[
2
]
!=
'
\n
'
:
raise
Error
(
"changelog.md: missing newline after version header"
)
for
i
,
line
in
enumerate
(
lines
[
3
:]):
if
not
line
.
startswith
(
'v'
):
continue
try
:
Version
(
line
[
1
:]
.
strip
())
break
except
:
continue
else
:
raise
Error
(
"changelog.md: cannot find section header of preceding release"
)
return
''
.
join
(
lines
[
3
:
i
+
3
])
.
strip
()
def
git
(
*
args
):
process
=
subprocess
.
run
([
'git'
,
*
args
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
if
process
.
returncode
!=
0
:
raise
Error
(
'Failed executing git {}: {}'
.
format
(
' '
.
join
(
args
),
process
.
stderr
.
decode
()))
return
process
.
stdout
def
post
(
url
,
data
,
contenttype
,
user
,
password
):
request
=
urllib
.
request
.
Request
(
url
,
data
=
data
)
request
.
add_header
(
'Accept'
,
'application/json'
)
request
.
add_header
(
'Content-Type'
,
contenttype
)
request
.
add_header
(
'Content-Length'
,
len
(
data
))
request
.
add_header
(
'Authorization'
,
'Basic '
+
base64
.
b64encode
(
'{}:{}'
.
format
(
user
,
password
)
.
encode
())
.
decode
())
try
:
response
=
urllib
.
request
.
urlopen
(
request
)
if
response
.
getcode
()
!=
201
:
raise
Error
(
"POST to '{}' failed: {}"
.
format
(
url
,
response
.
reason
))
except
urllib
.
error
.
URLError
as
e
:
raise
Error
(
"POST to '{}' failed: {}"
.
format
(
url
,
e
))
data
=
json
.
load
(
response
)
return
data
def
generate_asset
(
version
,
tree
,
archive_format
):
Asset
=
namedtuple
(
'Asset'
,
[
'name'
,
'label'
,
'mimetype'
,
'data'
])
mimetype
=
'application/{}'
.
format
(
'gzip'
if
archive_format
==
'tar.gz'
else
'zip'
)
return
Asset
(
"libgit2-{}.{}"
.
format
(
version
,
archive_format
),
"Release sources: libgit2-{}.{}"
.
format
(
version
,
archive_format
),
mimetype
,
git
(
'archive'
,
'--format'
,
archive_format
,
'--prefix'
,
'libgit2-{}/'
.
format
(
version
),
tree
)
)
def
release
(
args
):
params
=
{
"tag_name"
:
'v'
+
str
(
args
.
version
),
"name"
:
'libgit2 v'
+
str
(
args
.
version
),
"target_commitish"
:
git
(
'rev-parse'
,
args
.
tree
)
.
decode
()
.
strip
(),
"body"
:
generate_relnotes
(
args
.
tree
,
args
.
version
),
}
assets
=
[
generate_asset
(
args
.
version
,
args
.
tree
,
'tar.gz'
),
generate_asset
(
args
.
version
,
args
.
tree
,
'zip'
),
]
if
args
.
dryrun
:
for
k
,
v
in
params
.
items
():
print
(
'{}: {}'
.
format
(
k
,
v
))
for
asset
in
assets
:
print
(
'asset: name={}, label={}, mimetype={}, bytes={}'
.
format
(
asset
.
name
,
asset
.
label
,
asset
.
mimetype
,
len
(
asset
.
data
)))
return
try
:
url
=
'https://api.github.com/repos/{}/releases'
.
format
(
args
.
repository
)
response
=
post
(
url
,
json
.
dumps
(
params
)
.
encode
(),
'application/json'
,
args
.
user
,
args
.
password
)
except
Error
as
e
:
raise
Error
(
'Could not create release: '
+
str
(
e
))
for
asset
in
assets
:
try
:
url
=
list
(
urllib
.
parse
.
urlparse
(
response
[
'upload_url'
]
.
split
(
'{?'
)[
0
]))
url
[
4
]
=
urllib
.
parse
.
urlencode
({
'name'
:
asset
.
name
,
'label'
:
asset
.
label
})
post
(
urllib
.
parse
.
urlunparse
(
url
),
asset
.
data
,
asset
.
mimetype
,
args
.
user
,
args
.
password
)
except
Error
as
e
:
raise
Error
(
'Could not upload asset: '
+
str
(
e
))
def
main
():
parser
=
argparse
.
ArgumentParser
(
description
=
'Create a libgit2 release'
)
parser
.
add_argument
(
'--tree'
,
default
=
'HEAD'
,
help
=
'tree to create release for (default: HEAD)'
)
parser
.
add_argument
(
'--dryrun'
,
action
=
'store_true'
,
help
=
'generate release, but do not post it'
)
parser
.
add_argument
(
'--repository'
,
default
=
'libgit2/libgit2'
,
help
=
'GitHub repository to create repository in'
)
parser
.
add_argument
(
'--user'
,
help
=
'user to authenitcate as'
)
parser
.
add_argument
(
'--password'
,
help
=
'password to authenticate with'
)
parser
.
add_argument
(
'version'
,
type
=
Version
,
help
=
'version of the new release'
)
args
=
parser
.
parse_args
()
verify_version
(
args
.
version
)
release
(
args
)
if
__name__
==
'__main__'
:
try
:
main
()
except
Error
as
e
:
print
(
e
)
sys
.
exit
(
1
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment