diff --git a/README.md b/README.md index 69641bd..8738688 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Configure the action with a branch on your `target` repo - the one you want to u | Name | Required? | Default | Example | | -------------------------- | :----------------: | ------- | ---------------------------------------- | +| target_sync_repo | :white_check_mark: | | | | target_sync_branch | :white_check_mark: | | 'master', 'main', 'my-branch' | | target_repo_token | :white_check_mark: | | ${{ secrets.GITHUB_TOKEN }} | | upstream_repo_access_token | | | ${{ secrets.NAME_OF_TOKEN }} | @@ -39,7 +40,8 @@ Configure the action with a branch on your `target` repo - the one you want to u | upstream_sync_branch | :white_check_mark: | | 'master', 'main', 'my-branch' | | test_mode | | false | true / false | -**Always** set `target_repo_token` to `${{ secrets.GITHUB_TOKEN }}` so the action can push to your target repo. +`target_sync_repo` can ***only*** be a repo in which you have owner access. +If it corresponds to the repo in which the workflow is being used set `target_repo_token` as `${{ secrets.GITHUB_TOKEN }}`, otherwise `target_repo_token` should be a **[Private Access Token](https://github.com/aormsby/Fork-Sync-With-Upstream-action/wiki/Setup-Access-Token)** (`persist-credentials: false` is also **[needed](https://github.com/aormsby/Fork-Sync-With-Upstream-action/wiki/Configuration#private)**) > For more information on optional input variables, advanced configurations, and working with private repos, see [Wiki - Configuration](https://github.com/aormsby/Fork-Sync-With-Upstream-action/wiki/Configuration) @@ -91,8 +93,9 @@ jobs: id: sync uses: aormsby/Fork-Sync-With-Upstream-action@v3.4.1 with: + target_sync_repo: my-repo target_sync_branch: my-branch - # REQUIRED 'target_repo_token' exactly like this! + # can also be target_repo_token: ${{ secrets.MY_TOKEN }} (see Input Variables) target_repo_token: ${{ secrets.GITHUB_TOKEN }} upstream_sync_branch: main upstream_sync_repo: aormsby/Fork-Sync-With-Upstream-action diff --git a/action.yaml b/action.yaml index 85f53a6..ba0f4a9 100644 --- a/action.yaml +++ b/action.yaml @@ -7,6 +7,10 @@ branding: color: orange inputs: + target_sync_repo: + description: 'Repo receiving updates from the upstream repo' + required: true + target_sync_branch: description: 'Branch receiving updates from the upstream repo, e.g. => main, master, prod' required: true diff --git a/entry/config_and_run.sh b/entry/config_and_run.sh index 0e00a11..f30458f 100755 --- a/entry/config_and_run.sh +++ b/entry/config_and_run.sh @@ -29,7 +29,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "${GITHUB_ACTIONS}" = false ]; then # shellcheck disable=SC2034 INPUT_TARGET_REPO_TOKEN="" # shellcheck disable=SC2034 - GITHUB_REPOSITORY="" + INPUT_TARGET_SYNC_REPO="" # required vars (except token) # shellcheck disable=SC2034 @@ -62,6 +62,14 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "${GITHUB_ACTIONS}" = false ]; then INPUT_HOST_DOMAIN='github.com' fi +if [ -z "${INPUT_TARGET_REPO_TOKEN}" ]; then + # shellcheck disable=SC2034 + TARGET_REPO_URL="https://${INPUT_HOST_DOMAIN}/${INPUT_TARGET_SYNC_REPO}.git" +else + # shellcheck disable=SC2034 + TARGET_REPO_URL="https://${GITHUB_ACTOR}:${INPUT_TARGET_REPO_TOKEN}@${INPUT_HOST_DOMAIN}/${INPUT_TARGET_SYNC_REPO}.git" +fi + if [ -z "${INPUT_UPSTREAM_REPO_ACCESS_TOKEN}" ]; then # shellcheck disable=SC2034 UPSTREAM_REPO_URL="https://${INPUT_HOST_DOMAIN}/${INPUT_UPSTREAM_SYNC_REPO}.git" diff --git a/entry/run_action.sh b/entry/run_action.sh index e923215..1b96eb8 100755 --- a/entry/run_action.sh +++ b/entry/run_action.sh @@ -7,6 +7,10 @@ . "${ACTION_PARENT_DIR}"/run/config_git.sh config_for_action +# set target repo +. "${ACTION_PARENT_DIR}"/run/set_target_repo.sh +set_target + # checkout target branch in target repo . "${ACTION_PARENT_DIR}"/run/checkout_branch.sh checkout diff --git a/entry/run_tests.sh b/entry/run_tests.sh index a32a83f..6fc52d9 100755 --- a/entry/run_tests.sh +++ b/entry/run_tests.sh @@ -13,6 +13,11 @@ test_upstream_branch_exists test_has_upstream_repo_access cleanup_test_dir +# shellcheck disable=SC1091 +. "${ACTION_PARENT_DIR}"/test/verify_target_access.sh +test_has_target_repo_access +cleanup_test_dir + # shellcheck disable=SC1091 . "${ACTION_PARENT_DIR}"/test/verify_git_config.sh test_config_git diff --git a/run/push_updates.sh b/run/push_updates.sh index 3e0f1a4..62e68d6 100644 --- a/run/push_updates.sh +++ b/run/push_updates.sh @@ -7,7 +7,7 @@ push_new_commits() { # TODO: figure out how this would work in local mode... # update remote url with token since it is not persisted during checkout step when syncing from a private repo if [ -n "${INPUT_TARGET_REPO_TOKEN}" ]; then - git remote set-url origin "https://${GITHUB_ACTOR}:${INPUT_TARGET_REPO_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" + git remote set-url origin "https://${GITHUB_ACTOR}:${INPUT_TARGET_REPO_TOKEN}@github.com/${INPUT_TARGET_SYNC_REPO}.git" fi # shellcheck disable=SC2086 diff --git a/run/set_target_repo.sh b/run/set_target_repo.sh new file mode 100644 index 0000000..fcda544 --- /dev/null +++ b/run/set_target_repo.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +set_target() { + write_out -1 "Setting target repo to '${INPUT_TARGET_SYNC_REPO}'." + git remote add origin "${TARGET_REPO_URL}" + + # # exit if target can't be accessed + # if ! git ls-remote -h "${TARGET_REPO_URL}" --quiet; then + # write_out "$?" "Could not verify target repo." + # fi + + write_out "g" "SUCCESS\n" +} diff --git a/test/verify_branches.sh b/test/verify_branches.sh index 500f5bd..77696ff 100644 --- a/test/verify_branches.sh +++ b/test/verify_branches.sh @@ -1,9 +1,23 @@ #!/bin/sh +test_target_repo_exists() { + write_out "y" "TEST" + write_out -1 "[Verify Target Sync Repo Exists] -> tests 'target_sync_repo' input" + VERIFY_TARGET_REPO=$(git ls-remote "${TARGET_REPO_URL}" --quiet) + + # var is empty on success, so fail if return value has any data + if [ -n "${VERIFY_TARGET_REPO}" ]; then + write_out "r" "FAILED - Target repo '${INPUT_TARGET_SYNC_REPO}' not found OR you do not have permission to view it\n" + else + write_out "g" "PASSED\n" + fi + +} + test_target_branch_exists() { write_out "y" "TEST" write_out -1 "[Verify Target Sync Branch] -> tests 'target_sync_branch' input" - VERIFY_TARGET_BRANCH=$(git rev-parse --verify "remotes/origin/${INPUT_TARGET_SYNC_BRANCH}") + VERIFY_TARGET_BRANCH=$(git ls-remote "${TARGET_REPO_URL}" "${INPUT_TARGET_SYNC_BRANCH}" --quiet) if [ -z "${VERIFY_TARGET_BRANCH}" ]; then write_out "r" "FAILED - no branch '${INPUT_TARGET_SYNC_BRANCH}' to run action on\nDid you set 'ref' correctly in the checkout step?\n" diff --git a/test/verify_target_access.sh b/test/verify_target_access.sh new file mode 100644 index 0000000..b73944e --- /dev/null +++ b/test/verify_target_access.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +TEST_CLONE_DIR="fork-action-test-clone-dir" +SKIP_CLEANUP=false + +# in case test dir already exits, delete it +pretest_remove_dir() { + rm -rf "${TEST_CLONE_DIR}" +} + +test_has_target_repo_access() { + pretest_remove_dir + + write_out "y" "TEST" + write_out -1 "[Target Repo Access] -> Try to clone private repo with access token / git clone should succeed" + + git clone --quiet --depth 1 "${TARGET_REPO_URL}" "${TEST_CLONE_DIR}" + COMMAND_EXIT_CODE=$? + + if [ "${COMMAND_EXIT_CODE}" -eq "0" ]; then + write_out "g" "PASSED" # no \n because of cleanup output + else + write_out "r" "FAILED - repo does not exist OR you do not have permission to clone from it\n" + SKIP_CLEANUP=true + fi +} + +# remove test directory after clone is complete +cleanup_test_dir() { + if [ "${SKIP_CLEANUP}" = true ]; then + true # no-op skip + else + rm -rf "${TEST_CLONE_DIR}" + COMMAND_STATUS=$? + + # warn if cloned test directory can't be removed + if [ "${COMMAND_STATUS}" != 0 ] ; then + write_out "r" "(Clone cleanup failed - please find and remove directory '${TEST_CLONE_DIR}')\n" + else + write_out -1 "(Clone directory cleanup successful.)\n" + fi + fi +} \ No newline at end of file