drevops/git-artifact

Build artifact from your codebase in CI and push it to a separate git repo.

Fund package maintenance!
drevops
Patreon

Installs: 21 489

Dependents: 0

Suggesters: 0

Security: 0

Stars: 20

Watchers: 4

Forks: 2

Open Issues: 4

Type:package


README

Git Artifact logo

Package and push files to a remote repository

GitHub Issues GitHub Pull Requests GitHub release (latest by date) codecov Total Downloads LICENSE Renovate

Test PHP CircleCI

๐ŸŒŸ With Git Artifact, you can:

๐Ÿ“ฆ Assemble a code artifact locally or in CI
๐Ÿงน Exclude any unwanted files using a deployment .gitignore
๐Ÿ“ค Transfer the final artifact to a destination Git repository for deployment
๐Ÿ” Choose between force-push or branch modes to fit your workflow

See example of deployed artifact in Artifact branches.

๐Ÿ”€ Workflow

1๏ธโƒฃ ๐Ÿง‘โ€๐Ÿ’ป Develop in the source repository
2๏ธโƒฃ ๐Ÿ“ฆ CI installs dependencies and runs git-artifact to package and push code to destination repository
3๏ธโƒฃ ๐Ÿš€ Deployment triggered whan code received

๐ŸŽš๏ธ Modes

force-push mode (default)

Push the packaged artifact to the same branch in the destination repository. This will carry over the branch history from the source repository and will overwrite the existing branch history in the destination repository.

==================================================
 ๐Ÿƒ Run 1
==================================================

Local repo                  Remote repo
                            +------------------+
                            | Artifact commit  | ๐Ÿ’ฅ New commit
                            +------------------+
+-----------+               +------------------+
| Commit 2  |               | Commit 2         | \
+-----------+  ==  ๐Ÿ“ฆ  ==>  +------------------+  ) ๐Ÿ‘ Source commit
| Commit 1  |               | Commit 1         | /   history preserved
+-----------+               +------------------+
 `mybranch`                      `mybranch`

                                     ๐Ÿ‘†
                        Branch name identical to source

==================================================
 ๐Ÿƒ Run 2
==================================================

Local repo                    Remote repo
                            +------------------+
                            | Artifact commit  | ๐Ÿ’ฅ New commit
                            +------------------+
+-----------+               +------------------+
| Commit 4  |               | Commit 4         |  \
+-----------+               +------------------+   \
| Commit 3  |               | Commit 3         |    \
+-----------+  ==  ๐Ÿ“ฆ  ==>  +------------------+     )  ๐Ÿ‘ Source commit
| Commit 2  |               | Commit 2         |    /    history preserved
+-----------+               +------------------+   /
| Commit 1  |               | Commit 1         |  /
+-----------+               +------------------+
 `mybranch`                      `mybranch`

                                     ๐Ÿ‘†
                       Branch name identical to source

Use case

Forwarding all changes in the source repository to the destination repository as-is for every branch: for example, a commit in the source repository branch feature/123 would create a commit in the destination repository branch feature/123. The next commit to the source repository branch feature/123 would update the destination repository branch feature/123 with the changes, but would overwrite the last "artifact commit".

branch mode

Push the packaged artifact to the new branch in the destination repository. This will carry over the branch history from the source repository to a dedicated branch in the destination repository. The follow-up pushes to the branch in the destination repository will be blocked.

==================================================
 ๐Ÿƒ Run 1
==================================================

Local repo                  Remote repo
                            +------------------+
                            | Artifact commit  | ๐Ÿ’ฅ New commit
                            +------------------+
+-----------+               +------------------+
| Commit 2  |               | Commit 2         | \
+-----------+  ==  ๐Ÿ“ฆ  ==>  +------------------+  ) ๐Ÿ‘ Source commit
| Commit 1  |               | Commit 1         | /    history preserved
+-----------+               +------------------+

 `mybranch`                  `deployment/1.2.3`
 tagged with
   `1.2.3`

     ๐Ÿ‘†                              ๐Ÿ‘†
 Tagged branch              New branch based on tag

==================================================
 ๐Ÿƒ Run 2
==================================================

Local repo                    Remote repo
                            +------------------+
                            | Artifact commit  | ๐Ÿ’ฅ New commit
                            +------------------+
+-----------+               +------------------+
| Commit 4  |               | Commit 4         |  \
+-----------+               +------------------+   \
| Commit 3  |               | Commit 3         |    \
+-----------+  ==  ๐Ÿ“ฆ  ==>  +------------------+     )  ๐Ÿ‘ Source commit
| Commit 2  |               | Commit 2         |    /    history preserved
+-----------+               +------------------+   /
| Commit 1  |               | Commit 1         |  /
+-----------+               +------------------+

 `mybranch`                  `deployment/1.2.4`
 tagged with
   `1.2.4`  ๐Ÿ‘ˆ New tag 1.2.4

     ๐Ÿ‘†                              ๐Ÿ‘†
 Tagged branch            New branch based on a new tag
 with a new tag

Use case

Creating a new branch in the destination repository for every tag created in the source repository: for example, a tag 1.2.3 in the source repository would create a branch deployment/1.2.3 in the destination repository. The addition of the new tags would create new unique branches in the destination repository.

๐Ÿ“ฅ Installation

This package is intended to be used as a standalone binary. You will need to have PHP installed on your system to run the binary.

Download the latest release from the GitHub releases page.

You may also install the package globally using Composer:

composer global require --dev drevops/git-artifact

โ–ถ๏ธ Usage

./git-artifact git@github.com:yourorg/your-repo-destination.git

This will create an artifact from current directory and will send it to the specified remote repository into the same branch as a current one.

Avoid including development dependencies in your artifacts. Instead, configure your CI to build with production-only dependencies, export the resulting code, and use that as the artifact source. See our CI examples below.

Call from the CI configuration or deployment script:

export DEPLOY_BRANCH=<YOUR_CI_PROVIDER_BRANCH_VARIABLE>
./git-artifact git@github.com:yourorg/your-repo-destination.git \
  --branch="${DEPLOY_BRANCH}" \
  --push

CI providers may report branches differently when running builds triggered by tags. We encourage you to explore our continuously and automatically tested examples:

See extended and fully-configured example in the Vortex project.

๐ŸŽ›๏ธ Options

Name Default value Description
--mode force-push Mode of artifact build: branch, force-push
--branch [branch] Destination branch with optional tokens (see below)
--gitignore Path to the .gitignore file to replace the current .gitignore
--src Directory where source repository is located. Uses root directory if not specified
--root Path to the root for file path resolution. Uses current directory if not specified
--message Deployment commit Commit message with optional tokens (see below)
--no-cleanup Do not cleanup after run
--log Path to the log file
--show-changes Show changes made to the repo by the build in the output
--dry-run Run without pushing to the remote repository
--now Internal value used to set internal time
-h, --help Display help for the given command
-q, --quiet Do not output any messages
-V, --version Display this application version
--ansi Force ANSI output. Use --no-ansi to disable
-n, --no-interaction Do not ask any interactive question
-v, --verbose Increase the verbosity of messages: 1 for normal, 2 for more verbose, 3 for debug

๐Ÿงน Modifying artifact content

--gitignore option allows to specify the path to the artifact's .gitignore file that replaces existing .gitignore (if any) during the build. Any files no longer ignored by the replaced artifact's .gitignore are added into the deployment commit. If there are no no-longer-excluded files, the deployment commit is still created, to make sure that the deployment timestamp is captured.

๐Ÿท๏ธ Token support

Tokens are pre-defined strings surrounded by [ and ] and may contain optional formatter. For example, [timestamp:Y-m-d] is replaced with the current timestamp in format Y-m-d (token formatter), which is PHP date() expected format.

Both --branch and --message option values support token replacement.

Available tokens:

  • [timestamp:FORMAT] - current time with a PHP date()-compatible FORMAT.
  • [branch] - current branch in the source repository.
  • [safebranch] - current branch in the source repository with with all non-alphanumeric characters replaced with - and lowercased.
  • [tags:DELIMITER] - tags from the latest commit in the source repository separated by a DELIMITER.

Maintenance

๐Ÿงช Testing

Packaging and deployment of artifacts is a mission-critical process, so we maintain a set of unit, functional and integration tests to make sure that everything works as expected.

You can see examples of the branches created by the Git Artifact in the example destination repository.

Lint and fix code

composer lint
composer lint-fix

Run tests

composer test

Repository created using https://getscaffold.dev/ project scaffold template