From a3f502d067bf7fa812008622c5c20cdefcccb1d2 Mon Sep 17 00:00:00 2001
From: "allcontributors[bot]"
<46447321+allcontributors[bot]@users.noreply.github.com>
Date: Thu, 22 Feb 2024 17:16:24 +0100
Subject: [PATCH 1/2] docs: add jnig as a contributor for review (#457)
* docs: update README.md [skip ci]
* docs: update .all-contributorsrc [skip ci]
---------
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
---
.all-contributorsrc | 9 +++++++++
README.md | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/.all-contributorsrc b/.all-contributorsrc
index c0e6d22c..d25654c9 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -246,6 +246,15 @@
"ideas",
"code"
]
+ },
+ {
+ "login": "jnig",
+ "name": "Jakob",
+ "avatar_url": "https://avatars.githubusercontent.com/u/3729585?v=4",
+ "profile": "https://github.com/Jnig",
+ "contributions": [
+ "review"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/README.md b/README.md
index ea934ac9..103a5464 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# actions-template-sync
-[![All Contributors](https://img.shields.io/badge/all_contributors-24-orange.svg?style=flat-square)](#contributors-)
+[![All Contributors](https://img.shields.io/badge/all_contributors-25-orange.svg?style=flat-square)](#contributors-)
[![actions-template-sync](https://github.com/AndreasAugustin/actions-template-sync/actions/workflows/actions_template_sync.yml/badge.svg)](https://github.com/AndreasAugustin/actions-template-sync/actions/workflows/actions_template_sync.yml)
@@ -495,6 +495,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
jellllly420 🤔 💬 📖 |
Shaun Tabone 💻 |
Kevin AUDE 🤔 💻 |
+ Jakob 👀 |
From 99aefe5830f9ee249bbfbd90a85108f76e897c33 Mon Sep 17 00:00:00 2001
From: andy Augustin
Date: Thu, 22 Feb 2024 17:16:52 +0100
Subject: [PATCH 2/2] feat: :sparkles: (#204) gpg sign (#436)
* feat: :sparkles: (#204) add gnupg to docker image
* feat: :sparkles: (#204) add option to sign commits
* fix: :bug: (#204) issue with tty
* fix: :bug: (#204) fix issue with no tty
* fix: :bug: (#204) fix issue with no passphrase
* fix: :bug: (#204) trial
* fix: :bug: (#204) trial for fix
* fix: :bug: (#204) fix
* fix: :bug: (#204) trial
* fix: :bug: (#204) add pinentry mode loopback
* fix: :bug: (#204)
* feat: :sparkles: (#204) add signoff and tig
* fix: :bug: (#204) fix commit
* fix: :bug: (#204)
* fix: :bug: (#204) trial
* fix: :bug: (#204)
* fix: :bug: trial for gpg sign
* fix: :construction: wip
* fix: :construction: WIP
* fix: :construction: WIP
* fix: :bug: disable gpg with passphrase
---
Dockerfile | 5 ++--
Makefile | 4 +++
README.md | 63 ++++++++++++++++++++++++++++++++++++++++++++
action.yml | 3 +++
docker-compose.yml | 6 +++++
src/Dockerfile | 7 ++---
src/entrypoint.sh | 21 ++++++++++++++-
src/gpg_no_tty.sh | 11 ++++++++
src/sync_common.sh | 2 +-
src/sync_template.sh | 4 +--
10 files changed, 117 insertions(+), 9 deletions(-)
create mode 100644 src/gpg_no_tty.sh
diff --git a/Dockerfile b/Dockerfile
index a28dd2b8..3ddeca05 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@ FROM alpine:3.19.1 as dev
ARG GH_CLI_VER=2.34.0
# install packages
-RUN apk add --update --no-cache bash make git zsh curl tmux musl openssh git-lfs vim yq
+RUN apk add --update --no-cache bash make git zsh curl tmux musl openssh git-lfs vim yq gnupg tig
RUN wget https://github.com/cli/cli/releases/download/v${GH_CLI_VER}/gh_${GH_CLI_VER}_linux_386.tar.gz -O ghcli.tar.gz
RUN tar --strip-components=1 -xf ghcli.tar.gz
@@ -20,7 +20,8 @@ RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh
ADD src/*.sh /bin/
RUN chmod +x /bin/entrypoint.sh \
&& chmod +x /bin/sync_template.sh \
- && chmod +x /bin/sync_common.sh
+ && chmod +x /bin/sync_common.sh \
+ && chmod +x /bin/gpg_no_tty.sh
RUN mkdir -p /root/.ssh \
&& ssh-keyscan -t rsa github.com >> /root/.ssh/known_hosts
diff --git a/Makefile b/Makefile
index 95d3cd06..5060ec00 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,10 @@ markdownlint: ## Validate markdown files
zsh: ## open dev container with build environment
docker-compose run --service-ports dev /bin/zsh
+.PHONY: prod
+prod: ## run the prod docker image with bash
+ docker-compose run prod
+
.PHONY: prune
prune: ## delete the whole environment
docker-compose down -v --rmi all --remove-orphans
diff --git a/README.md b/README.md
index 103a5464..3bcd5486 100644
--- a/README.md
+++ b/README.md
@@ -252,6 +252,7 @@ jobs:
| git_user_name | `[optional]` set the committer git user.name | `false` | `${GITHUB_ACTOR}` |
| git_user_email | `[optional]` set the committer git user.email | `false` | `github-action@actions-template-sync.noreply.${SOURCE_REPO_HOSTNAME}` |
| git_remote_pull_params | `[optional]` set remote pull parameters | `false` | `--allow-unrelated-histories --squash --strategy=recursive -X theirs` |
+| gpg_private_key | `[optional]` set if you want to sign commits | `false` | |
### Docker
@@ -293,6 +294,65 @@ E.g. when you like to disable the sync for all files with exceptions, you need t
*
```
+## Sign commits
+
+It is recommended to [sign your commits][devto-sign-commits]. This action is able to sign commits.
+
+First, [generate a GPG key][github-create-gpg-key] and export the GPG private key as an ASCII armored version to your clipboard:
+
+```bash
+# macOS
+gpg --armor --export-secret-key jon@doe.example | pbcopy
+
+# Ubuntu (assuming GNU base64)
+gpg --armor --export-secret-key jon@doe.example -w0 | xclip
+
+# Arch
+gpg --armor --export-secret-key jon@doe.example | xclip -selection clipboard -i
+
+# FreeBSD (assuming BSD base64)
+gpg --armor --export-secret-key jon@doe.example | xclip
+```
+
+:warning: the gpg username and email must match the `git_user_name` and `git_user_email` parameters.
+Paste your clipboard as a [secret][github-create-secret] named `GPG_PRIVATE_KEY` for example.
+:warning: currently a pgp key with passphrase is not supported (yet).
+
+```yaml
+# File: .github/workflows/template-sync.yml
+
+on:
+ # cronjob trigger
+ schedule:
+ - cron: "0 0 1 * *"
+ # manual trigger
+ workflow_dispatch:
+jobs:
+ repo-sync:
+ runs-on: ubuntu-latest
+ # https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
+ permissions:
+ contents: write
+ pull-requests: write
+
+ steps:
+ # To use this repository's private action, you must check out the repository
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: actions-template-sync
+ uses: AndreasAugustin/actions-template-sync@v1
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ source_repo_path:
+ git_user_name: # add the gpg username
+ git_user_email: # add the gpg email
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+ # uncomment if your key has a passpharse
+ # gpg_passpharse: ${{ secrets.GPG_PASSPHRASE }}
+
+```
+
## Lifecycle hooks
Different lifecycle hooks are supported. You need to enable the functionality with the option `is_allow_hooks` and set it to `true`
@@ -443,6 +503,7 @@ There are other great tools available within GitHub. Here you can find a compari
| dry run | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
| ignore files | :heavy_check_mark: | :x: | :x: | :heavy_check_mark: |
| creates a PR | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: |
+| sign commits | :heavy_check_mark: | :x: | :x: | :x: |
| remarks | The action is placed within the target repositories | The action is placed within the target repositories | CLI meant for local use | The action will be based within the base repository with a list of dependent repositories |
## DEV
@@ -516,6 +577,7 @@ specification. Contributions of any kind are welcome!
[self-usage]: https://github.com/AndreasAugustin/actions-template-sync/blob/main/.github/workflows/actions_template_sync.yml
[pr-labels]: https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels
[devto-example]: https://dev.to/andreasaugustin/github-actions-template-sync-1g9k
+[devto-sign-commits]: https://dev.to/andreasaugustin/git-how-and-why-to-sign-commits-35dn
[github-example]: https://github.com/AndreasAugustin/teaching/blob/main/docs/git/git_action_sync.md
[github-app]: https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps
[glob-pattern]: https://en.wikipedia.org/wiki/Glob_(programming)
@@ -530,3 +592,4 @@ specification. Contributions of any kind are welcome!
[dotdc-blog]: https://0xdc.me/blog/github-templates-and-repository-sync/
[github-create-pat]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token
[github-create-secret]: https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository
+[github-create-gpg-key]: https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key
diff --git a/action.yml b/action.yml
index f3f654d1..9479443c 100644
--- a/action.yml
+++ b/action.yml
@@ -52,6 +52,8 @@ inputs:
description: "[optional] set the committer git user.email for the merge commit"
git_remote_pull_params:
description: "[optional] set the pull parameters for the remote repository"
+ gpg_private_key:
+ description: "[optional] set the gpg private key if you want to sign your commits"
runs:
using: "docker"
image: "src/Dockerfile"
@@ -74,3 +76,4 @@ runs:
GIT_USER_NAME: ${{ inputs.git_user_name }}
GIT_USER_EMAIL: ${{ inputs.git_user_email }}
GIT_REMOTE_PULL_PARAMS: ${{ inputs.git_remote_pull_params }}
+ GPG_PRIVATE_KEY: ${{ inputs.gpg_private_key }}
diff --git a/docker-compose.yml b/docker-compose.yml
index a72254db..2ab78b42 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -23,3 +23,9 @@ services:
volumes:
- .:/app/
working_dir: /app/
+
+ prod:
+ build:
+ context: ./src/
+ tty: true
+ entrypoint: ["/bin/bash"]
diff --git a/src/Dockerfile b/src/Dockerfile
index 11fee153..3799db38 100644
--- a/src/Dockerfile
+++ b/src/Dockerfile
@@ -15,7 +15,7 @@ LABEL org.opencontainers.image.title="actions-template-sync image"
LABEL org.opencontainers.image.description="contains actions-template-sync"
# install packages
-RUN apk add --update --no-cache bash git curl musl openssh git-lfs yq
+RUN apk add --update --no-cache bash git curl musl openssh git-lfs yq gnupg tig
RUN wget https://github.com/cli/cli/releases/download/v${GH_CLI_VER}/gh_${GH_CLI_VER}_linux_386.tar.gz -O ghcli.tar.gz
RUN tar --strip-components=1 -xf ghcli.tar.gz
@@ -23,9 +23,10 @@ RUN tar --strip-components=1 -xf ghcli.tar.gz
ADD *.sh /bin/
RUN chmod +x /bin/entrypoint.sh \
&& chmod +x /bin/sync_template.sh \
- && chmod +x /bin/sync_common.sh
+ && chmod +x /bin/sync_common.sh \
+ && chmod +x /bin/gpg_no_tty.sh
RUN mkdir -p /root/.ssh \
&& ssh-keyscan -t rsa github.com >> /root/.ssh/known_hosts
-ENTRYPOINT ["/bin/entrypoint.sh"]
+ENTRYPOINT ["/bin/bash", "/bin/entrypoint.sh"]
diff --git a/src/entrypoint.sh b/src/entrypoint.sh
index c5c34869..4d788e13 100644
--- a/src/entrypoint.sh
+++ b/src/entrypoint.sh
@@ -1,4 +1,4 @@
-#! /usr/bin/env bash
+#!/usr/bin/env bash
set -e
# set -u
# set -x
@@ -41,6 +41,21 @@ function ssh_setup() {
echo "::endgroup::"
}
+function gpg_setup() {
+ echo "::group::gpg setup"
+ info "start prepare gpg"
+ echo -e "$GPG_PRIVATE_KEY" | gpg --import --batch
+ for fpr in $(gpg --list-key --with-colons "${GIT_USER_EMAIL}" | awk -F: '/fpr:/ {print $10}' | sort -u); do echo -e "5\ny\n" | gpg --no-tty --command-fd 0 --expert --edit-key "$fpr" trust; done
+
+ KEY_ID="$(gpg --list-secret-key --with-colons "${GIT_USER_EMAIL}" | awk -F: '/sec:/ {print $5}')"
+ git config --global user.signingkey "${KEY_ID}"
+ git config --global commit.gpgsign true
+ git config --global gpg.program /bin/gpg_no_tty.sh
+
+ info "done prepare gpg"
+ echo "::endgroup::"for fpr in
+}
+
# Forward to /dev/null to swallow the output of the private key
if [[ -n "${SSH_PRIVATE_KEY_SRC}" ]] &>/dev/null; then
ssh_setup
@@ -73,5 +88,9 @@ function git_init() {
git_init
+if [[ -n "${GPG_PRIVATE_KEY}" ]] &>/dev/null; then
+ gpg_setup
+fi
+
# shellcheck source=src/sync_template.sh
source sync_template.sh
diff --git a/src/gpg_no_tty.sh b/src/gpg_no_tty.sh
new file mode 100644
index 00000000..e742a973
--- /dev/null
+++ b/src/gpg_no_tty.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+if [[ -n "${GPG_PASSPHRASE}" ]] &>/dev/null; then
+ # echo -e "${GPG_PASSPHRASE}" | gpg --pinentry-mode loopback --batch --yes --passphrase-fd 0 "$@" <&0
+ echo "::error::currently gpg with passphrase is not supported"
+ exit 1
+else
+ gpg --pinentry-mode loopback --yes --batch "$@" <&0
+fi
+
+exit $?
diff --git a/src/sync_common.sh b/src/sync_common.sh
index 8677a408..e8abc366 100755
--- a/src/sync_common.sh
+++ b/src/sync_common.sh
@@ -1,4 +1,4 @@
-#! /usr/bin/env bash
+#!/usr/bin/env bash
set -e
# set -u
diff --git a/src/sync_template.sh b/src/sync_template.sh
index 7894a55c..d4cb6921 100644
--- a/src/sync_template.sh
+++ b/src/sync_template.sh
@@ -1,4 +1,4 @@
-#! /usr/bin/env bash
+#!/usr/bin/env bash
set -e
# set -u
@@ -139,7 +139,7 @@ if git diff --quiet && git diff --staged --quiet; then
exit 0
fi
-git commit -m "${PR_COMMIT_MSG}"
+git commit --signoff -m "${PR_COMMIT_MSG}"
echo "::endgroup::"