Skip to content

Commit 21959dd

Browse files
author
Metin Yazici
committed
Create release workflow for GHA
Closes #14
1 parent 61c198f commit 21959dd

File tree

7 files changed

+171
-66
lines changed

7 files changed

+171
-66
lines changed

.github/workflows/CI.yml

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
name: CI
22

3-
on:
4-
push:
5-
branches:
6-
- master
7-
pull_request:
8-
branches:
9-
- master
3+
on: [push, pull_request]
104

115
jobs:
126

137
pre-commit:
14-
name: "pre-commit checks"
8+
name: pre-commit checks
159
runs-on: ubuntu-latest
1610
timeout-minutes: 2
1711
steps:
@@ -20,7 +14,7 @@ jobs:
2014
- uses: pre-commit/[email protected]
2115

2216
tests:
23-
name: "Run all tests Python v.${{ matrix.python-version }}"
17+
name: Run tests with python ${{ matrix.python-version }}
2418
runs-on: ubuntu-latest
2519
timeout-minutes: 2
2620

.github/workflows/release.yml

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
jobs:
9+
10+
prepare:
11+
name: "Prepare for release"
12+
runs-on: ubuntu-latest
13+
timeout-minutes: 1
14+
15+
outputs:
16+
version: ${{ steps.versions.outputs.version }}
17+
py_version: ${{ steps.versions.outputs.py_version }}
18+
19+
steps:
20+
- uses: actions/checkout@v2
21+
22+
- name: Get versions
23+
id: versions
24+
run: |
25+
version="$(./get_version.sh __version__)"
26+
py_version="$(./get_version.sh __py_version__)"
27+
# check the tag ref is the same as package version:
28+
if [ "v${version}" != "$tag_ref" ]; then
29+
echo "::error ::fatal! version not matching with tag"
30+
exit 1
31+
fi
32+
echo "::set-output name=version::$version"
33+
echo "::set-output name=py_version::$py_version"
34+
env:
35+
tag_ref: ${{ github.ref_name }}
36+
37+
release_github:
38+
name: "Create release on Github"
39+
needs: [ prepare ]
40+
runs-on: ubuntu-latest
41+
timeout-minutes: 2
42+
43+
steps:
44+
- uses: actions/checkout@v2
45+
46+
- name: Create release
47+
uses: softprops/action-gh-release@v1
48+
with:
49+
body: |
50+
# v${{ needs.prepare.outputs.version }}
51+
52+
## PyPI
53+
54+
```bash
55+
pip install git-substatus==${{ needs.prepare.outputs.version }}
56+
```
57+
58+
## DockerHub
59+
60+
```bash
61+
docker run --rm -t -v "$(pwd)":/"$(pwd)" -w "$(pwd)" strboul/git-substatus:${{ needs.prepare.outputs.version }}
62+
```
63+
# TODO which files actually?
64+
files: dist/
65+
66+
publish_pypi:
67+
name: "Publish to PyPI (https://pypi.org/project/git-substatus/)"
68+
needs: [ prepare ]
69+
runs-on: ubuntu-latest
70+
timeout-minutes: 2
71+
72+
steps:
73+
- uses: actions/checkout@v2
74+
75+
- name: Setup Python
76+
uses: actions/setup-python@v2
77+
with:
78+
python-version: ${{ needs.prepare.outputs.py_version }}
79+
80+
- name: Install dev dependencies
81+
run: |
82+
python -m pip install --upgrade pip
83+
pip install -r dev-requirements.txt
84+
85+
- name: Build a binary wheel and a source tarball
86+
run: |
87+
python -m pip install build --user
88+
python -m build --sdist --wheel --outdir dist/
89+
90+
- name: Publish to PyPI
91+
uses: pypa/gh-action-pypi-publish@master
92+
with:
93+
password: ${{ secrets.PYPI_API_TOKEN }}
94+
95+
publish_dockerhub:
96+
name: "Publish to DockerHub (https://hub.docker.com/r/strboul/git-substatus)"
97+
needs: [ prepare ]
98+
runs-on: ubuntu-latest
99+
timeout-minutes: 2
100+
101+
steps:
102+
- name: Login to DockerHub
103+
uses: docker/login-action@v1
104+
with:
105+
username: strboul
106+
password: ${{ secrets.DOCKERHUB_TOKEN }}
107+
108+
- name: Build and push
109+
id: docker_build
110+
uses: docker/build-push-action@v2
111+
with:
112+
push: true
113+
build-args:
114+
PY_VERSION=${{ needs.prepare.outputs.py_version }}
115+
tags: |
116+
strboul/git-substatus:${{ needs.prepare.outputs.version }}
117+
strboul/git-substatus:latest

Dockerfile

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
FROM python:3.8-alpine
1+
ARG PY_VERSION
2+
FROM python:${PY_VERSION}-alpine
23
LABEL MAINTAINER="strboul"
34
LABEL REPOSITORY="https://github.com/strboul/git-substatus"
45
LABEL HOMEPAGE="https://github.com/strboul/git-substatus"
56

6-
RUN apk add --no-cache git
7+
RUN apk add --update --no-cache --no-progress git
78

89
ARG CONTAINER_PATH="/opt/git-substatus/"
910
RUN mkdir -p "$CONTAINER_PATH"
1011
COPY setup.py README.md "$CONTAINER_PATH"
1112
COPY git_substatus/ "$CONTAINER_PATH"/git_substatus
12-
RUN cd "$CONTAINER_PATH" && pip install .
13+
RUN cd "$CONTAINER_PATH" && \
14+
python -m pip install --upgrade pip
1315

1416
ENTRYPOINT ["git-substatus"]

Makefile

+18-24
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
.PHONY: install test typecheck coverage docker clean release
2-
3-
41
define check_pip_module
52
$(if $(shell pip show $(1)),,$(error "module '$(1)' not found."))
63
endef
74

85

96
define echo_section
10-
@printf "\33[33m\n%s\n%s\n\33[0m" $(1) "=============================="
7+
@printf "\33[33m\n%s\n%s\n\33[0m" $(1) "==========================="
8+
endef
9+
10+
11+
define ask_prompt
12+
@printf "%s\nAre you sure? [y/N]" $(1) && read ans && [ $${ans:-N} = y ]
1113
endef
1214

1315

14-
VERSION := $(shell sed -n "s/__version__ = *\"\([^ ]*\)\"/\1/p" git_substatus/__init__.py)
16+
VERSION := $(shell ./get_version.sh __version__)
17+
PY_VERSION := $(shell ./get_version.sh __py_version__)
1518

1619

1720
all: typecheck black test install clean
@@ -56,26 +59,17 @@ clean:
5659
find . -depth -name .coverage -exec rm {} \;
5760

5861

59-
# release with twine: https://twine.readthedocs.io/en/latest/#using-twine
60-
release-pypi:
61-
$(call echo_section,"releasing to PyPi")
62-
$(call check_pip_module,"twine")
63-
$(call check_pip_module,"wheel")
64-
python setup.py sdist bdist_wheel
65-
twine check dist/*
66-
twine upload dist/*
67-
$(RM) -r build/ dist/ *.egg-info/
62+
tag-create:
63+
$(call ask_prompt,"creating tag \"v$(VERSION)\".")
64+
git tag "v$(VERSION)"
6865

6966

70-
docker-build:
71-
$(call echo_section,"building the docker image")
72-
docker build -t strboul/git-substatus:$(VERSION) .
73-
docker tag strboul/git-substatus:$(VERSION) strboul/git-substatus:latest
67+
tag-push:
68+
$(call ask_prompt,"pushing tag \"$(VERSION)\" to master.")
69+
git push origin "v$(VERSION)"
7470

7571

76-
docker-release:
77-
$(call echo_section,"releasing to https://hub.docker.com")
78-
@echo "Login with the Docker ID to push the image to Docker Hub."
79-
docker login -u strboul
80-
docker push strboul/git-substatus:$(VERSION)
81-
docker push strboul/git-substatus:latest
72+
docker-build:
73+
$(call echo_section,"building the docker image")
74+
docker build -t strboul/git-substatus:"$(VERSION)" --build-arg PY_VERSION="$(PY_VERSION)" .
75+
docker tag strboul/git-substatus:"$(VERSION)" strboul/git-substatus:latest

README.md

+19-29
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Alternatively, the [Docker](https://hub.docker.com/r/strboul/git-substatus)
4848
image can be used:
4949

5050
```bash
51-
docker run --rm -t -v "$(pwd)":/"$(pwd)" -w "$(pwd)" strboul/git-substatus:latest <optional-path>
51+
docker run --rm -t -v "$(pwd)":/"$(pwd)" -w "$(pwd)" strboul/git-substatus:latest
5252
```
5353

5454
To shorten the command, it's also possible to add an alias in the `.bashrc` or
@@ -61,9 +61,9 @@ _git_substatus() {
6161
alias git-substatus="_git_substatus"
6262
```
6363

64-
Benchmark: I measured that the container solution is about 70% slower than the
65-
native operation, most likely due to the overhead; however, the container is
66-
still useful when portability matters.
64+
Benchmark: it's measured that the container solution is ~70% slower than the
65+
native operation due to the overhead; however, the container solution is still
66+
useful for portability matters.
6767

6868
## Development
6969

@@ -74,6 +74,16 @@ This module has no module dependency outside
7474

7575
<summary>Development docs</summary>
7676

77+
### Versioning and release
78+
79+
1. Bump up the `__version__` in `git_substatus/__init__.py` and commit the
80+
change in the batch where you changed the files.
81+
82+
2. (For the codeowner) Create a version tag with `make tag-create` number. Push
83+
the tag to the origin with `make tag-push`. Upon the push, the release
84+
workflow will be triggered that distributes the new version to the
85+
platforms, like *PyPI*, *DockerHub*.
86+
7787
### pre-commit
7888

7989
Run pre-commit git hooks on every commit that run checks against the files
@@ -83,6 +93,11 @@ Upon cloning the repo, set up `pre-commit`:
8393
- Install pre-commit https://pre-commit.com/#installation
8494
- Run `pre-commit install` that installs the hook scripts at `.git/hooks`
8595

96+
### Add tests
97+
98+
+ Write/update unit tests (if relevant). You can start by adding/modifying a
99+
case to generator file `tests/gen_test_repos.sh`.
100+
86101
### Run tests && debugging
87102

88103
```bash
@@ -103,29 +118,4 @@ make test
103118
+ Use the reference to name the functions/methods in the module:
104119
https://mirrors.edge.kernel.org/pub/software/scm/git/docs/gitglossary.html
105120

106-
### Sending a PR
107-
108-
+ Bump up the version - `major.minor.path` (depends on the change) Change the
109-
version in the file `git_substatus/__init__.py`.
110-
111-
+ Write/update unit tests (where relevant). You can start by adding/modifying a
112-
case to generator file `tests/gen_test_repos.sh`.
113-
114-
### Release
115-
116-
*(needs credentials)*
117-
118-
+ Release to PyPi
119-
120-
```bash
121-
make release-pypi
122-
```
123-
124-
+ Release to Docker Hub
125-
126-
```bash
127-
make docker-build
128-
make docker-release
129-
```
130-
131121
</details>

get_version.sh

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
3+
variable="$1"
4+
sed -n "s/$variable = *\"\([^ ]*\)\"/\1/p" git_substatus/__init__.py

git_substatus/__init__.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
__version__ = "0.2.8"
1+
# package version:
2+
__version__ = "0.2.9"
3+
4+
# min default supported python version:
5+
__py_version__ = "3.8"

0 commit comments

Comments
 (0)