From 3f98a5677da8b3672179cc78863c611e40643c44 Mon Sep 17 00:00:00 2001 From: Enes Date: Wed, 13 Jul 2022 12:24:20 +0200 Subject: [PATCH] Initial Commit --- .editorconfig | 12 + .gitattributes | 1 + .github/CODEOWNERS | 1 + .github/workflows/build-docker.yml | 59 ++++ .gitignore | 3 + Classes/Config.php | 137 ++++++++ Classes/ConfigFactory.php | 45 +++ Classes/Exception/ConfigurationException.php | 10 + Classes/PublicAccessTokenResolver.php | 35 ++ Classes/Slicer.php | 99 ++++++ Classes/autoload.php | 8 + DockerfileBuild | 13 + LICENSE | 21 ++ ReadMe.md | 53 +++ action.yaml | 58 ++++ bin/git-subsplit.sh | 347 +++++++++++++++++++ entrypoint.php | 9 + 17 files changed, 911 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/build-docker.yml create mode 100644 .gitignore create mode 100644 Classes/Config.php create mode 100644 Classes/ConfigFactory.php create mode 100644 Classes/Exception/ConfigurationException.php create mode 100644 Classes/PublicAccessTokenResolver.php create mode 100644 Classes/Slicer.php create mode 100644 Classes/autoload.php create mode 100644 DockerfileBuild create mode 100644 LICENSE create mode 100644 ReadMe.md create mode 100644 action.yaml create mode 100644 bin/git-subsplit.sh create mode 100644 entrypoint.php diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..cd93830 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +[*.yml] +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..1737133 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @erkenes diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml new file mode 100644 index 0000000..2fcceb4 --- /dev/null +++ b/.github/workflows/build-docker.yml @@ -0,0 +1,59 @@ +name: Build Docker-Image + +on: + push: + tags: [ '*.*.*' ] + +env: + # Use docker.io for Docker Hub if empty + REGISTRY: ghcr.io + # github.repository as / + IMAGE_NAME: ${{ github.repository }} + + +jobs: + build-php: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Workaround: https://github.com/docker/build-push-action/issues/461 + - name: Setup Docker buildx + uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata - php + id: meta-php + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/php + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image - php + id: build-and-push-php + uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a + with: + context: . + file: ./DockerfileBuild + push: true + tags: ${{ steps.meta-php.outputs.tags }} + labels: ${{ steps.meta-php.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c558abb --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +vendor/ +Slicer/git-subsplit-temporary diff --git a/Classes/Config.php b/Classes/Config.php new file mode 100644 index 0000000..07ad901 --- /dev/null +++ b/Classes/Config.php @@ -0,0 +1,137 @@ +repositoryProtocol; + } + + /** + * @return string + */ + public function getRepositoryHost(): string + { + return $this->repositoryHost; + } + + /** + * @return string + */ + public function getRepositoryOrganization(): string + { + return $this->repositoryOrganization; + } + + /** + * @return string + */ + public function getRepositoryName(): string + { + return $this->repositoryName; + } + + /** + * @return string + */ + public function getAccessToken(): string + { + return $this->accessToken; + } + + /** + * @param bool $withAccessToken + * @return string + */ + public function getRepositoryUrl(bool $withAccessToken = false): string + { + $repositoryUrl = $this->repositoryHost . '/' . $this->repositoryOrganization . '/' . $this->repositoryName . '.git'; + + return $withAccessToken ? $this->repositoryProtocol . $this->accessToken . '@' . $repositoryUrl : $this->repositoryProtocol . $repositoryUrl; + } + + /** + * @return string + */ + public function getAllowedRefsPattern(): string + { + return $this->allowedRefsPattern; + } + + public function getSplits(): array + { + return [ + $this->getPackageDirectory() . ':' . $this->getRemoteRepository() + ]; + } + + /** + * @return string + */ + public function getDefaultBranch(): string + { + return $this->defaultBranch; + } + + /** + * @param bool $fullPath + * @return string + */ + public function getTargetBranch(bool $fullPath = false): string + { + return $fullPath ? 'refs/heads/' . $this->targetBranch : $this->targetBranch; + } + + /** + * @return string + */ + public function getPackageDirectory(): string + { + return $this->packageDirectory; + } + + /** + * @return string + */ + public function getRemoteRepository(): string + { + return $this->remoteRepositoryAccessToken + ? $this->insertStringBetween($this->remoteRepository, 'https://', $this->remoteRepositoryAccessToken . '@') + : $this->remoteRepository; + } + + /** + * @return string|null + */ + public function getRemoteRepositoryAccessToken(): ?string + { + return $this->remoteRepositoryAccessToken; + } + + private function insertStringBetween ($string, $keyword, $body): string + { + return substr_replace($string, $body, strpos($string, $keyword) + strlen($keyword), 0); + } +} diff --git a/Classes/ConfigFactory.php b/Classes/ConfigFactory.php new file mode 100644 index 0000000..e56e81d --- /dev/null +++ b/Classes/ConfigFactory.php @@ -0,0 +1,45 @@ +publicAccessTokenResolver = new PublicAccessTokenResolver(); + } + + public function create(array $env): Config + { + $accessToken = $this->publicAccessTokenResolver->resolve($env); + + return $this->createFormEnv($env, $accessToken, self::GITHUB); + } + + protected function createFormEnv(array $env, string $accessToken, string $ciPlatform): Config + { + $envPrefix = $ciPlatform === self::GITHUB ? 'INPUT_' : ''; + + return new Config( + repositoryProtocol: $env[$envPrefix . 'REPOSITORY_PROTOCOL'] ?? throw new ConfigurationException('Repository Protocol is missing'), + repositoryHost: $env[$envPrefix . 'REPOSITORY_HOST'] ?? throw new ConfigurationException('Repository Host is missing'), + repositoryOrganization: $env[$envPrefix . 'REPOSITORY_ORGANIZATION'] ?? throw new ConfigurationException('Repository Organization is missing'), + repositoryName: $env[$envPrefix . 'REPOSITORY_NAME'] ?? throw new ConfigurationException('Repository Name is missing'), + accessToken: $accessToken ?? throw new ConfigurationException('Access Token is missing'), + allowedRefsPattern: $env[$envPrefix . 'ALLOWED_REFS_PATTERN'] ?? throw new ConfigurationException('Allowed Refs Pattern is missing'), + defaultBranch: $env[$envPrefix . 'DEFAULT_BRANCH'] ?? self::DEFAULT_BRANCH, + targetBranch: $env[$envPrefix . 'TARGET_BRANCH'] ?? throw new ConfigurationException('Target Branch is missing'), + packageDirectory: $env[$envPrefix . 'PACKAGE_DIRECTORY'] ?? throw new ConfigurationException('Package Directory is missing'), + remoteRepository: $env[$envPrefix . 'REMOTE_REPOSITORY'] ?? throw new ConfigurationException('Remote Repository is missing'), + remoteRepositoryAccessToken: $env[$envPrefix . 'REMOTE_REPOSITORY_ACCESS_TOKEN'] ?? null, + ); + } +} diff --git a/Classes/Exception/ConfigurationException.php b/Classes/Exception/ConfigurationException.php new file mode 100644 index 0000000..771e7f7 --- /dev/null +++ b/Classes/Exception/ConfigurationException.php @@ -0,0 +1,10 @@ + $env + */ + public function resolve(array $env): string + { + if (isset($env[self::GITHUB_TOKEN])) { + return $env[self::GITHUB_TOKEN]; + } + + $message = sprintf( + 'Public access token is missing, add it via: "%s"', + implode('", "', self::POSSIBLE_TOKEN_ENVS) + ); + + throw new ConfigurationException($message); + } +} diff --git a/Classes/Slicer.php b/Classes/Slicer.php new file mode 100644 index 0000000..21ebcee --- /dev/null +++ b/Classes/Slicer.php @@ -0,0 +1,99 @@ +config = $configFactory->create(getenv()); + } catch (ConfigurationException $configurationException) { + $this->error($configurationException->getMessage()); + exit(0); + } + } + + /** + * Runner to slice a mono-repository + * @return void + */ + public function run(): void + { + $targetRef = $this->config->getTargetBranch(true); + $repositoryUrl = $this->config->getRepositoryUrl(true); + + // This is required for the git-subsplit.sh + putenv('DEFAULT_BRANCH=' . $this->config->getDefaultBranch()); + + if ($this->config->getAllowedRefsPattern() !== null && preg_match($this->config->getAllowedRefsPattern(), $targetRef) !== 1) { + echo sprintf('Skipping request (blacklisted reference detected: %s)', $targetRef) . PHP_EOL; + exit(0); + } + + $publishCommand = [ + sprintf( + '%s publish --update %s', + self::GIT_SUB_SPLIT_BINARY, + escapeshellarg(implode(' ', $this->config->getSplits())) + ) + ]; + + if (preg_match('/refs\/tags\/(.+)$/', $targetRef, $matches)) { + $publishCommand[] = escapeshellarg('--no-heads'); + $publishCommand[] = escapeshellarg(sprintf('--tags=%s', $matches[1])); + } elseif (preg_match('/refs\/heads\/(.+)$/', $targetRef, $matches)) { + $publishCommand[] = escapeshellarg('--no-tags'); + $publishCommand[] = escapeshellarg(sprintf('--heads=%s', $matches[1])); + } else { + echo sprintf('Skipping request (unexpected reference detected: %s)', $targetRef) . PHP_EOL; + exit(0); + } + + $projectWorkingDirectory = self::WORKING_DIRECTORY; + if (!file_exists($projectWorkingDirectory)) { + echo sprintf('Creating working directory (%s)', $projectWorkingDirectory) . PHP_EOL; + mkdir($projectWorkingDirectory, 0750, true); + } + + $subtreeCachePath = $projectWorkingDirectory . '/.subsplit/.git/subtree-cache'; + if (file_exists($subtreeCachePath)) { + echo sprintf('Removing subtree-cache (%s)', $subtreeCachePath); + passthru(sprintf('rm -rf %s', escapeshellarg($subtreeCachePath))); + } + + $command = implode(' && ', [ + sprintf('cd %s', escapeshellarg($projectWorkingDirectory)), + sprintf('( %s init %s || true )', self::GIT_SUB_SPLIT_BINARY, escapeshellarg($repositoryUrl)), + implode(' ', $publishCommand) + ]); + passthru($command, $exitCode); + if (0 !== $exitCode) { + echo sprintf('Command %s had a problem, exit code %s', $command, $exitCode) . PHP_EOL; + exit($exitCode); + } + } + + /** + * Display an error message + * + * @param string $message + * @return void + */ + protected function error(string $message): void + { + echo PHP_EOL . PHP_EOL . "\033[0;31m[ERROR] " . $message . "\033[0m" . PHP_EOL . PHP_EOL; + } +} diff --git a/Classes/autoload.php b/Classes/autoload.php new file mode 100644 index 0000000..ffcaa83 --- /dev/null +++ b/Classes/autoload.php @@ -0,0 +1,8 @@ +" + +inputs: + repository_protocol: + description: 'Protokoll (https://)' + required: true + default: 'https://' + repository_host: + description: 'The Host of the mono repository' + required: true + default: 'github.com' + repository_organization: + description: 'Remote organization' + required: true + repository_name: + description: 'Remote repository' + required: true + allowed_refs_pattern: + description: 'Allowed Refs Pattern' + required: true + default_branch: + description: 'Default Branch of the repository' + required: true + default: 'main' + target_branch: + description: 'The target branch' + required: true + default: 'main' + package_directory: + description: 'Local package directory' + required: true + remote_repository: + description: 'remote repository' + required: true + remote_repository_access_token: + description: 'GitHub Token for remote repository' + required: true +runs: + using: 'docker' + image: 'docker://ghcr.io/erkenes/monorepo-split-action/php:latest' + args: + - ${{ inputs.repository_protocol }} + - ${{ inputs.repository_host }} + - ${{ inputs.repository_organization }} + - ${{ inputs.repository_name }} + - ${{ inputs.allowed_refs_pattern }} + - ${{ inputs.default_branch }} + - ${{ inputs.target_branch }} + - ${{ inputs.package_directory }} + - ${{ inputs.remote_repository }} + - ${{ inputs.remote_repository_access_token }} + +branding: + icon: database + color: blue diff --git a/bin/git-subsplit.sh b/bin/git-subsplit.sh new file mode 100644 index 0000000..8b27859 --- /dev/null +++ b/bin/git-subsplit.sh @@ -0,0 +1,347 @@ +#!/usr/bin/env bash +# +# git-subsplit.sh: Automate and simplify the process of managing one-way +# read-only subtree splits. +# +# Copyright (C) 2012 Dragonfly Development Inc. +# +if [ $# -eq 0 ]; then + set -- -h +fi +OPTS_SPEC="\ +git subsplit init url +git subsplit publish splits --heads= --tags= --splits= +git subsplit update +-- +h,help show the help +q quiet +debug show plenty of debug output +n,dry-run do everything except actually send the updates +work-dir directory that contains the subsplit working directory + + options for 'publish' +heads= only publish for listed heads instead of all heads +no-heads do not publish any heads +tags= only publish for listed tags instead of all tags +no-tags do not publish any tags +update fetch updates from repository before publishing +rebuild-tags rebuild all tags (as opposed to skipping tags that are already synced) +" +eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)" + +# We can run this from anywhere. +NONGIT_OK=1 +DEBUG=" :DEBUG >" + +PATH=$PATH:$(git --exec-path) + +. git-sh-setup + +if [ "$(hash git-subtree &>/dev/null && echo OK)" = "" ] +then + die "Git subplit needs git subtree; install git subtree or upgrade git to >=1.7.11" +fi + +ANNOTATE= +QUIET= +COMMAND= +SPLITS= +REPO_URL= +WORK_DIR="${PWD}/.subsplit" +HEADS= +NO_HEADS= +TAGS= +NO_TAGS= +REBUILD_TAGS= +DRY_RUN= +VERBOSE= + +subsplit_main() +{ + while [ $# -gt 0 ]; do + opt="$1" + shift + case "$opt" in + -q) QUIET=1 ;; + --debug) VERBOSE=1 ;; + --heads) HEADS="$1"; shift ;; + --no-heads) NO_HEADS=1 ;; + --tags) TAGS="$1"; shift ;; + --no-tags) NO_TAGS=1 ;; + --update) UPDATE=1 ;; + -n) DRY_RUN="--dry-run" ;; + --dry-run) DRY_RUN="--dry-run" ;; + --rebuild-tags) REBUILD_TAGS=1 ;; + --) break ;; + *) die "Unexpected option: $opt" ;; + esac + done + + COMMAND="$1" + shift + + case "$COMMAND" in + init) + if [ $# -lt 1 ]; then die "init command requires url to be passed as first argument"; fi + REPO_URL="$1" + shift + subsplit_init + ;; + publish) + if [ $# -lt 1 ]; then die "publish command requires splits to be passed as first argument"; fi + SPLITS="$1" + shift + subsplit_publish + ;; + update) + subsplit_update + ;; + *) die "Unknown command '$COMMAND'" ;; + esac +} +say() +{ + if [ -z "$QUIET" ]; + then + echo "$@" >&2 + fi +} + +subsplit_require_work_dir() +{ + if [ ! -e "$WORK_DIR" ] + then + die "Working directory not found at ${WORK_DIR}; please run init first" + fi + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} pushd \"${WORK_DIR}\" >/dev/null" + fi + + pushd "$WORK_DIR" >/dev/null +} + +subsplit_init() +{ + if [ -e "$WORK_DIR" ] + then + die "Working directory already found at ${WORK_DIR}; please remove or run update" + fi + + say "Initializing subsplit from origin (${REPO_URL})" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git clone -q \"${REPO_URL}\" \"${WORK_DIR}\"" + fi + + git clone -q "$REPO_URL" "$WORK_DIR" || die "Could not clone repository" +} + +subsplit_publish() +{ + subsplit_require_work_dir + + if [ -n "$UPDATE" ]; + then + subsplit_update + fi + + if [ -z "$HEADS" ] && [ -z "$NO_HEADS" ] + then + # If heads are not specified and we want heads, discover them. + HEADS="$(git ls-remote origin 2>/dev/null | grep "refs/heads/" | cut -f3- -d/)" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} HEADS=\"${HEADS}\"" + fi + fi + + if [ -z "$TAGS" ] && [ -z "$NO_TAGS" ] + then + # If tags are not specified and we want tags, discover them. + TAGS="$(git ls-remote origin 2>/dev/null | grep -v "\^{}" | grep "refs/tags/" | cut -f3 -d/)" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} TAGS=\"${TAGS}\"" + fi + fi + + for SPLIT in $SPLITS + do + SUBPATH=$(echo "$SPLIT" | cut -f1 -d:) + REMOTE_URL=$(echo "$SPLIT" | cut -f2- -d:) + REMOTE_NAME=$(echo "$SPLIT" | git hash-object --stdin) + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} SUBPATH=${SUBPATH}" + echo "${DEBUG} REMOTE_URL=${REMOTE_URL}" + echo "${DEBUG} REMOTE_NAME=${REMOTE_NAME}" + fi + + if ! git remote | grep "^${REMOTE_NAME}$" >/dev/null + then + git remote add "$REMOTE_NAME" "$REMOTE_URL" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git remote add \"${REMOTE_NAME}\" \"${REMOTE_URL}\"" + fi + fi + + + say "Syncing ${SUBPATH} -> ${REMOTE_URL}" + + for HEAD in $HEADS + do + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git show-ref --quiet --verify -- \"refs/remotes/origin/${HEAD}\"" + fi + + if ! git show-ref --quiet --verify -- "refs/remotes/origin/${HEAD}" + then + say " - skipping head '${HEAD}' (does not exist)" + continue + fi + LOCAL_BRANCH="${REMOTE_NAME}-branch-${HEAD}" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} LOCAL_BRANCH=\"${LOCAL_BRANCH}\"" + fi + + say " - syncing branch '${HEAD}'" + + git checkout "${DEFAULT_BRANCH}" >/dev/null 2>&1 + git branch -D "$LOCAL_BRANCH" >/dev/null 2>&1 + git branch -D "${LOCAL_BRANCH}-checkout" >/dev/null 2>&1 + git checkout -b "${LOCAL_BRANCH}-checkout" "origin/${HEAD}" >/dev/null 2>&1 + git subtree split -q --prefix="$SUBPATH" --branch="$LOCAL_BRANCH" "origin/${HEAD}" >/dev/null + RETURNCODE=$? + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git checkout ${DEFAULT_BRANCH} >/dev/null 2>&1" + echo "${DEBUG} git branch -D \"$LOCAL_BRANCH\" >/dev/null 2>&1" + echo "${DEBUG} git branch -D \"${LOCAL_BRANCH}-checkout\" >/dev/null 2>&1" + echo "${DEBUG} git checkout -b \"${LOCAL_BRANCH}-checkout\" \"origin/${HEAD}\" >/dev/null 2>&1" + echo "${DEBUG} git subtree split -q --prefix=\"$SUBPATH\" --branch=\"$LOCAL_BRANCH\" \"origin/${HEAD}\" >/dev/null" + fi + + if [ $RETURNCODE -eq 0 ] + then + PUSH_CMD="git push -q ${DRY_RUN} --force $REMOTE_NAME ${LOCAL_BRANCH}:${HEAD}" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} $PUSH_CMD" + fi + + if [ -n "$DRY_RUN" ] + then + echo \# $PUSH_CMD + $PUSH_CMD + else + $PUSH_CMD + fi + fi + done + + for TAG in $TAGS + do + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git show-ref --quiet --verify -- \"refs/tags/${TAG}\"" + fi + + if ! git show-ref --quiet --verify -- "refs/tags/${TAG}" + then + say " - skipping tag '${TAG}' (does not exist)" + continue + fi + LOCAL_TAG="${REMOTE_NAME}-tag-${TAG}" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} LOCAL_TAG="${LOCAL_TAG}"" + fi + + if git branch | grep "${LOCAL_TAG}$" >/dev/null && [ -z "$REBUILD_TAGS" ] + then + say " - skipping tag '${TAG}' (already synced)" + continue + fi + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git branch | grep \"${LOCAL_TAG}$\" >/dev/null && [ -z \"${REBUILD_TAGS}\" ]" + fi + + say " - syncing tag '${TAG}'" + say " - deleting '${LOCAL_TAG}'" + git branch -D "$LOCAL_TAG" >/dev/null 2>&1 + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git branch -D \"${LOCAL_TAG}\" >/dev/null 2>&1" + fi + + say " - subtree split for '${TAG}'" + git subtree split -q --annotate="${ANNOTATE}" --prefix="$SUBPATH" --branch="$LOCAL_TAG" "$TAG" >/dev/null + RETURNCODE=$? + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git subtree split -q --annotate=\"${ANNOTATE}\" --prefix=\"$SUBPATH\" --branch=\"$LOCAL_TAG\" \"$TAG\" >/dev/null" + fi + + say " - subtree split for '${TAG}' [DONE]" + if [ $RETURNCODE -eq 0 ] + then + PUSH_CMD="git push -q ${DRY_RUN} --force ${REMOTE_NAME} ${LOCAL_TAG}:refs/tags/${TAG}" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} PUSH_CMD=\"${PUSH_CMD}\"" + fi + + if [ -n "$DRY_RUN" ] + then + echo \# $PUSH_CMD + $PUSH_CMD + else + $PUSH_CMD + fi + fi + done + done + + popd >/dev/null +} + +subsplit_update() +{ + subsplit_require_work_dir + + say "Updating subsplit from origin" + + git fetch -q -t origin + git checkout "${DEFAULT_BRANCH}" + git reset --hard "origin/${DEFAULT_BRANCH}" + + if [ -n "$VERBOSE" ]; + then + echo "${DEBUG} git fetch -q -t origin" + echo "${DEBUG} git checkout ${DEFAULT_BRANCH}" + echo "${DEBUG} git reset --hard origin/${DEFAULT_BRANCH}" + fi + + popd >/dev/null +} + +subsplit_main "$@" diff --git a/entrypoint.php b/entrypoint.php new file mode 100644 index 0000000..2348df6 --- /dev/null +++ b/entrypoint.php @@ -0,0 +1,9 @@ +run();