Skip to content

Commit 85e27b7

Browse files
authored
refactor: optimize & improve maintainability of GitHub Action definition (#914)
* fix(gha): correct use of `prerelease` option for GitHub Action * style(gha): improve shell format of GitHub Action script * docs(gha): update GitHub Actions doc with all available options * refactor(gha): drop cli defaults from action definition * refactor(gha): optimize gha docker definition * refactor(gha): drop defaults & optimize action entrypoint script * chore(dependabot): add updater for gha docker environment * refactor(gha): execute the gha version of semantic-release * refactor(gha): update container os to bookworm, dropping backports need When using Debian Bullseye, it did not have a git version available that supported SSH key signing. SSH key signing was integrated in git version 2.34 and the highest version for Bullseye was 2.30. Through the backports repository, a version greater than 2.34 was made available but now bumping to Debian Bookworm, the available version is 2.39 in the base OS repository so no backports configuration required. * build(deps): bump GitHub Action container to use `python3.12` Updates the base container that runs the GitHub Action environment to python3.12 which enables users to specify and run build scripts that are python3.12 specific as python3.12 is now the latest stable version of python available and we were only providing `3.10`. Resolves: #801 * refactor(gha): add common python binary module deps for builds * refactor(gha): removed execute permissions on action script
1 parent 6b24288 commit 85e27b7

File tree

5 files changed

+97
-71
lines changed

5 files changed

+97
-71
lines changed

.github/dependabot.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ updates:
1818
rebase-strategy: auto
1919
versioning-strategy: "increase-if-necessary"
2020

21+
# Maintain dependencies for Docker (ie our GitHub Action)
22+
- package-ecosystem: "docker"
23+
directory: "/"
24+
schedule:
25+
interval: "monthly"
26+
labels:
27+
- dependencies
28+
- dependabot
29+
rebase-strategy: auto
30+
commit-message:
31+
prefix: "build"
32+
include: "scope" # (deps)
33+
2134
- package-ecosystem: "github-actions"
2235
directory: "/"
2336
schedule:

Dockerfile

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
# This Dockerfile is only for GitHub Actions
2-
FROM python:3.10-bullseye
2+
FROM python:3.12-bookworm
33

4-
RUN set -ex; \
5-
apt-get update; \
6-
apt-get install -y --no-install-recommends \
7-
git-lfs
4+
# Copy python-semantic-release source code into container
5+
COPY . /psr
86

9-
# install backported stable version of git, which supports ssh signing
10-
RUN echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list; \
11-
apt-get update;\
12-
apt-get install -y git/bullseye-backports
7+
RUN \
8+
# Install desired packages
9+
apt update && apt install -y --no-install-recommends \
10+
# install git with git-lfs support
11+
git git-lfs \
12+
# install python cmodule / binary module build utilities
13+
python3-dev gcc make cmake cargo \
14+
# Configure global pip
15+
&& { \
16+
printf '%s\n' "[global]"; \
17+
printf '%s\n' "no-cache-dir = true"; \
18+
printf '%s\n' "disable-pip-version-check = true"; \
19+
} > /etc/pip.conf \
20+
# Create virtual environment for python-semantic-release
21+
&& python3 -m venv /psr/.venv \
22+
# Update core utilities in the virtual environment
23+
&& /psr/.venv/bin/pip install -U pip setuptools wheel \
24+
# Install psr & its dependencies from source into virtual environment
25+
&& /psr/.venv/bin/pip install /psr \
26+
# Cleanup
27+
&& apt clean -y
1328

14-
ENV PYTHONPATH /semantic-release
15-
16-
COPY . /semantic-release
17-
18-
RUN cd /semantic-release && \
19-
python -m venv /semantic-release/.venv && \
20-
/semantic-release/.venv/bin/pip install .
21-
22-
RUN /semantic-release/.venv/bin/python -m semantic_release --help
23-
24-
ENTRYPOINT ["/semantic-release/action.sh"]
29+
ENTRYPOINT ["/bin/bash", "-l", "/psr/action.sh"]

action.sh

100755100644
Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,19 @@ eval_boolean_action_input() {
2525
fi
2626
}
2727

28-
# Copy inputs into correctly-named environment variables
29-
export GH_TOKEN="${INPUT_GITHUB_TOKEN}"
30-
export PATH="${PATH}:/semantic-release/.venv/bin"
31-
export GIT_COMMITTER_NAME="${INPUT_GIT_COMMITTER_NAME:="github-actions"}"
32-
export GIT_COMMITTER_EMAIL="${INPUT_GIT_COMMITTER_EMAIL:="[email protected]"}"
33-
export SSH_PRIVATE_SIGNING_KEY="${INPUT_SSH_PRIVATE_SIGNING_KEY}"
34-
export SSH_PUBLIC_SIGNING_KEY="${INPUT_SSH_PUBLIC_SIGNING_KEY}"
35-
export GIT_COMMIT_AUTHOR="${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>"
36-
export ROOT_OPTIONS="${INPUT_ROOT_OPTIONS:="-v"}"
37-
export PRERELEASE="${INPUT_PRERELEASE:="false"}"
38-
export COMMIT="${INPUT_COMMIT:="false"}"
39-
export PUSH="${INPUT_PUSH:="false"}"
40-
export CHANGELOG="${INPUT_CHANGELOG:="false"}"
41-
export VCS_RELEASE="${INPUT_VCS_RELEASE:="false"}"
42-
4328
# Convert inputs to command line arguments
4429
export ARGS=()
45-
ARGS+=("$(eval_boolean_action_input "prerelease" "$PRERELEASE" "--prerelease" "")") || exit 1
46-
ARGS+=("$(eval_boolean_action_input "commit" "$COMMIT" "--commit" "--no-commit")") || exit 1
30+
# v10 Breaking change as prerelease should be as_prerelease to match
31+
ARGS+=("$(eval_boolean_action_input "prerelease" "$INPUT_PRERELEASE" "--as-prerelease" "")") || exit 1
32+
ARGS+=("$(eval_boolean_action_input "commit" "$INPUT_COMMIT" "--commit" "--no-commit")") || exit 1
4733
ARGS+=("$(eval_boolean_action_input "tag" "$INPUT_TAG" "--tag" "--no-tag")") || exit 1
48-
ARGS+=("$(eval_boolean_action_input "push" "$PUSH" "--push" "--no-push")") || exit 1
49-
ARGS+=("$(eval_boolean_action_input "changelog" "$CHANGELOG" "--changelog" "--no-changelog")") || exit 1
50-
ARGS+=("$(eval_boolean_action_input "vcs_release" "$VCS_RELEASE" "--vcs-release" "--no-vcs-release")") || exit 1
34+
ARGS+=("$(eval_boolean_action_input "push" "$INPUT_PUSH" "--push" "--no-push")") || exit 1
35+
ARGS+=("$(eval_boolean_action_input "changelog" "$INPUT_CHANGELOG" "--changelog" "--no-changelog")") || exit 1
36+
ARGS+=("$(eval_boolean_action_input "vcs_release" "$INPUT_VCS_RELEASE" "--vcs-release" "--no-vcs-release")") || exit 1
5137

5238
# Handle --patch, --minor, --major
5339
# https://stackoverflow.com/a/47541882
54-
valid_force_levels=("patch" "minor" "major")
40+
valid_force_levels=("prerelease" "patch" "minor" "major")
5541
if [ -z "$INPUT_FORCE" ]; then
5642
true # do nothing if 'force' input is not set
5743
elif printf '%s\0' "${valid_force_levels[@]}" | grep -Fxzq "$INPUT_FORCE"; then
@@ -68,33 +54,51 @@ fi
6854
cd "${INPUT_DIRECTORY}"
6955

7056
# Set Git details
71-
git config --global user.name "$GIT_COMMITTER_NAME"
72-
git config --global user.email "$GIT_COMMITTER_EMAIL"
57+
if ! [ "${INPUT_GIT_COMMITTER_NAME:="-"}" = "-" ]; then
58+
git config --global user.name "$INPUT_GIT_COMMITTER_NAME"
59+
fi
60+
if ! [ "${INPUT_GIT_COMMITTER_EMAIL:="-"}" = "-" ]; then
61+
git config --global user.email "$INPUT_GIT_COMMITTER_EMAIL"
62+
fi
7363

7464
# See https://github.com/actions/runner-images/issues/6775#issuecomment-1409268124
7565
# and https://github.com/actions/runner-images/issues/6775#issuecomment-1410270956
7666
git config --system --add safe.directory "*"
7767

78-
if [[ -n $SSH_PUBLIC_SIGNING_KEY && -n $SSH_PRIVATE_SIGNING_KEY ]]; then
68+
if [[ -n "$INPUT_SSH_PUBLIC_SIGNING_KEY" && -n "$INPUT_SSH_PRIVATE_SIGNING_KEY" ]]; then
7969
echo "SSH Key pair found, configuring signing..."
80-
mkdir ~/.ssh
81-
echo -e "$SSH_PRIVATE_SIGNING_KEY" >>~/.ssh/signing_key
82-
cat ~/.ssh/signing_key
83-
echo -e "$SSH_PUBLIC_SIGNING_KEY" >>~/.ssh/signing_key.pub
70+
71+
# Write keys to disk
72+
mkdir -vp ~/.ssh
73+
echo -e "$INPUT_SSH_PUBLIC_SIGNING_KEY" >>~/.ssh/signing_key.pub
8474
cat ~/.ssh/signing_key.pub
85-
chmod 600 ~/.ssh/signing_key && chmod 600 ~/.ssh/signing_key.pub
86-
eval "$(ssh-agent)"
75+
echo -e "$INPUT_SSH_PRIVATE_SIGNING_KEY" >>~/.ssh/signing_key
76+
# DO NOT CAT private key for security reasons
77+
sha256sum ~/.ssh/signing_key
78+
# Ensure read only private key
79+
chmod 400 ~/.ssh/signing_key
80+
81+
# Enable ssh-agent & add signing key
82+
eval "$(ssh-agent -s)"
8783
ssh-add ~/.ssh/signing_key
84+
85+
# Create allowed_signers file for git
86+
if [ "${INPUT_GIT_COMMITTER_EMAIL:="-"}" = "-" ]; then
87+
echo >&2 "git_committer_email must be set to use SSH key signing!"
88+
exit 1
89+
fi
90+
touch ~/.ssh/allowed_signers
91+
echo "$INPUT_GIT_COMMITTER_EMAIL $INPUT_SSH_PUBLIC_SIGNING_KEY" >~/.ssh/allowed_signers
92+
93+
# Configure git for signing
8894
git config --global gpg.format ssh
95+
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
8996
git config --global user.signingKey ~/.ssh/signing_key
9097
git config --global commit.gpgsign true
91-
git config --global user.email $GIT_COMMITTER_EMAIL
92-
git config --global user.name $GIT_COMMITTER_NAME
93-
touch ~/.ssh/allowed_signers
94-
echo "$GIT_COMMITTER_EMAIL $SSH_PUBLIC_SIGNING_KEY" >~/.ssh/allowed_signers
95-
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
9698
fi
9799

98-
# Run Semantic Release
99-
/semantic-release/.venv/bin/python \
100-
-m semantic_release ${ROOT_OPTIONS} version ${ARGS[@]}
100+
# Copy inputs into correctly-named environment variables
101+
export GH_TOKEN="${INPUT_GITHUB_TOKEN}"
102+
103+
# Run Semantic Release (explicitly use the GitHub action version)
104+
eval "/psr/.venv/bin/semantic-release $INPUT_ROOT_OPTIONS version ${ARGS[*]}"

action.yml

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,30 @@ inputs:
88
description: "Additional options for the main command. Example: -vv --noop"
99
required: false
1010
default: "-v"
11+
1112
directory:
1213
description: "Sub-directory to cd into before running semantic-release"
1314
default: "."
1415
required: false
16+
1517
github_token:
1618
description: "GitHub token used to push release notes and new commits/tags"
1719
required: true
20+
1821
git_committer_name:
1922
description: "The human name for the “committer” field"
2023
default: "github-actions"
2124
required: false
25+
2226
git_committer_email:
2327
description: "The email address for the “committer” field"
2428
default: "[email protected]"
2529
required: false
30+
2631
ssh_public_signing_key:
2732
description: "The ssh public key used to sign commits"
2833
required: false
34+
2935
ssh_private_signing_key:
3036
description: "The ssh private key used to sign commits"
3137
required: false
@@ -36,7 +42,6 @@ inputs:
3642
required: false
3743
description: |
3844
Force the next version to be a prerelease. Set to "true" or "false".
39-
default: "false"
4045
4146
prerelease_token:
4247
type: string
@@ -48,13 +53,13 @@ inputs:
4853
required: false
4954
description: |
5055
Force the next version to be a major release. Must be set to
51-
one of "patch", "minor", or "major".
56+
one of "prerelease", "patch", "minor", or "major".
5257
5358
commit:
5459
type: string
5560
required: false
56-
default: "true"
57-
description: Whether or not to commit changes locally
61+
description: Whether or not to commit changes locally. Defaults are handled
62+
by python-semantic-release internal version command.
5863

5964
tag:
6065
type: string
@@ -66,24 +71,20 @@ inputs:
6671
push:
6772
type: string
6873
required: false
69-
default: "true"
7074
description: |
71-
Whether or not to push local commits to the Git repository.
72-
Defaults to "true", but when either the "commit" or "tag"
73-
input is "false", this push setting will also be set to
74-
"false" regardless of the value supplied.
75+
Whether or not to push local commits to the Git repository. See
76+
the configuration page for defaults of `semantic-release version`
77+
for how the default is determined between push, tag, & commit.
7578
7679
changelog:
7780
type: string
7881
required: false
79-
default: "true"
8082
description: |
8183
Whether or not to update the changelog.
8284
8385
vcs_release:
8486
type: string
8587
required: false
86-
default: "true"
8788
description: |
8889
Whether or not to create a release in the remote VCS, if supported
8990

docs/github-action.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,18 @@ defaults as their corresponding command line option.
106106
In general, the input for an action corresponding to a command line option has the same
107107
name, with dashes (``-``) replaced by underscores.
108108

109-
The command line arguments ``--patch``, ``--minor`` and ``--major`` are mutually
110-
exclusive, and are supplied via the ``force`` input.
109+
The command line arguments ``--prerelease``, ``--patch``, ``--minor`` and ``--major``
110+
are mutually exclusive, and are supplied via the ``force`` input.
111111

112112
Flags, which require either ``--<option>`` or ``--no-<option>`` to be passed on the
113113
command-line, should be specified using the option name (with dashes replaced by
114114
underscores), and set to the value ``"true"`` to supply ``--<option>`` on the
115115
command-line, and ``"false"`` to specify ``--no-<option>``.
116116
Any other values are not accepted.
117117

118+
The flag ``--as-prerelease`` is uniquely provided as just the ``prerelease`` flag value.
119+
This is for compatibility reasons.
120+
118121
For command line options requiring a value, set the input to the required value.
119122

120123
For example, to specify ``--patch --no-push --build-metadata abc123``, you should

0 commit comments

Comments
 (0)