10000 refactor: optimize & improve maintainability of GitHub Action definition by codejedi365 · Pull Request #914 · python-semantic-release/python-semantic-release · GitHub
[go: up one dir, main page]

Skip to content

refactor: optimize & improve maintainability of GitHub Action definition #914

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

Merged
merged 12 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ updates:
rebase-strategy: auto
versioning-strategy: "increase-if-necessary"

# Maintain dependencies for Docker (ie our GitHub Action)
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "monthly"
labels:
- dependencies
- dependabot
rebase-strategy: auto
commit-message:
prefix: "build"
include: "scope" # (deps)

- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand Down
45 changes: 25 additions & 20 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
# This Dockerfile is only for GitHub Actions
FROM python:3.10-bullseye
FROM python:3.12-bookworm

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

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

ENV PYTHONPATH /semantic-release

COPY . /semantic-release

RUN cd /semantic-release && \
python -m venv /semantic-release/.venv && \
/semantic-release/.venv/bin/pip install .

RUN /semantic-release/.venv/bin/python -m semantic_release --help

ENTRYPOINT ["/semantic-release/action.sh"]
ENTRYPOINT ["/bin/bash", "-l", "/psr/action.sh"]
80 changes: 42 additions & 38 deletions action.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,19 @@ eval_boolean_action_input() {
fi
}

# Copy inputs into correctly-named environment variables
export GH_TOKEN="${INPUT_GITHUB_TOKEN}"
export PATH="${PATH}:/semantic-release/.venv/bin"
export GIT_COMMITTER_NAME="${INPUT_GIT_COMMITTER_NAME:="github-actions"}"
export GIT_COMMITTER_EMAIL="${INPUT_GIT_COMMITTER_EMAIL:="github-actions@github.com"}"
export SSH_PRIVATE_SIGNING_KEY="${INPUT_SSH_PRIVATE_SIGNING_KEY}"
export SSH_PUBLIC_SIGNING_KEY="${INPUT_SSH_PUBLIC_SIGNING_KEY}"
export GIT_COMMIT_AUTHOR="${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>"
export ROOT_OPTIONS="${INPUT_ROOT_OPTIONS:="-v"}"
export PRERELEASE="${INPUT_PRERELEASE:="false"}"
export COMMIT="${INPUT_COMMIT:="false"}"
export PUSH="${INPUT_PUSH:="false"}"
export CHANGELOG="${INPUT_CHANGELOG:="false"}"
export VCS_RELEASE="${INPUT_VCS_RELEASE:="false"}"

# Convert inputs to command line arguments
export ARGS=()
ARGS+=("$(eval_boolean_action_input "prerelease" "$PRERELEASE" "--prerelease" "")") || exit 1
ARGS+=("$(eval_boolean_action_input "commit" "$COMMIT" "--commit" "--no-commit")") || exit 1
# v10 Breaking change as prerelease should be as_prerelease to match
ARGS+=("$(eval_boolean_action_input "prerelease" "$INPUT_PRERELEASE" "--as-prerelease" "")") || exit 1
ARGS+=("$(eval_boolean_action_input "commit" "$INPUT_COMMIT" "--commit" "--no-commit")") || exit 1
ARGS+=("$(eval_boolean_action_input "tag" "$INPUT_TAG" "--tag" "--no-tag")") || exit 1
ARGS+=("$(eval_boolean_action_input "push" "$PUSH" "--push" "--no-push")") || exit 1
ARGS+=("$(eval_boolean_action_input "changelog" "$CHANGELOG" "--changelog" "--no-changelog")") || exit 1
ARGS+=("$(eval_boolean_action_input "vcs_release" "$VCS_RELEASE" "--vcs-release" "--no-vcs-release")") || exit 1
ARGS+=("$(eval_boolean_action_input "push" "$INPUT_PUSH" "--push" "--no-push")") || exit 1
ARGS+=("$(eval_boolean_action_input "changelog" "$INPUT_CHANGELOG" "--changelog" "--no-changelog")") || exit 1
ARGS+=("$(eval_boolean_action_input "vcs_release" "$INPUT_VCS_RELEASE" "--vcs-release" "--no-vcs-release")") || exit 1

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

# Set Git details
git config --global user.name "$GIT_COMMITTER_NAME"
git config --global user.email "$GIT_COMMITTER_EMAIL"
if ! [ "${INPUT_GIT_COMMITTER_NAME:="-"}" = "-" ]; then
git config --global user.name "$INPUT_GIT_COMMITTER_NAME"
fi
if ! [ "${INPUT_GIT_COMMITTER_EMAIL:="-"}" = "-" ]; then
git config --global user.email "$INPUT_GIT_COMMITTER_EMAIL"
fi

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

if [[ -n $SSH_PUBLIC_SIGNING_KEY && -n $SSH_PRIVATE_SIGNING_KEY ]]; then
if [[ -n "$INPUT_SSH_PUBLIC_SIGNING_KEY" && -n "$INPUT_SSH_PRIVATE_SIGNING_KEY" ]]; then
echo "SSH Key pair found, configuring signing..."
mkdir ~/.ssh
echo -e "$SSH_PRIVATE_SIGNING_KEY" >>~/.ssh/signing_key
cat ~/.ssh/signing_key
echo -e "$SSH_PUBLIC_SIGNING_KEY" >>~/.ssh/signing_key.pub

# Write keys to disk
mkdir -vp ~/.ssh
echo -e "$INPUT_SSH_PUBLIC_SIGNING_KEY" >>~/.ssh/signing_key.pub
cat ~/.ssh/signing_key.pub
chmod 600 ~/.ssh/signing_key && chmod 600 ~/.ssh/signing_key.pub
eval "$(ssh-agent)"
echo -e "$INPUT_SSH_PRIVATE_SIGNING_KEY" >>~/.ssh/signing_key
# DO NOT CAT private key for security reasons
sha256sum ~/.ssh/signing_key
# Ensure read only private key
chmod 400 ~/.ssh/signing_key

# Enable ssh-agent & add signing key
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/signing_key

# Create allowed_signers file for git
if [ "${INPUT_GIT_COMMITTER_EMAIL:="-"}" = "-" ]; then
echo >&2 "git_committer_email must be set to use SSH key signing!"
exit 1
fi
touch ~/.ssh/allowed_signers
echo "$INPUT_GIT_COMMITTER_EMAIL $INPUT_SSH_PUBLIC_SIGNING_KEY" >~/.ssh/allowed_signers

# Configure git for signing
git config --global gpg.format ssh
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
git config --global user.signingKey ~/.ssh/signing_key
git config --global commit.gpgsign true
git config --global user.email $GIT_COMMITTER_EMAIL
git config --global user.name $GIT_COMMITTER_NAME
touch ~/.ssh/allowed_signers
echo "$GIT_COMMITTER_EMAIL $SSH_PUBLIC_SIGNING_KEY" >~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
fi

# Run Semantic Release
/semantic-release/.venv/bin/python \
-m semantic_release ${R D7AE OOT_OPTIONS} version ${ARGS[@]}
# Copy inputs into correctly-named environment variables
export GH_TOKEN="${INPUT_GITHUB_TOKEN}"

# Run Semantic Release (explicitly use the GitHub action version)
eval "/psr/.venv/bin/semantic-release $INPUT_ROOT_OPTIONS version ${ARGS[*]}"
23 changes: 12 additions & 11 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,30 @@ inputs:
description: "Additional options for the main command. Example: -vv --noop"
required: false
default: "-v"

directory:
description: "Sub-directory to cd into before running semantic-release"
default: "."
required: false

github_token:
description: "GitHub token used to push release notes and new commits/tags"
required: true

git_committer_name:
description: "The human name for the “committer” field"
default: "github-actions"
required: false

git_committer_email:
description: "The email address for the “committer” field"
default: "github-actions@github.com"
required: false

ssh_public_signing_key:
description: "The ssh public key used to sign commits"
required: false

ssh_private_signing_key:
description: "The ssh private key used to sign commits"
required: false
Expand All @@ -36,7 +42,6 @@ inputs:
required: false
description: |
Force the next version to be a prerelease. Set to "true" or "false".
default: "false"

prerelease_token:
type: string
Expand All @@ -48,13 +53,13 @@ inputs:
required: false
description: |
Force the next version to be a major release. Must be set to
one of "patch", "minor", or "major".
one of "prerelease", "patch", "minor", or "major".

commit:
type: string
required: false
default: "true"
description: Whether or not to commit changes locally
description: Whether or not to commit changes locally. Defaults are handled
by python-semantic-release internal version command.

tag:
type: string
Expand All @@ -66,24 +71,20 @@ inputs:
push:
type: string
required: false
default: "true"
description: |
Whether or not to push local commits to the Git repository.
Defaults to "true", but when either the "commit" or "tag"
input is "false", this push setting will also be set to
"false" regardless of the value supplied.
Whether or not to push local commits to the Git repository. See
the configuration page for defaults of `semantic-release version`
for how the default is determined between push, tag, & commit.

changelog:
type: string
required: false
default: "true"
description: |
Whether or not to update the changelog.

vcs_release:
type: string
required: false
default: "true"
description: |
Whether or not to create a release in the remote VCS, if supported

Expand Down
7 changes: 5 additions & 2 deletions docs/github-action.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,18 @@ defaults as their corresponding command line option.
In general, the input for an action corresponding to a command line option has the same
name, with dashes (``-``) replaced by underscores.

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

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

The flag ``--as-prerelease`` is uniquely provided as just the ``prerelease`` flag value.
This is for compatibility reasons.

For command line options requiring a value, set the input to the required value.

For example, to specify ``--patch --no-push --build-metadata abc123``, you should
Expand Down
0