{"id":19140275,"url":"https://github.com/drevops/git-artifact","last_synced_at":"2026-02-04T02:14:48.370Z","repository":{"id":38943425,"uuid":"102357490","full_name":"drevops/git-artifact","owner":"drevops","description":"📦 Assemble a code artifact from your codebase, remove unnecessary files, and push it into a separate Git repository.","archived":false,"fork":false,"pushed_at":"2025-04-08T12:52:48.000Z","size":372,"stargazers_count":20,"open_issues_count":5,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-09T22:18:17.828Z","etag":null,"topics":["acquia","artefact","artifact","composer","devops","git","package"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drevops.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"drevops","patreon":"drevops"}},"created_at":"2017-09-04T12:10:57.000Z","updated_at":"2025-03-29T02:23:45.000Z","dependencies_parsed_at":"2023-11-15T02:35:40.446Z","dependency_job_id":"cdbe8c46-358c-42d9-98cf-d88cd4d9d946","html_url":"https://github.com/drevops/git-artifact","commit_stats":{"total_commits":50,"total_committers":3,"mean_commits":"16.666666666666668","dds":0.28,"last_synced_commit":"68b57fa6174aa427def8ae47c875b1b1df51ebe3"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fgit-artifact","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fgit-artifact/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fgit-artifact/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drevops%2Fgit-artifact/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drevops","download_url":"https://codeload.github.com/drevops/git-artifact/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248119286,"owners_count":21050755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acquia","artefact","artifact","composer","devops","git","package"],"created_at":"2024-11-09T07:17:00.091Z","updated_at":"2026-02-04T02:14:48.362Z","avatar_url":"https://github.com/drevops.png","language":"PHP","funding_links":["https://github.com/sponsors/drevops","https://patreon.com/drevops"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"\" rel=\"noopener\"\u003e\n  \u003cimg width=150px height=150px src=\"logo.png\" alt=\"Git Artifact logo\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch2 align=\"center\"\u003ePackage and push files to a remote repository\u003c/h2\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![GitHub Issues](https://img.shields.io/github/issues/drevops/git-artifact.svg)](https://github.com/drevops/git-artifact/issues)\n[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/drevops/git-artifact.svg)](https://github.com/drevops/git-artifact/pulls)\n![GitHub release (latest by date)](https://img.shields.io/github/v/release/drevops/git-artifact)\n[![codecov](https://codecov.io/gh/drevops/git-artifact/branch/main/graph/badge.svg?token=QNBXCIBK5J)](https://codecov.io/gh/drevops/git-artifact)\n[![Total Downloads](https://poser.pugx.org/drevops/behat-screenshot/downloads)](https://packagist.org/packages/drevops/git-artifact)\n![LICENSE](https://img.shields.io/github/license/drevops/git-artifact)\n![Renovate](https://img.shields.io/badge/renovate-enabled-green?logo=renovatebot)\n\n[![Test PHP](https://github.com/drevops/git-artifact/actions/workflows/test-php.yml/badge.svg)](https://github.com/drevops/git-artifact/actions/workflows/test-php.yml)\n[![CircleCI](https://circleci.com/gh/drevops/git-artifact.svg?style=shield)](https://circleci.com/gh/drevops/git-artifact)\n\n\u003c/div\u003e\n\n---\n\n## 🌟 With Git Artifact, you can:\n\n📦 Assemble a code artifact locally or in CI\u003cbr/\u003e\n🧹 Exclude any unwanted files using a deployment `.gitignore`\u003cbr/\u003e\n📤 Transfer the final artifact to a destination Git repository for deployment\u003cbr/\u003e\n🔁 Choose between `force-push` or `branch` modes to fit your workflow\u003cbr/\u003e\n\nSee example of deployed artifact\nin [Artifact branches](https://github.com/drevops/git-artifact-destination/branches).\n\n## 🔀 Workflow\n\n1️⃣ 🧑‍💻 Develop in the _source_ repository\u003cbr/\u003e\n2️⃣ 📦 CI installs dependencies and runs **git-artifact** to package and push code to _destination_ repository\u003cbr/\u003e\n3️⃣ 🚀 Hosting receives the code artifact and triggers a deployment\u003cbr/\u003e\n\n## 🎚️ Modes\n\n### `force-push` mode (default)\n\nPush the packaged artifact to the **same branch** in the _destination_ repository.\nThis will carry over the branch history from the _source_ repository and will overwrite\nthe existing branch history in the _destination_ repository.\n\n```\n==================================================\n 🏃 Run 1\n==================================================\n\nLocal repo                  Remote repo\n                            +------------------+\n                            | Artifact commit  | 💥 New commit\n                            +------------------+\n+-----------+               +------------------+\n| Commit 2  |               | Commit 2         | \\\n+-----------+  ==  📦  ==\u003e  +------------------+  ) 👍 Source commit\n| Commit 1  |               | Commit 1         | /   history preserved\n+-----------+               +------------------+\n `mybranch`                      `mybranch`\n\n                                     👆\n                        Branch name identical to source\n\n==================================================\n 🏃 Run 2\n==================================================\n\nLocal repo                    Remote repo\n                            +------------------+\n                            | Artifact commit  | 💥 New commit\n                            +------------------+\n+-----------+               +------------------+\n| Commit 4  |               | Commit 4         |  \\\n+-----------+               +------------------+   \\\n| Commit 3  |               | Commit 3         |    \\\n+-----------+  ==  📦  ==\u003e  +------------------+     )  👍 Source commit\n| Commit 2  |               | Commit 2         |    /    history preserved\n+-----------+               +------------------+   /\n| Commit 1  |               | Commit 1         |  /\n+-----------+               +------------------+\n `mybranch`                      `mybranch`\n\n                                     👆\n                       Branch name identical to source\n\n```\n\n#### Use case\n\nForwarding all changes in the _source_ repository to the _destination_\nrepository **as-is** for **every branch**: for example, a commit in the _source_\nrepository branch `feature/123` would create a commit in the _destination_\nrepository branch `feature/123`. The next commit to the _source_ repository\nbranch `feature/123` would update the _destination_ repository branch\n`feature/123` with the changes, but would overwrite the last \"artifact commit\".\n\n### `branch` mode\n\nPush the packaged artifact to the **new branch** in the _destination_ repository.\nThis will carry over the branch history from the _source_ repository to a\ndedicated branch in the _destination_ repository. The follow-up pushes to the\nbranch in the _destination_ repository will be blocked.\n\n```\n==================================================\n 🏃 Run 1\n==================================================\n\nLocal repo                  Remote repo\n                            +------------------+\n                            | Artifact commit  | 💥 New commit\n                            +------------------+\n+-----------+               +------------------+\n| Commit 2  |               | Commit 2         | \\\n+-----------+  ==  📦  ==\u003e  +------------------+  ) 👍 Source commit\n| Commit 1  |               | Commit 1         | /    history preserved\n+-----------+               +------------------+\n\n `mybranch`                  `deployment/1.2.3`\n tagged with\n   `1.2.3`\n\n     👆                              👆\n Tagged branch              New branch based on tag\n\n==================================================\n 🏃 Run 2\n==================================================\n\nLocal repo                    Remote repo\n                            +------------------+\n                            | Artifact commit  | 💥 New commit\n                            +------------------+\n+-----------+               +------------------+\n| Commit 4  |               | Commit 4         |  \\\n+-----------+               +------------------+   \\\n| Commit 3  |               | Commit 3         |    \\\n+-----------+  ==  📦  ==\u003e  +------------------+     )  👍 Source commit\n| Commit 2  |               | Commit 2         |    /    history preserved\n+-----------+               +------------------+   /\n| Commit 1  |               | Commit 1         |  /\n+-----------+               +------------------+\n\n `mybranch`                  `deployment/1.2.4`\n tagged with\n   `1.2.4`  👈 New tag 1.2.4\n\n     👆                              👆\n Tagged branch            New branch based on a new tag\n with a new tag\n\n```\n\n#### Use case\n\nCreating a **new branch** in the _destination_ repository for every **tag**\ncreated in the _source_ repository: for example, a tag `1.2.3` in the source\nrepository would create a branch `deployment/1.2.3` in the destination\nrepository. The addition of the new tags would create new unique branches in the\ndestination repository.\n\n## 📥 Installation\n\n### As a standalone binary\n\nThis tool is intended to be used as a standalone binary. You will need to\nhave PHP installed on your system to run the binary.\n\nDownload the latest release from the [GitHub releases page](https://github.com/drevops/git-artifact/releases/latest).\n\n### As a Composer dependency\n\nYou may also install this tool globally using Composer:\n```shell\ncomposer global require --dev drevops/git-artifact:~1.1\n```\n\n#### 📌 Version constraint\n\nWhen using `git-artifact` in CI/CD scripts, we recommend using **Tilde Version Range Operator** to ensure stability.\nThe tilde constraint allows patch updates (e.g., `1.0.0` → `1.1.1`) but blocks minor version updates (e.g., `1.1.0` → `1.2.0`).\n\nThis ensures that:\n- **Security fixes and bug patches** are automatically applied\n- **CI/CD pipelines remain stable** - no unexpected breaking changes\n- **Minor version updates are blocked** - these may introduce behavioral changes that could affect deployments\n\nThis is especially important in CI/CD environments where deployment reliability is critical and changes should be tested before adoption.\n\n## ▶️ Usage\n\n```shell\n./git-artifact git@github.com:yourorg/your-repo-destination.git\n```\n\nThis will create an artifact from current directory and will send it to the\nspecified remote repository into the same branch as a current one.\n\nAvoid including development dependencies in your artifacts. Instead, configure\nyour CI to install production-only dependencies, export the resulting code,\nand use that as the artifact source. See our CI examples below.\n\nCall from the CI configuration or deployment script:\n\n```shell\nexport DEPLOY_BRANCH=\u003cYOUR_CI_PROVIDER_BRANCH_VARIABLE\u003e\n./git-artifact git@github.com:yourorg/your-repo-destination.git \\\n  --branch=\"${DEPLOY_BRANCH}\" \\\n  --push\n```\n\nCI providers may report branches differently when packaging is triggered by tags.\nWe encourage you to explore our continuously and automatically tested examples:\n\n- [GitHub Actions](.github/workflows/test-php.yml)\n- [CircleCI](.circleci/config.yml)\n\nSee extended and\nfully-configured [example in the Vortex project](https://github.com/drevops/vortex/blob/develop/scripts/vortex/deploy-artifact.sh).\n\n\n## 🎛️ Options\n\n| Name                       | Default value       | Description                                                                                                         |\n|----------------------------|---------------------|---------------------------------------------------------------------------------------------------------------------|\n| `--ansi`                   |                     | Force ANSI output. Use `--no-ansi` to disable                                                                       |\n| `--branch`                 | `[branch]`          | Destination branch with optional tokens (see below)                                                                 |\n| `--dry-run`                |                     | Run without pushing to the remote repository                                                                        |\n| `--fail-on-missing-branch` |                     | Fail artifact packaging if source branch cannot be determined. By default, artifact packaging is skipped gracefully |\n| `--gitignore`              |                     | Path to the `.gitignore` file to replace the current `.gitignore`                                                   |\n| `--log`                    |                     | Path to the log file                                                                                                |\n| `--message`                | `Deployment commit` | Commit message with optional tokens (see below)                                                                     |\n| `--mode`                   | `force-push`        | Mode of artifact packaging: `branch`, `force-push`                                                                  |\n| `--no-cleanup`             |                     | Do not cleanup after run                                                                                            |\n| `--now`                    |                     | Internal value used to set internal time                                                                            |\n| `--root`                   |                     | Path to the root for file path resolution. Uses current directory if not specified                                  |\n| `--show-changes`           |                     | Show changes made to the repo during packaging in the output                                                        |\n| `--src`                    |                     | Directory where source repository is located. Uses root directory if not specified                                  |\n| `-V, --version`            |                     | Display this application version                                                                                    |\n| `-h, --help`               |                     | Display help for the given command                                                                                  |\n| `-n, --no-interaction`     |                     | Do not ask any interactive question                                                                                 |\n| `-q, --quiet`              |                     | Do not output any messages                                                                                          |\n| `-v, --verbose`            |                     | Increase the verbosity of messages: 1 for normal, 2 for more verbose, 3 for debug                                   |\n\n## 🧹 Modifying artifact content\n\n`--gitignore` option allows to specify the path to the artifact's `.gitignore`\nfile that replaces existing `.gitignore` (if any) during packaging. Any files no\nlonger ignored by the replaced artifact's `.gitignore` are added into the\ndeployment commit. If there are no no-longer-excluded files, the deployment\ncommit is still created, to make sure that the deployment timestamp is\ncaptured.\n\n## 🏷️ Token support\n\nTokens are pre-defined strings surrounded by `[` and `]` and may contain\noptional formatter. For example, `[timestamp:Y-m-d]` is\nreplaced with the current timestamp in format `Y-m-d` (token formatter), which\nis PHP [`date()`](https://www.php.net/manual/en/function.date.php) expected format.\n\nBoth `--branch` and `--message` option values support token replacement.\n\nAvailable tokens:\n\n- `[timestamp:FORMAT]` - current time with a PHP [`date()`](https://www.php.net/manual/en/function.date.php)-compatible `FORMAT`.\n- `[branch]` - current branch in the source repository.\n- `[safebranch]` - current branch in the source repository with with all non-alphanumeric characters replaced with `-` and lowercased.\n- `[tags:DELIMITER]` - tags from the latest commit in the source repository\n  separated by a `DELIMITER`.\n\n## Maintenance\n\n### 🧪 Testing\n\nPackaging and deployment of artifacts is a mission-critical process, so we maintain\na set of unit, functional and integration tests to make sure that everything works\nas expected.\n\nYou can see examples of the branches created by the Git Artifact in the [example _destination_ repository](https://github.com/drevops/git-artifact-destination/branches).\n\n### Lint and fix code\n\n```bash\ncomposer lint\ncomposer lint-fix\n```\n\n### Run tests\n\n```bash\ncomposer test\n```\n\n---\n_Repository created using https://getscaffold.dev/ project scaffold template_\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrevops%2Fgit-artifact","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrevops%2Fgit-artifact","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrevops%2Fgit-artifact/lists"}