Merge a2e083e01c8506d549d0db9a27115146dfa280aa into cbe757f8d8b380dd2b3ceec5a80fbcd61f1f3107

This commit is contained in:
PWall 2023-05-10 11:27:19 +02:00 committed by GitHub
commit 92fa8faac4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 295 additions and 66 deletions

9
.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[submodule "test/bats"]
path = test/bats
url = https://github.com/bats-core/bats-core.git
[submodule "test/test_helper/bats-support"]
path = test/test_helper/bats-support
url = https://github.com/bats-core/bats-support.git
[submodule "test/test_helper/bats-assert"]
path = test/test_helper/bats-assert
url = https://github.com/bats-core/bats-assert.git

View File

@ -3,5 +3,6 @@ FROM alpine:latest
RUN apk add --no-cache git git-lfs openssh-client
COPY entrypoint.sh /entrypoint.sh
COPY functions.sh /functions.sh
ENTRYPOINT ["/entrypoint.sh"]

View File

@ -3,19 +3,10 @@
set -e # if a command fails it stops the execution
set -u # script fails if trying to access to an undefined variable
. ./functions.sh
echo "[+] Action start"
SOURCE_BEFORE_DIRECTORY="${1}"
SOURCE_DIRECTORY="${2}"
DESTINATION_GITHUB_USERNAME="${3}"
DESTINATION_REPOSITORY_NAME="${4}"
GITHUB_SERVER="${5}"
USER_EMAIL="${6}"
USER_NAME="${7}"
DESTINATION_REPOSITORY_USERNAME="${8}"
TARGET_BRANCH="${9}"
COMMIT_MESSAGE="${10}"
TARGET_DIRECTORY="${11}"
CREATE_TARGET_BRANCH_IF_NEEDED="${12}"
getArgs "$@"
if [ -z "$DESTINATION_REPOSITORY_USERNAME" ]
then
@ -32,24 +23,11 @@ fi
if [ -n "${SSH_DEPLOY_KEY:=}" ]
then
echo "[+] Using SSH_DEPLOY_KEY"
# Inspired by https://github.com/leigholiver/commit-with-deploy-key/blob/main/entrypoint.sh , thanks!
mkdir --parents "$HOME/.ssh"
DEPLOY_KEY_FILE="$HOME/.ssh/deploy_key"
echo "${SSH_DEPLOY_KEY}" > "$DEPLOY_KEY_FILE"
chmod 600 "$DEPLOY_KEY_FILE"
SSH_KNOWN_HOSTS_FILE="$HOME/.ssh/known_hosts"
ssh-keyscan -H "$GITHUB_SERVER" > "$SSH_KNOWN_HOSTS_FILE"
export GIT_SSH_COMMAND="ssh -i "$DEPLOY_KEY_FILE" -o UserKnownHostsFile=$SSH_KNOWN_HOSTS_FILE"
GIT_CMD_REPOSITORY="git@$GITHUB_SERVER:$DESTINATION_REPOSITORY_USERNAME/$DESTINATION_REPOSITORY_NAME.git"
sshDeployKey
elif [ -n "${API_TOKEN_GITHUB:=}" ]
then
echo "[+] Using API_TOKEN_GITHUB"
GIT_CMD_REPOSITORY="https://$DESTINATION_REPOSITORY_USERNAME:$API_TOKEN_GITHUB@$GITHUB_SERVER/$DESTINATION_REPOSITORY_USERNAME/$DESTINATION_REPOSITORY_NAME.git"
githubToken
else
echo "::error::API_TOKEN_GITHUB and SSH_DEPLOY_KEY are empty. Please fill one (recommended the SSH_DEPLOY_KEY)"
exit 1
@ -65,29 +43,10 @@ echo "[+] Enable git lfs"
git lfs install
echo "[+] Cloning destination git repository $DESTINATION_REPOSITORY_NAME"
# Setup git
git config --global user.email "$USER_EMAIL"
git config --global user.name "$USER_NAME"
setupGit
{
git clone --single-branch --depth 1 --branch "$TARGET_BRANCH" "$GIT_CMD_REPOSITORY" "$CLONE_DIR"
} || {
if [ "$CREATE_TARGET_BRANCH_IF_NEEDED" = "true" ]
then
# Default branch of the repository is cloned. Later on the required branch
# will be created
git clone --single-branch --depth 1 "$GIT_CMD_REPOSITORY" "$CLONE_DIR"
else
false
fi
} || {
echo "::error::Could not clone the destination repository. Command:"
echo "::error::git clone --single-branch --branch $TARGET_BRANCH $GIT_CMD_REPOSITORY $CLONE_DIR"
echo "::error::(Note that if they exist USER_NAME and API_TOKEN is redacted by GitHub)"
echo "::error::Please verify that the target repository exist AND that it contains the destination branch name, and is accesible by the API_TOKEN_GITHUB OR SSH_DEPLOY_KEY"
exit 1
cloneRepo
}
ls -la "$CLONE_DIR"
TEMP_DIR=$(mktemp -d)
@ -117,19 +76,7 @@ echo "[+] List contents of $SOURCE_DIRECTORY"
ls "$SOURCE_DIRECTORY"
echo "[+] Checking if local $SOURCE_DIRECTORY exist"
if [ ! -d "$SOURCE_DIRECTORY" ]
then
echo "ERROR: $SOURCE_DIRECTORY does not exist"
echo "This directory needs to exist when push-to-another-repository is executed"
echo
echo "In the example it is created by ./build.sh: https://github.com/cpina/push-to-another-repository-example/blob/main/.github/workflows/ci.yml#L19"
echo
echo "If you want to copy a directory that exist in the source repository"
echo "to the target repository: you need to clone the source repository"
echo "in a previous step in the same build section. For example using"
echo "actions/checkout@v2. See: https://github.com/cpina/push-to-another-repository-example/blob/main/.github/workflows/ci.yml#L16"
exit 1
fi
checkSource
echo "[+] Copying contents of source repository folder $SOURCE_DIRECTORY to folder $TARGET_DIRECTORY in git repo $DESTINATION_REPOSITORY_NAME"
cp -ra "$SOURCE_DIRECTORY"/. "$CLONE_DIR/$TARGET_DIRECTORY"
@ -147,11 +94,7 @@ echo "[+] Set directory is safe ($CLONE_DIR)"
# TODO: review before releasing it as a version
git config --global --add safe.directory "$CLONE_DIR"
if [ "$CREATE_TARGET_BRANCH_IF_NEEDED" = "true" ]
then
git switch -c "$TARGET_BRANCH"
fi
switchBranch
echo "[+] Adding git commit"
git add .

89
functions.sh Normal file
View File

@ -0,0 +1,89 @@
#!/bin/sh
getArgs() {
SOURCE_BEFORE_DIRECTORY="${1}"
SOURCE_DIRECTORY="${2}"
DESTINATION_GITHUB_USERNAME="${3}"
DESTINATION_REPOSITORY_NAME="${4}"
GITHUB_SERVER="${5}"
USER_EMAIL="${6}"
USER_NAME="${7}"
DESTINATION_REPOSITORY_USERNAME="${8}"
TARGET_BRANCH="${9}"
COMMIT_MESSAGE="${10}"
TARGET_DIRECTORY="${11}"
CREATE_TARGET_BRANCH_IF_NEEDED="${12}"
}
sshDeployKey() {
mkdir --parents "$HOME/.ssh"
DEPLOY_KEY_FILE="$HOME/.ssh/deploy_key"
echo "${SSH_DEPLOY_KEY}" > "$DEPLOY_KEY_FILE"
chmod 600 "$DEPLOY_KEY_FILE"
SSH_KNOWN_HOSTS_FILE="$HOME/.ssh/known_hosts"
ssh-keyscan -H "$GITHUB_SERVER" > "$SSH_KNOWN_HOSTS_FILE"
export GIT_SSH_COMMAND="ssh -i "$DEPLOY_KEY_FILE" -o UserKnownHostsFile=$SSH_KNOWN_HOSTS_FILE"
GIT_CMD_REPOSITORY="git@$GITHUB_SERVER:$DESTINATION_REPOSITORY_USERNAME/$DESTINATION_REPOSITORY_NAME.git"
}
githubToken() {
GIT_CMD_REPOSITORY="https://$DESTINATION_REPOSITORY_USERNAME:$API_TOKEN_GITHUB@$GITHUB_SERVER/$DESTINATION_REPOSITORY_USERNAME/$DESTINATION_REPOSITORY_NAME.git"
}
setupGit() {
git config --global user.email "$USER_EMAIL"
git config --global user.name "$USER_NAME"
}
cloneSimple() {
git clone --single-branch --depth 1 --branch "$TARGET_BRANCH" "$GIT_CMD_REPOSITORY" "$CLONE_DIR"
}
cloneCreateBranch() {
if [ "$CREATE_TARGET_BRANCH_IF_NEEDED" = "true" ]
then
# Default branch of the repository is cloned. Later on the required branch
# will be created
git clone --single-branch --depth 1 "$GIT_CMD_REPOSITORY" "$CLONE_DIR"
else
false
fi
}
cloneError() {
echo "::error::Could not clone the destination repository. Command:"
echo "::error::git clone --single-branch --branch $TARGET_BRANCH $GIT_CMD_REPOSITORY $CLONE_DIR"
echo "::error::(Note that if they exist USER_NAME and API_TOKEN is redacted by GitHub)"
echo "::error::Please verify that the target repository exist AND that it contains the destination branch name, and is accesible by the API_TOKEN_GITHUB OR SSH_DEPLOY_KEY"
exit 1
}
cloneRepo() {
cloneSimple || cloneCreateBranch || cloneError
}
checkSource() {
if [ ! -d "$SOURCE_DIRECTORY" ]
then
echo "ERROR: $SOURCE_DIRECTORY does not exist"
echo "This directory needs to exist when push-to-another-repository is executed"
echo
echo "In the example it is created by ./build.sh: https://github.com/cpina/push-to-another-repository-example/blob/main/.github/workflows/ci.yml#L19"
echo
echo "If you want to copy a directory that exist in the source repository"
echo "to the target repository: you need to clone the source repository"
echo "in a previous step in the same build section. For example using"
echo "actions/checkout@v2. See: https://github.com/cpina/push-to-another-repository-example/blob/main/.github/workflows/ci.yml#L16"
exit 1
fi
}
switchBranch() {
if [ "$CREATE_TARGET_BRANCH_IF_NEEDED" = "true" ]
then
git switch -c "$TARGET_BRANCH"
fi
}

1
test/bats Submodule

@ -0,0 +1 @@
Subproject commit 4417a96cfc5e4afc493df94eeef8af4eec760163

184
test/test.bats Normal file
View File

@ -0,0 +1,184 @@
#!/bin/sh
set -e
setup() {
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load '../functions.sh'
}
_var_setup() {
SSH_DEPLOY_KEY="SSH TEST"
DESTINATION_REPOSITORY_USERNAME="UserTest"
DESTINATION_REPOSITORY_NAME="RepoTest"
GITHUB_SERVER="github.com"
}
_mockup_repo() {
cd "$1"
git init
git checkout -b main
touch "TEST"
git add ./TEST
git config user.name "Test"
git config user.email "test@example.com"
git commit -m "TEST_COMMIT"
}
@test "Script arguments" {
getArgs 1 2 3 4 5 6 7 8 9 10 11 12
assert [ $SOURCE_BEFORE_DIRECTORY = "1" ]
assert [ $SOURCE_DIRECTORY = "2" ]
assert [ $DESTINATION_GITHUB_USERNAME = "3" ]
assert [ $DESTINATION_REPOSITORY_NAME = "4" ]
assert [ $GITHUB_SERVER = "5" ]
assert [ $USER_EMAIL = "6" ]
assert [ $USER_NAME = "7" ]
assert [ $DESTINATION_REPOSITORY_USERNAME = "8" ]
assert [ $TARGET_BRANCH = "9" ]
assert [ $COMMIT_MESSAGE = "10" ]
assert [ $TARGET_DIRECTORY = "11" ]
assert [ $CREATE_TARGET_BRANCH_IF_NEEDED = "12" ]
}
@test "Create SSH keys" {
_var_setup
HOME="$BATS_TEST_TMPDIR"
GITHUB_KEYS="KNOWN TEST"
ssh-keyscan() {
echo "KNOWN TEST"
}
sshDeployKey
assert [ -d "$BATS_TEST_TMPDIR/.ssh" ]
assert [ -f "$BATS_TEST_TMPDIR/.ssh/deploy_key" ]
assert [ "$(cat $BATS_TEST_TMPDIR/.ssh/deploy_key)" = "$SSH_DEPLOY_KEY" ]
assert [ -f "$BATS_TEST_TMPDIR/.ssh/known_hosts" ]
assert [ "$(cat $BATS_TEST_TMPDIR/.ssh/known_hosts)" = "$GITHUB_KEYS" ]
assert [ "$GIT_CMD_REPOSITORY" = "git@$GITHUB_SERVER:$DESTINATION_REPOSITORY_USERNAME/$DESTINATION_REPOSITORY_NAME.git" ]
assert [ "$GIT_SSH_COMMAND" = "ssh -i $BATS_TEST_TMPDIR/.ssh/deploy_key -o UserKnownHostsFile=$BATS_TEST_TMPDIR/.ssh/known_hosts" ]
}
@test "Put github host in kwown_hosts" {
skip "Network test"
_var_setup
HOME="$BATS_TEST_TMPDIR"
# Get only the ssh keys (not hostnames)
GITHUB_KEYS=$(ssh-keyscan "github.com" | cut -d " " -f 3)
sshDeployKey
for KEY in $GITHUB_KEYS; do
# Check if the ssh keys are in known hosts
assert grep -q "$KEY" "$BATS_TEST_TMPDIR/.ssh/known_hosts"
done
}
@test "Set Github token in GIT_CMD_REPOSITORY" {
_var_setup
API_TOKEN_GITHUB="TokenTest"
githubToken
assert [ "$GIT_CMD_REPOSITORY" = "https://$DESTINATION_REPOSITORY_USERNAME:$API_TOKEN_GITHUB@$GITHUB_SERVER/$DESTINATION_REPOSITORY_USERNAME/$DESTINATION_REPOSITORY_NAME.git" ]
}
@test "Setup git" {
export HOME="$BATS_TEST_TMPDIR"
USER_NAME="TestUser"
USER_EMAIL="TestEmail@example.com"
setupGit
assert [ -f "$BATS_TEST_TMPDIR/.gitconfig" ]
assert grep -q "$USER_NAME" "$BATS_TEST_TMPDIR/.gitconfig"
assert grep -q "$USER_EMAIL" "$BATS_TEST_TMPDIR/.gitconfig"
}
@test "When source directory exist do nothing" {
SOURCE_DIRECTORY="$BATS_TEST_TMPDIR/SourceTest"
mkdir --parents $SOURCE_DIRECTORY
run checkSource
assert_output ""
}
@test "When source directory is missing exit" {
SOURCE_DIRECTORY="$BATS_TEST_TMPDIR/SourceTest"
run checkSource
assert_failure
}
@test "Switch branch when \$CREATE_TARGET is true" {
mkdir "$BATS_TEST_TMPDIR/Repo"
_mockup_repo "$BATS_TEST_TMPDIR/Repo"
CREATE_TARGET_BRANCH_IF_NEEDED="true"
TARGET_BRANCH="TestBranch"
switchBranch
assert [ "$(git branch --show-current --format="%(refname:short)")" = "$TARGET_BRANCH" ]
}
@test "Only switch branch when \$CREATE_TARGET is true" {
mkdir "$BATS_TEST_TMPDIR/Repo"
_mockup_repo "$BATS_TEST_TMPDIR/Repo"
CREATE_TARGET_BRANCH_IF_NEEDED="false"
TARGET_BRANCH="TestBranch"
switchBranch
assert [ "$(git branch --show-current --format="%(refname:short)")" = "main" ]
}
@test "Clone repo (network)" {
skip "Network test"
TARGET_BRANCH="main"
GIT_CMD_REPOSITORY="https://github.com/cpina/github-action-push-to-another-repository.git"
CLONE_DIR="$BATS_TEST_TMPDIR"
run cloneRepo
assert_success
}
@test "Clone repo (local)" {
TARGET_BRANCH="main"
GIT_CMD_REPOSITORY="$BATS_TEST_TMPDIR/Repo"
CLONE_DIR="$BATS_TEST_TMPDIR/RepoCloned"
mkdir --parent "$CLONE_DIR"
mkdir --parent "$GIT_CMD_REPOSITORY"
_mockup_repo "$GIT_CMD_REPOSITORY"
run cloneRepo
assert_success
}
@test "When cloning repo and \$CREATE_TARGET is true create missing branch" {
TARGET_BRANCH="TestBranch"
GIT_CMD_REPOSITORY="$BATS_TEST_TMPDIR/Repo"
CLONE_DIR="$BATS_TEST_TMPDIR/RepoCloned"
CREATE_TARGET_BRANCH_IF_NEEDED="true"
mkdir --parent "$GIT_CMD_REPOSITORY"
_mockup_repo "$GIT_CMD_REPOSITORY"
run cloneRepo
assert_success
}
@test "When cloning with missing branch and \$CREATE_TARGET is false exit" {
TARGET_BRANCH="TestBranch"
GIT_CMD_REPOSITORY="$BATS_TEST_TMPDIR/Repo"
CLONE_DIR="$BATS_TEST_TMPDIR/RepoCloned"
CREATE_TARGET_BRANCH_IF_NEEDED="false"
mkdir --parent "$CLONE_DIR"
mkdir --parent "$GIT_CMD_REPOSITORY"
_mockup_repo "$GIT_CMD_REPOSITORY"
run cloneRepo
assert_failure
}
@test "When cloning non existing repo exit" {
TARGET_BRANCH="TestBranch"
GIT_CMD_REPOSITORY="$BATS_TEST_TMPDIR/Repo"
CLONE_DIR="$BATS_TEST_TMPDIR/RepoCloned"
CREATE_TARGET_BRANCH_IF_NEEDED="false"
run cloneRepo
assert_failure
}
@test "When cloning non existing repo exit (network)" {
TARGET_BRANCH="TestBranch"
GIT_CMD_REPOSITORY="http://example.example/"
CLONE_DIR="$BATS_TEST_TMPDIR/RepoCloned"
CREATE_TARGET_BRANCH_IF_NEEDED="false"
run cloneRepo
assert_failure
}

@ -0,0 +1 @@
Subproject commit 44913ffe6020d1561c4c4d1e26cda8e07a1f374f

@ -0,0 +1 @@
Subproject commit 3c8fadc5097c9acfc96d836dced2bb598e48b009