Skip to content

Commit

Permalink
Merge pull request #24 from andstor/develop
Browse files Browse the repository at this point in the history
v3.0.0
  • Loading branch information
andstor authored Mar 10, 2020
2 parents beb01c3 + f8e71cd commit b14e6d3
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 31 deletions.
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org).

## [Unreleased]

## [3.0.0] - 2020-03-10
### Added
- Input variable `clean` for optional removal of contents in the `dst_path` before copying.
- Input variable `exclude` for path exclusion filter with glob patterns.
- Input variable `filter` for path filtering with glob patterns.
### Changed
- Renamed input variable `src_filter` to `file_filter`.

## [2.0.0] - 2020-02-23

## [1.1.0] - 2019-08-29

## [1.0.1] - 2019-07-09

## 1.0.0 - 2019-07-09

[Unreleased]: https://github.com/andstor/copycat-action/compare/v3.0.0...HEAD
[3.0.0]: https://github.com/andstor/copycat-action/compare/v2.0.0...v3.0.0
[2.0.0]: https://github.com/andstor/copycat-action/compare/v1.1.0...v2.0.0
[1.1.0]: https://github.com/andstor/copycat-action/compare/v1.1.0...v1.0.1
[1.0.1]: https://github.com/andstor/copycat-action/compare/v1.0.1...v1.0.1
[1.0.1]: https://github.com/andstor/copycat-action/compare/v1.0.0...v1.0.1
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM alpine:3.10

RUN apk add --no-cache bash
RUN apk add --no-cache git

COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
ENTRYPOINT ["/bin/bash", "-c", "/entrypoint.sh"]
32 changes: 24 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The following example [workflow step](https://help.github.com/en/actions/configu

```yml
- name: Copy
uses: andstor/copycat-action@v2
uses: andstor/copycat-action@v3
with:
personal_token: ${{ secrets.PERSONAL_TOKEN }}
src_path: /.
Expand All @@ -30,22 +30,38 @@ The following input variable options can/must be configured:
|Input variable|Necessity|Description|Default|
|--------------------|--------|-----------|-------|
|`src_path`|Required|The source path to the file(s) or folder(s) to copy from. For example, `/.` or `path/to/home.md`.||
|`dst_path`|Optional|The destination path to copy the file(s) or folder(s) to. For example, `/wiki/` or `path/to/index.md`. |`src_path`|
|`dst_owner`|Required|The name of the owner of the repository to push to. For example, `andstor`.||
|`dst_repo_name`|Required|The name of the repository to push to. For example, `copycat-action`.||
|`src_path`|Required|The source path to the file(s) or folder(s) to copy from. For example `/.` or `path/to/home.md`.||
|`dst_path`|Optional|The destination path to copy the file(s) or folder(s) to. For example `/wiki/` or `path/to/index.md`. |`src_path`|
|`dst_owner`|Required|The name of the owner of the repository to push to. For example `andstor`.||
|`dst_repo_name`|Required|The name of the repository to push to. For example `copycat-action`.||
|`src_branch`|Optional|The branch name of the source repository.|`master`|
|`dst_branch`|Optional|The branch name of the destination repository.|`master`|
|`src_filter`|Optional|A pattern for filtering files to be copied. For example `*.sh`||
|`clean`|Optional|Set to `true` if the `dst_path` should be emptied before copying.|`false`|
|`file_filter`|Optional|A simple [pattern](https://www.gnu.org/software/findutils/manual/html_mono/find.html#Shell-Pattern-Matching) for filtering files to be copied. Acts on file basename. For example `*.sh`.||
|`filter`|Optional|A glob pattern for filtering files to be copied. Acts on file paths. For example `**/!(*.*)`.||
|`exclude`|Optional|A glob pattern for excluding paths. For example `*/tests/*`.||
|`src_wiki`|Optional|Set to `true` if the source repository you want to copy from is the GitHub Wiki.| `false`|
|`dst_wiki`|Optional|Set to `true` if the destination repository you want to copy from is the GitHub Wiki.|`false`|
|`username`|Optional|The GitHub username to associate commits made by this GitHub action.|[`GITHUB_ACTOR`](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables)|
|`email`|Optional|The email used for associating commits made by this GitHub action.|[`GITHUB_ACTOR`](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables)`@users.noreply.github.com`|
|`email`|Optional|The email used for associating commits made by this GitHub action.|[`GITHUB_ACTOR`](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables) `@users.noreply.github.com`|

## Secrets

* `personal_token`: (required) GitHub Private Access Token used for the clone/push operations. To create it follow the [GitHub Documentation](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line).

## Filtering
Copycat provides several ways of filtering which files you want to copy.
All three types of filtering can be applied simultaneously.

### Input variables
#### `file_filter`
The `file_filter`input variable allows you to filter file basenames. Hence, you can for example only copy all text files by setting `file_filter`to `*.txt`. The variable only accepts simple [patterns](https://www.gnu.org/software/findutils/manual/html_mono/find.html#Shell-Pattern-Matching).

#### `filter`
The `filter` input variable provides extensive globbing support. It also supports extended globbing and globstar. The globbing applies to file paths. So, to for example match all files that doesn't have a file extention, the pattern could look like `**/!(*.*)`.

#### `exclude`
The `exclude` input variable can be used to exclude certain paths. It will apply to the file paths. One are for example able to exclude certain deirectory names. Setting `exclude` to `*/tests/*` results in only copying files that don't lie inside a folder named `tests` (both directly and indirectly). Here, a file with for example the path `foo/tests/bar/baz.txt` would not be copied over.

## Examples

Expand All @@ -63,7 +79,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Copycat
uses: andstor/copycat-action@v2
uses: andstor/copycat-action@v3
with:
personal_token: ${{ secrets.PERSONAL_TOKEN }}
src_path: /.
Expand Down
19 changes: 16 additions & 3 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,18 @@ inputs:
description: 'The branch name of the destination repository'
required: false
default: 'master'
src_filter:
description: 'A pattern for filtering files to be copied'
clean:
description: 'Set to true if the dst_path should be emptied before copying'
default: false
required: false
file_filter:
description: 'A glob pattern for filtering file names'
required: false
filter:
description: 'A glob pattern for filtering file paths to be included for copying'
required: false
exclude:
description: 'A glob pattern for excluding paths'
required: false
src_wiki:
description: 'Set to true if the source repository you want to copy from is the GitHub Wiki'
Expand All @@ -56,7 +66,10 @@ runs:
- ${{ inputs.dst_repo_name }}
- ${{ inputs.src_branch }}
- ${{ inputs.dst_branch }}
- ${{ inputs.src_filter }}
- ${{ inputs.clean }}
- ${{ inputs.file_filter }}
- ${{ inputs.filter }}
- ${{ inputs.exclude }}
- ${{ inputs.src_wiki }}
- ${{ inputs.dst_wiki }}
- ${{ inputs.username }}
Expand Down
75 changes: 56 additions & 19 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,37 +1,43 @@
#!/bin/sh
#!/bin/bash
#
# @author André Storhaug <[email protected]>
# @date 2020-02-22
# @date 2020-03-09
# @license MIT
# @version 2.0.0
# @version 3.0.0

set -o pipefail

shopt -s extglob globstar nullglob dotglob

PERSONAL_TOKEN="$INPUT_PERSONAL_TOKEN"
SRC_PATH="$INPUT_SRC_PATH"
DST_PATH="$INPUT_DST_PATH"
DST_OWNER="$INPUT_DST_OWNER"
DST_REPO_NAME="$INPUT_DST_REPO_NAME"
SRC_BRANCH="$INPUT_SRC_BRANCH"
DST_BRANCH="$INPUT_DST_BRANCH"
CLEAN="$INPUT_CLEAN"
FILE_FILTER="$INPUT_FILE_FILTER"
FILTER="$INPUT_FILTER"
EXCLUDE="$INPUT_EXCLUDE"
SRC_WIKI="$INPUT_SRC_WIKI"
DST_WIKI="$INPUT_DST_WIKI"
USERNAME="$INPUT_USERNAME"
EMAIL="$INPUT_EMAIL"

if [[ -z "$SRC_PATH" ]]; then
echo "SRC_PATH environment variable is missing. Cannot proceed."
exit 1
echo "SRC_PATH environment variable is missing. Cannot proceed."
exit 1
fi

if [[ -z "$DST_OWNER" ]]; then
echo "DST_OWNER environment variable is missing. Cannot proceed."
exit 1
echo "DST_OWNER environment variable is missing. Cannot proceed."
exit 1
fi

if [[ -z "$DST_REPO_NAME" ]]; then
echo "DST_REPO_NAME environment variable is missing. Cannot proceed."
exit 1
echo "DST_REPO_NAME environment variable is missing. Cannot proceed."
exit 1
fi

if [ "$SRC_WIKI" = "true" ]; then
Expand All @@ -46,6 +52,10 @@ else
DST_WIKI=""
fi

if [[ -n "$EXCLUDE" && -z "$FILTER" ]]; then
FILTER="**"
fi

BASE_PATH=$(pwd)
DST_PATH="${DST_PATH:-${SRC_PATH}}"

Expand All @@ -60,15 +70,15 @@ SRC_REPO_NAME="${GITHUB_REPOSITORY#*/}${SRC_WIKI}"
DST_REPO="${DST_OWNER}/${DST_REPO_NAME}${DST_WIKI}"
DST_REPO_NAME="${DST_REPO_NAME}${DST_WIKI}"

DIR="${DST_PATH%/*}"
FINAL_SOURCE="${SRC_REPO_NAME}/${SRC_PATH}"

git config --global user.name "${USERNAME}"
git config --global user.email "${EMAIL}"

if [[ -z "$SRC_FILTER" ]]; then
if [[ -z "$FILE_FILTER" ]]; then
echo "Copying \"${SRC_REPO_NAME}/${SRC_PATH}\" and pushing it to ${GITHUB_REPOSITORY}"
else
echo "Copying files matching \"${SRC_FILTER}\" from \"${SRC_REPO_NAME}/${SRC_PATH}\" and pushing it to ${GITHUB_REPOSITORY}"
echo "Copying files matching \"${FILE_FILTER}\" from \"${SRC_REPO_NAME}/${SRC_PATH}\" and pushing it to ${GITHUB_REPOSITORY}"
fi

git clone --branch ${SRC_BRANCH} --single-branch --depth 1 https://${PERSONAL_TOKEN}@github.com/${SRC_REPO}.git
Expand All @@ -78,8 +88,25 @@ if [ "$?" -ne 0 ]; then
fi
rm -rf ${SRC_REPO_NAME}/.git

if [[ -n "$SRC_FILTER" ]]; then
find ${SRC_REPO_NAME}/ -type f -not -name "${SRC_FILTER}" -exec rm {} \;
if [[ -n "$FILE_FILTER" ]]; then
find ${SRC_REPO_NAME}/ -type f -not -name "${FILE_FILTER}" -exec rm {} \;
fi

if [[ -n "$FILTER" ]]; then
tmp_dir=$(mktemp -d -t ci-XXXXXXXXXX)
mkdir ${temp_dir}/${SRC_REPO_NAME}
cd ${SRC_REPO_NAME}
FINAL_SOURCE="${tmp_dir}/${SRC_REPO_NAME}/${SRC_PATH}"
for f in ${FILTER} ; do
[ -e "$f" ] || continue
[ -d "$f" ] && continue
if [[ -n "$EXCLUDE" ]] ; then
[[ $f == $EXCLUDE ]] && continue
fi
file_dir=$(dirname "${f}")
mkdir -p ${tmp_dir}/${SRC_REPO_NAME}/${file_dir} && cp ${f} ${tmp_dir}/${SRC_REPO_NAME}/${file_dir}
done
cd ..
fi

git clone --branch ${DST_BRANCH} --single-branch --depth 1 https://${PERSONAL_TOKEN}@github.com/${DST_REPO}.git
Expand All @@ -88,14 +115,24 @@ if [ "$?" -ne 0 ]; then
exit 1
fi

mkdir -p ${DST_REPO_NAME}/${DIR} || exit "$?"
cp -rf ${SRC_REPO_NAME}/${SRC_PATH} ${DST_REPO_NAME}/${DST_PATH} || exit "$?"
if [ "$CLEAN" = "true" ]; then
if [ -f "${DST_REPO_NAME}/${DST_PATH}" ] ; then
find ${DST_REPO_NAME}/${DST_PATH} -type f -not -path '*/\.git/*' -delete
elif [ -d "${DST_REPO_NAME}/${DST_PATH}" ] ; then
find ${DST_REPO_NAME}/${DST_PATH%/*}/* -type f -not -path '*/\.git/*' -delete
else
echo >&2 "Nothing to clean 🧽"
fi
fi

mkdir -p ${DST_REPO_NAME}/${DST_PATH%/*} || exit "$?"
cp -rf ${FINAL_SOURCE} ${DST_REPO_NAME}/${DST_PATH} || exit "$?"
cd ${DST_REPO_NAME} || exit "$?"

if [ -d "${BASE_PATH}/${SRC_REPO_NAME}/${SRC_PATH}" ]; then
COMMIT_MESSAGE="Update file(s) in \"${SRC_PATH}\" from \"${GITHUB_REPOSITORY}\""
if [ -f "${BASE_PATH}/${FINAL_SOURCE}" ]; then
COMMIT_MESSAGE="Update file in \"${SRC_PATH}\" from \"${GITHUB_REPOSITORY}\""
else
COMMIT_MESSAGE="Update file \"${SRC_PATH}\" from \"${GITHUB_REPOSITORY}\""
COMMIT_MESSAGE="Update file(s) \"${SRC_PATH}\" from \"${GITHUB_REPOSITORY}\""
fi

if [ -z "$(git status --porcelain)" ]; then
Expand Down

0 comments on commit b14e6d3

Please sign in to comment.