Skip to content
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

feat: ✨ (#204) gpg sign #436

Merged
merged 28 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
027d6e3
feat: :sparkles: (#204) add gnupg to docker image
AndreasAugustin Jan 7, 2024
8915340
feat: :sparkles: (#204) add option to sign commits
AndreasAugustin Jan 7, 2024
97a1e27
fix: :bug: (#204) issue with tty
AndreasAugustin Jan 7, 2024
9621a71
fix: :bug: (#204) fix issue with no tty
AndreasAugustin Jan 7, 2024
f57d687
fix: :bug: (#204) fix issue with no passphrase
AndreasAugustin Jan 7, 2024
20188f4
fix: :bug: (#204) trial
AndreasAugustin Jan 7, 2024
d6fe6df
fix: :bug: (#204) trial for fix
AndreasAugustin Jan 7, 2024
d4dadf0
fix: :bug: (#204) fix
AndreasAugustin Jan 7, 2024
9d35a97
fix: :bug: (#204) trial
AndreasAugustin Jan 7, 2024
0cf0761
fix: :bug: (#204) add pinentry mode loopback
AndreasAugustin Jan 7, 2024
d620612
fix: :bug: (#204)
AndreasAugustin Jan 7, 2024
93fe048
feat: :sparkles: (#204) add signoff and tig
AndreasAugustin Jan 8, 2024
6a81079
fix: :bug: (#204) fix commit
AndreasAugustin Jan 8, 2024
a0821ac
fix: :bug: (#204)
AndreasAugustin Jan 8, 2024
6759d0e
fix: :bug: (#204) trial
AndreasAugustin Jan 8, 2024
c302e72
fix: :bug: (#204)
AndreasAugustin Jan 8, 2024
6ecf2c0
Merge branch 'main' into feat/gpg_sign
AndreasAugustin Jan 18, 2024
9305ea9
Merge branch 'main' into feat/gpg_sign
AndreasAugustin Jan 23, 2024
e2980bd
Merge branch 'main' into feat/gpg_sign
AndreasAugustin Feb 4, 2024
856280c
Merge branch 'main' into feat/gpg_sign
AndreasAugustin Feb 5, 2024
3b9a839
fix: :bug: trial for gpg sign
AndreasAugustin Feb 5, 2024
2d4cee9
fix: :construction: wip
AndreasAugustin Feb 5, 2024
6c8e1be
fix: :construction: WIP
AndreasAugustin Feb 5, 2024
739dc19
fix: :construction: WIP
AndreasAugustin Feb 6, 2024
cea65b0
Merge branch 'main' into feat/gpg_sign
AndreasAugustin Feb 16, 2024
1dd7023
Merge branch 'main' into feat/gpg_sign
AndreasAugustin Feb 21, 2024
6daf078
fix: :bug: disable gpg with passphrase
AndreasAugustin Feb 22, 2024
21a0269
Merge branch 'main' into feat/gpg_sign
AndreasAugustin Feb 22, 2024
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
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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: <owner/repo>
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`
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 }}
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ services:
volumes:
- .:/app/
working_dir: /app/

prod:
build:
context: ./src/
tty: true
entrypoint: ["/bin/bash"]
7 changes: 4 additions & 3 deletions src/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ 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

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"]
21 changes: 20 additions & 1 deletion src/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! /usr/bin/env bash
#!/usr/bin/env bash
set -e
# set -u
# set -x
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
11 changes: 11 additions & 0 deletions src/gpg_no_tty.sh
Original file line number Diff line number Diff line change
@@ -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 $?
2 changes: 1 addition & 1 deletion src/sync_common.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! /usr/bin/env bash
#!/usr/bin/env bash

set -e
# set -u
Expand Down
4 changes: 2 additions & 2 deletions src/sync_template.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! /usr/bin/env bash
#!/usr/bin/env bash

set -e
# set -u
Expand Down Expand Up @@ -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::"

Expand Down