From 11c016848bf342603a02a5cf5132a2e4cc1d618f Mon Sep 17 00:00:00 2001 From: Jacob Hummer Date: Tue, 16 May 2023 16:58:04 -0500 Subject: [PATCH 1/7] fix #27 --- action.yml | 74 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/action.yml b/action.yml index 03a5868..935c709 100644 --- a/action.yml +++ b/action.yml @@ -1,35 +1,55 @@ # Copyright 2023 Andrew Chen Wang +# Copyright 2023 Jacob Hummer # SPDX-License-Identifier: Apache-2.0 + name: GitHub Wiki Action author: Andrew Chen Wang -description: This action publishes Wiki pages with a provided directory into a GitHub repository's Wiki. -runs: - using: 'docker' - image: 'Dockerfile' +description: 📖 Deploy docs from your source tree to the GitHub wiki +branding: + icon: book + color: blue inputs: - WIKI_DIR: - description: 'Directory to rsync files to the wiki.' - required: false - default: 'wiki/' - GH_TOKEN: - description: 'The GitHub Token for this action to use. Specify secrets.GITHUB_TOKEN.' + repository: + description: >- + The repository housing the wiki. Use this if you're publishing to a wiki + that's not the current repository. You can change the GitHub server with + the github-server-url input. Default is github.repository. required: true - GH_MAIL: - description: 'The email associated with the token.' + default: ${{ github.repository }} + token: + description: >- + github.token is the default. This token is used when cloning and pushing + wiki changes. required: true - GH_NAME: - description: 'The username associated with the token.' + default: ${{ github.token }} + path: + description: >- + The directory to use for your wiki contents. Default wiki. required: true - REPO: - description: 'The target repository. Default is the current repo.' - required: false - WIKI_PUSH_MESSAGE: - description: 'The commit message for the wiki commit. Default is the commit to actual repository.' - required: false - EXCLUDED_FILES: - description: 'A list of files you want to exclude (separate with spaces).' - required: false - -branding: - icon: upload-cloud - color: blue + default: wiki + commit-message: + description: >- + The message to use when committing new content. Default is 'Update wiki + github.sha'. You probably don't need to change this, since this only + applies if you look really closely in your wiki. + required: true + default: Update wiki ${{ github.sha }} + ignore: + description: >- + A multiline list of files that should be ignored when committing and + pushing to the remote wiki. Each line is a pattern like .gitignore. Make + sure these paths are relative to the path option! The default is none. + required: true + default: "" +runs: + using: composite + steps: + - id: index + run: '"${GITHUB_ACTION_PATH%/}/index.sh"' + shell: bash + env: + INPUT_REPOSITORY: ${{ inputs.repository }} + INPUT_TOKEN: ${{ inputs.token }} + INPUT_PATH: ${{ inputs.path }} + INPUT_COMMIT_MESSAGE: ${{ inputs.commit-message }} + INPUT_IGNORE: ${{ inputs.ignore }} From 5af2102885a060864cb4c6dfb25d56232fee37b5 Mon Sep 17 00:00:00 2001 From: Jacob Hummer Date: Tue, 16 May 2023 16:58:32 -0500 Subject: [PATCH 2/7] fix #32 --- Dockerfile | 9 ----- entrypoint.sh | 73 ----------------------------------- index.sh | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 82 deletions(-) delete mode 100644 Dockerfile delete mode 100644 entrypoint.sh create mode 100644 index.sh diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 9400adb..0000000 --- a/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2023 Andrew Chen Wang -# SPDX-License-Identifier: Apache-2.0 -FROM alpine/git - -RUN apk add rsync - -COPY entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100644 index 6f9103b..0000000 --- a/entrypoint.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh -# Copyright 2023 Andrew Chen Wang -# SPDX-License-Identifier: Apache-2.0 - -TEMP_CLONE_FOLDER="temp_wiki_$GITHUB_SHA" -TEMP_EXCLUDED_FILE="temp_wiki_excluded_$GITHUB_SHA.txt" - -if [ -z "$GH_TOKEN" ]; then - echo "GH_TOKEN ENV is missing. Use $\{{ secrets.GITHUB_TOKEN }} or a PAT if your wiki repo is different from your current repo." - exit 1 -fi - -if [ -z "$GH_MAIL" ]; then - echo "GH_MAIL ENV is missing. Use the email for a user that can push to this repository." - exit 1 -fi - -if [ -z "$GH_NAME" ]; then - echo "GH_NAME ENV is missing. Use the username for a user that can push to this repository." - exit 1 -fi - -if [ -z "$REPO" ]; then - echo "REPO ENV is missing. Using the current one." - REPO=$GITHUB_REPOSITORY -fi - -if [ -z "$WIKI_DIR" ]; then - echo "WIKI_FOLDER ENV is missing, using default wiki/" - WIKI_DIR='wiki/' -fi - -# Disable Safe Repository checks -git config --global --add safe.directory "/github/workspace" -git config --global --add safe.directory "/github/workspace/$TEMP_CLONE_FOLDER" - -echo "Cloning wiki git..." -git clone https://$GH_NAME:$GH_TOKEN@github.com/$REPO.wiki.git $TEMP_CLONE_FOLDER - -# Get commit message -if [ -z "$WIKI_PUSH_MESSAGE" ]; then - message=$(git log -1 --format=%B) -else - message=$WIKI_PUSH_MESSAGE -fi -echo "Message:" -echo $message - -echo "Copying files to Wiki" -# Configuring a file to exclude specified files -if [ -z "$EXCLUDED_FILES" ]; then - rsync -av --delete $WIKI_DIR $TEMP_CLONE_FOLDER/ --exclude .git -else - for file in $EXCLUDED_FILES; do - echo "$file" >> ./$TEMP_EXCLUDED_FILE - done - rsync -av --delete $WIKI_DIR $TEMP_CLONE_FOLDER/ --exclude .git --exclude-from=$TEMP_EXCLUDED_FILE - # Delete files in target repo if it was a reminant. - for file in $EXCLUDED_FILES; do - rm -r $TEMP_CLONE_FOLDER/$file - done -fi - -echo "Pushing to Wiki" -cd $TEMP_CLONE_FOLDER - -# Setup credentials -git config user.name $GH_NAME -git config user.email $GH_MAIL - -git add . -git commit -m "$message" -git push origin master diff --git a/index.sh b/index.sh new file mode 100644 index 0000000..b9f90ca --- /dev/null +++ b/index.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# Copyright 2023 Jacob Hummer +# SPDX-License-Identifier: Apache-2.0 +set -e + +# We overwrite the $GITHUB_* environment variables with user-provided ones. +# GitHub Actions normally provides a bunch of $GITHUB_* env vars. These can +# be used in scripts to tailor them to the current GitHub thing (repo, issue, +# etc). Here, we want to use these same variables, but with our custom +# user-provided values instead. We overwrite the originals (in this process; +# we can't affect our parent process) with the user-provided (or default) +# values so that we can use the same $GITHUB_REPOSITORY semantics to refer to +# the current repo that the action is on (the default) or the user-provided +# repo that we want to use instead. We use the same var names to make it +# familiar. +export GITHUB_TOKEN="$INPUT_TOKEN" +export GITHUB_SERVER_URL="$INPUT_GITHUB_SERVER_URL" +export GITHUB_REPOSITORY="$INPUT_REPOSITORY" +# This is the default host that gh uses for clones and commands without a repo +# context (a .git folder). We use Bash string magic to get the github.com part +# from a full origin (no pathname) like https://github.com => github.com. The +# '#*//' operation removes '*//' from the start of the string. That's the +# 'https://' chunk. With that gone, we are left with 'github.company.com' or +# something similar. +export GH_HOST="${GITHUB_SERVER_URL#*//}" + +# We configure some special $GIT_* environment variables to make it so that +# we can have our special .git folder (you know, the one that holds all the +# critical repo information & history?) in a completely different location +# from our working tree! Normally, $GIT_DIR is automagically determined by +# walking up the folders from your $PWD until '.git/' is found. In this case, +# we want that in a temp folder. Then, we use $GIT_WORK_TREE to control what +# the base folder or "root" of the $GIT_DIR's repo should be. Normally, this +# would be the $PWD, but we want to set it to the $INPUT_PATH which is +# probably a subfolder of the project somwhere! +export GIT_DIR=$(mktemp -d) +export GIT_WORK_TREE="$INPUT_PATH" +# This is just good practice to clean up after yourself. It's not needed per-se. +# This is a one-off Actions runner that will delete every part of itself after +# completion. It's a good habit nonetheless. +trap 'rm -rf "$GIT_DIR"' SIGINT SIGTERM ERR EXIT + +# This setup-git is a command is what makes it so that we can be authorized to +# do normal 'git clone' and 'git push' operations without using the gh CLI. It +# auto-adds the credentials for the host in $GH_HOST and any additional --host +# options passed to it. We need this to make it so that our 'git push' at the +# end of this script works! +gh auth setup-git +# We also need to preemptively mark the $GIT_DIR as safe to use. Normally Git +# will protect you against doing insecure stuff in untrusted areas, and that's +# a good thing! In this case, though, we know that what we are doing in this +# temp folder is OK. +git config --global --add safe.directory "$GIT_DIR" + +# We clone the $GITHUB_REPOSITORY.wiki Git repo into a temp folder. This is +# a special Git repository that holds a flat file structure of markup files +# that are rendered on the Wiki tab in the GitHub web UI. We clone this repo +# into the aforementioned $GIT_DIR folder. We use the --bare option to make +# the underlying 'git clone' command that's run create just a .git folder +# without pulling out all the initial files (which is the default behaviour). +# So, we'll have a .git-like folder sitting in /tmp/id.1234 which we want to +# use as our .git folder that we commit to and use for the rest of the Git +# stuff. The $GIT_WORK_TREE is already set to use the $INPUT_PATH (likely a +# folder like 'wiki/'). +git clone "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY.wiki.git" "$GIT_DIR" --bare +# This is a trick to make the git CLI think that there should be a worktree too! +# By default, --bare Git repos are pretty inert. We unset this and then use our +# previously configured $GIT_WORK_TREE. +git config --unset core.bare + +# We are using .gitignore syntax for the 'ignore' option. Here's where we put it +# to good use! We then immediately add everything verbosely to "apply" it. +echo "$INPUT_IGNORE" >>"$GIT_DIR/info/exclude" +git add -Av + +# This sets the default author & committer for the Git commit that we make. If +# you want to change this, you can! You can set the $GIT_AUTHOR_* and +# $GIT_COMMITTER_* env vars in your workflow and they should pass down to this +# 'git commit' operation. +git config user.name github-actions[bot] +git config user.email 41898282+github-actions[bot]@users.noreply.github.com +# Allowing an empty commit is way easier than detecting empty commits! This also +# makes semantic sense. If you run this action, it adds a commit to your wiki. +# How large that commit is comes down to your changes. 0 change = commit with 0. +# This works well with the default "Update wiki ${{ github.sha }}" message so +# that even if the commit is empty, the message has the SHA there. +git commit --allow-empty -m "$INPUT_COMMIT_MESSAGE" + +# If we are given 'dry-run: true', then we want to just print changes and stop +# without pushing. This is only used in testing right now. +if [[ $INPUT_DRY_RUN == true ]]; then + echo 'Dry run' + git remote show origin + git show + exit 0 +fi + +# This is the pushing operation! The origin remote looks something like: +# "https://github.com/octocat/awesome.wiki.git" with no token attached. That +# 'gh auth setup-git' is what makes the username & password automagically attach +# to that 'github.com' hostname! We aren't using -u or -f here since there +# shouldn't be a need. +git push origin master From 85a9b505392e976d0457ba3779371766908d0832 Mon Sep 17 00:00:00 2001 From: Jacob Hummer Date: Tue, 16 May 2023 17:02:41 -0500 Subject: [PATCH 3/7] remove dry-run and github-server-url --- index.sh | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/index.sh b/index.sh index b9f90ca..57fb553 100644 --- a/index.sh +++ b/index.sh @@ -14,15 +14,7 @@ set -e # repo that we want to use instead. We use the same var names to make it # familiar. export GITHUB_TOKEN="$INPUT_TOKEN" -export GITHUB_SERVER_URL="$INPUT_GITHUB_SERVER_URL" export GITHUB_REPOSITORY="$INPUT_REPOSITORY" -# This is the default host that gh uses for clones and commands without a repo -# context (a .git folder). We use Bash string magic to get the github.com part -# from a full origin (no pathname) like https://github.com => github.com. The -# '#*//' operation removes '*//' from the start of the string. That's the -# 'https://' chunk. With that gone, we are left with 'github.company.com' or -# something similar. -export GH_HOST="${GITHUB_SERVER_URL#*//}" # We configure some special $GIT_* environment variables to make it so that # we can have our special .git folder (you know, the one that holds all the @@ -62,7 +54,7 @@ git config --global --add safe.directory "$GIT_DIR" # use as our .git folder that we commit to and use for the rest of the Git # stuff. The $GIT_WORK_TREE is already set to use the $INPUT_PATH (likely a # folder like 'wiki/'). -git clone "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY.wiki.git" "$GIT_DIR" --bare +git clone "https://github.com/$GITHUB_REPOSITORY.wiki.git" "$GIT_DIR" --bare # This is a trick to make the git CLI think that there should be a worktree too! # By default, --bare Git repos are pretty inert. We unset this and then use our # previously configured $GIT_WORK_TREE. @@ -86,15 +78,6 @@ git config user.email 41898282+github-actions[bot]@users.noreply.github.com # that even if the commit is empty, the message has the SHA there. git commit --allow-empty -m "$INPUT_COMMIT_MESSAGE" -# If we are given 'dry-run: true', then we want to just print changes and stop -# without pushing. This is only used in testing right now. -if [[ $INPUT_DRY_RUN == true ]]; then - echo 'Dry run' - git remote show origin - git show - exit 0 -fi - # This is the pushing operation! The origin remote looks something like: # "https://github.com/octocat/awesome.wiki.git" with no token attached. That # 'gh auth setup-git' is what makes the username & password automagically attach From d6808bd495be527a41202daebf073b067a3e2b2e Mon Sep 17 00:00:00 2001 From: Jacob Hummer Date: Tue, 16 May 2023 17:09:00 -0500 Subject: [PATCH 4/7] add explainer for user.name & user.email values --- index.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index.sh b/index.sh index 57fb553..d8bba49 100644 --- a/index.sh +++ b/index.sh @@ -68,7 +68,10 @@ git add -Av # This sets the default author & committer for the Git commit that we make. If # you want to change this, you can! You can set the $GIT_AUTHOR_* and # $GIT_COMMITTER_* env vars in your workflow and they should pass down to this -# 'git commit' operation. +# 'git commit' operation. These values are from one of the popular Git commit +# actions: stefanzweifel/git-auto-commit-action [1] +# +# [1]: https://github.com/stefanzweifel/git-auto-commit-action/blob/master/action.yml#L35-L42 git config user.name github-actions[bot] git config user.email 41898282+github-actions[bot]@users.noreply.github.com # Allowing an empty commit is way easier than detecting empty commits! This also From 4f207299a0e5b2ca8588a191a98511c5d7067ace Mon Sep 17 00:00:00 2001 From: Jacob Hummer Date: Tue, 16 May 2023 17:09:19 -0500 Subject: [PATCH 5/7] update readme to match current state --- README.md | 57 ++++++++++++++++++++----------------------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index c38f1b1..0f9c7e2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ @@ -21,31 +22,24 @@ Add a GitHub Actions workflow file to your `.github/workflows/` folder similar to the example shown below. ```yml -name: Wiki +name: Publish wiki on: push: branches: [main] - paths: [wiki/**, .github/workflows/wiki.yml] + paths: + - wiki/** + - .github/workflows/publish-wiki.yml concurrency: - group: wiki + group: publish-wiki cancel-in-progress: true permissions: contents: write jobs: - wiki: + publish-wiki: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: Andrew-Chen-Wang/github-wiki-action@v3 - # ⚠️ We use the env: key to provide our inputs! See #27. - env: - # Make sure this has a slash at the end! We use wiki/ by default. - WIKI_DIR: my-octocat-wiki/ - # You MUST manually pass in the GitHub token. - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # These are currently REQUIRED options - GH_MAIL: actions@users.noreply.github.com - GH_NAME: actions[bot] + - uses: Andrew-Chen-Wang/github-wiki-action@v4 ``` Screenshot of 'Create the first page' button @@ -82,32 +76,23 @@ workflow `.yml` file) you'll always need to use a GitHub PAT. ### Options -⚠️ This action uses `env:` to supply these options, not `with:`! +- **`repository`:** The repository housing the wiki. Use this if you're + publishing to a wiki that's not the current repository. You can change the + GitHub server with the `github-server-url` input. Default is + `${{ github.repository }}`. -- **`GH_TOKEN`:** The GitHub API token to use. This is usually - `${{ secrets.GITHUB_TOKEN }}` or `${{ github.token }}` (they are the same). - This is **required**. +- **`token`:** `${{ github.token }}` is the default. This token is used when + cloning and pushing wiki changes. -- **`GH_MAIL`:** You must specify an email address to be associated with the - commit that we make to the wiki. This is **required**. +- **`path`:** The directory to use for your wiki contents. Default `wiki/`. -- **`GH_NAME`:** In addition to an email, you must also specify a username to - tie to the commit that we make. This is **required**. +- **`commit-message`:** The message to use when committing new content. Default + is `Update wiki ${{ github.sha }}`. You probably don't need to change this, + since this only applies if you look really closely in your wiki. -- **`WIKI_DIR`:** This is the directory to process and publish to the wiki. - Usually it's something like `wiki/` or `docs/`. The default is `wiki/`. - -- **`EXCLUDED_FILES`:** The files or directories you want to exclude. This _can_ - be a glob pattern. By default, we include everything. - -- **`REPO`:** The repository to push to. This is useful if you want to push to a - different repository than the one that houses the workflow file. This should - be in the format `owner/repo`. The default is `${{ github.repository }}` (the - current repo). - -- **`WIKI_PUSH_MESSAGE`:** The commit message to use when pushing to the wiki. - This is useful if you want to customize the commit message. The default is the - latest commit message from the main Git repo. +- **`ignore`:** A multiline list of files that should be ignored when committing + and pushing to the remote wiki. Each line is a pattern like `.gitignore`. Make + sure these paths are relative to the path option! The default is none. [github.com/settings/personal-access-tokens]: https://github.com/settings/personal-access-tokens From 74c78c8a52b519bbf82f7e5a919900f3c3215989 Mon Sep 17 00:00:00 2001 From: Jacob Hummer Date: Tue, 16 May 2023 17:14:31 -0500 Subject: [PATCH 6/7] remove id --- action.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 935c709..7b9f223 100644 --- a/action.yml +++ b/action.yml @@ -44,8 +44,7 @@ inputs: runs: using: composite steps: - - id: index - run: '"${GITHUB_ACTION_PATH%/}/index.sh"' + - run: '"${GITHUB_ACTION_PATH%/}/index.sh"' shell: bash env: INPUT_REPOSITORY: ${{ inputs.repository }} From 142ff4f944f34b9da7c9cfb922e8d14c907d8f90 Mon Sep 17 00:00:00 2001 From: Jacob Hummer Date: Tue, 16 May 2023 20:15:02 -0500 Subject: [PATCH 7/7] use correct option name --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0f9c7e2..28aff3a 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,9 @@ jobs: GitHub wiki Git-based storage backend that we then push to in this Action. After creating your workflow file, now all you need is to put your Markdown -files in a `wiki/` folder (or whatever you set the `WIKI_DIR` option to) and -commit them to your default branch to trigger the workflow (or whatever other -trigger you set up). +files in a `wiki/` folder (or whatever you set the `wiki` option to) and commit +them to your default branch to trigger the workflow (or whatever other trigger +you set up). 💡 Each page has an auto-generated title. It is derived from the filename by replacing every `-` (dash) character with a space. Name your files accordingly.