Artifact deployment
In an artifact deployment, CI builds your codebase and pushes it as an artifact to a remote Git repository. Use it for a hosting platform that deploys pre-built code from a Git repository it controls, such as Acquia. The artifact carries only what production needs.
This page is for the lead or DevOps engineer who sets up artifact deployments. It explains how CI builds and pushes the artifact, how to configure the push and how to control which files the artifact carries.
How it works
When $VORTEX_DEPLOY_TYPES includes artifact, CI and the deployment
script go through these steps:
- The
buildjob builds the stack and copies the codebase out of theclicontainer before development dependencies install, so the copy holds production dependencies only. - The
deployjob restores that copy and runs the deployment script, which downloads the Git artifact tool and verifies its checksum. - The script copies
.gitand.gitignore.artifactfrom the repository checkout into the copied codebase. The tool then applies the.gitignore.artifactrules to control which files are included. - The tool pushes the artifact to the configured remote repository. The optional stale branch cleanup runs after a successful push.
- The hosting platform then deploys from that repository.
Configuration
Configure the push with the variables in the following table, then follow the setup steps.
Environment variables
The Deployment overview explains the Location values and
how the script loads .env. The following table lists the variables that
control the push:
| Variable | Required | Default | Location | Description |
|---|---|---|---|---|
VORTEX_DEPLOY_ARTIFACT_GIT_REMOTE | Yes | None | CI, or .env on CircleCI | Remote repository URL for the artifact |
VORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAIL | Yes | None | CI, or .env on CircleCI | Email address of the user committing to the remote repository |
VORTEX_DEPLOY_ARTIFACT_GIT_USER_NAME | No | Deployment Robot | CI, or .env on CircleCI | Name of the user committing to the remote repository |
VORTEX_DEPLOY_ARTIFACT_DST_BRANCH | No | [branch] | .env | Remote branch to push to; supports tokens. Tag deployments always push to deployment/[tags:-], whatever this is set to |
VORTEX_DEPLOY_ARTIFACT_SRC | Yes, set by the shipped CI configs | None | CI | Directory with the built codebase to package, passed to git-artifact as --source; the shipped CI configs set it to /tmp/workspace/code |
VORTEX_DEPLOY_ARTIFACT_ROOT | No | Current directory | CI | Repository checkout that .git and .gitignore.artifact are copied from, passed to git-artifact as --root |
VORTEX_DEPLOY_ARTIFACT_LOG | No | <root>/deployment_log.txt | .env | Path to the deployment log file; the shipped CircleCI config sets it to /tmp/artifacts/deployment_log.txt |
VORTEX_DEPLOY_ARTIFACT_SSH_FINGERPRINT | No | Value of VORTEX_DEPLOY_SSH_FINGERPRINT | CI | Fingerprint of the SSH key used to push to the remote repository |
VORTEX_DEPLOY_ARTIFACT_SSH_FILE | No | Value of VORTEX_DEPLOY_SSH_FILE, then ~/.ssh/id_rsa | CI | SSH key file used when no fingerprint is set |
Git artifact tool covers the pinned git-artifact
version and the optional stale branch cleanup. The
Variables reference lists every variable
with the script that reads it.
The shipped CI configs set VORTEX_DEPLOY_ARTIFACT_SRC and
VORTEX_DEPLOY_ARTIFACT_ROOT for you.
On GitHub Actions, the shipped workflow passes 3 variables from repository variables of the same name:
VORTEX_DEPLOY_ARTIFACT_GIT_REMOTEVORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAILVORTEX_DEPLOY_ARTIFACT_GIT_USER_NAME
Set these 3 as repository variables. The value the workflow passes wins
over .env, even when it's empty. Set the other artifact variables in
.env, because the workflow doesn't pass them.
Setup
To set up artifact deployment:
-
Add
artifactto theVORTEX_DEPLOY_TYPESvariable in your.envfile:.envVORTEX_DEPLOY_TYPES=artifact -
Set the remote repository's Git URL as
VORTEX_DEPLOY_ARTIFACT_GIT_REMOTE, where your CI provider reads it:- On GitHub Actions, add a repository variable under Settings > Secrets and variables > Actions > Variables.
- On CircleCI, add a project environment variable, or set it in
.env.
In
.env, the setting looks like this:.envVORTEX_DEPLOY_ARTIFACT_GIT_REMOTE=git@github.com:your-org/your-project-artifact.git -
Set the email address for the deployment commits as
VORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAIL, in the same place as the remote. The following example also sets the optional user name, which replaces the defaultDeployment Robot:VORTEX_DEPLOY_ARTIFACT_GIT_USER_EMAIL="deploy@example.com"VORTEX_DEPLOY_ARTIFACT_GIT_USER_NAME="Deployment Bot"The script sets the email and name as the runner's global Git identity, but only when the runner has no identity yet.
-
Give CI an SSH key with write access to the remote repository:
- On GitHub Actions, add the private key as the
VORTEX_DEPLOY_SSH_PRIVATE_KEYrepository secret. - On CircleCI, add the private key under Project Settings > SSH Keys
and set its fingerprint as
deploy_ssh_fingerprintin.circleci/config.yml.
The script loads the key before it pushes and stops when the key file is missing.
- On GitHub Actions, add the private key as the
Confirm that the next deployment pushed the artifact. The deploy job log
shows [ OK ] Finished artifact deployment. The remote repository has a
branch with the same name as the deployed branch.
Git artifact tool
git-artifact packages and
pushes files to remote repositories.
Some hosting providers, such as Acquia, restrict certain build operations,
so you build the site somewhere else, then deploy the result. The tool
handles that transfer. A .gitignore.artifact file controls which files go
across. Each push replaces the history of the destination branch with the
history of the source branch, while the source repository stays untouched.
Vortex ships 2 files for this:
- A pre-configured
.gitignore.artifactfile - The
vortex-deploy-artifactdeployment script from thedrevops/vortex-toolingComposer package
CI uses them to build the artifact and push it to the remote repository, such as Acquia's, with no manual steps.
The deployment script downloads the git-artifact binary from GitHub
Releases and checks its
SHA256 checksum before running it. A mismatch stops the deployment.
These variables control the version and the checksum:
VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_VERSION: Version to download (default:1.9.0).VORTEX_DEPLOY_ARTIFACT_GIT_ARTIFACT_SHA256: Expected SHA256 checksum of the binary (default: the checksum of the default version).
Change them together, and set both in .env. The checksum matches 1 exact
binary, so a new version with the old checksum fails the check. To get the
checksum of another version, use either of these:
- The SHA256 digest that GitHub shows for the release's
git-artifactasset - The output of
sha256sumon the downloaded binary
Stale branch cleanup
With the default [branch] destination, each source branch deploys to a
branch of the same name. Over time, the destination repository collects
branches for source branches that no longer exist. Vortex can prune
these stale branches after each successful push.
Cleanup is opt-in. These variables control it, and they go in .env:
VORTEX_DEPLOY_ARTIFACT_CLEANUP_PATTERN: branches eligible for pruning. Cleanup runs only when this variable is set, and it's empty by default. The value is a comma-separated list of globs, for examplefeature/*,bugfix/*, or a single regular expression literal, for example/^feature\/.+$/. A branch matching any pattern is eligible.VORTEX_DEPLOY_ARTIFACT_CLEANUP_AGE: the number of days since a matching branch's last commit after which the branch counts as stale (default:7).
Cleanup keeps the newly pushed branch and the destination repository's default branch. A failed cleanup doesn't fail the deployment.
Artifact file control
The .gitignore.artifact file controls which files go into the deployment
artifact. During deployment, git-artifact applies its rules in place of
the standard .gitignore, so these rules decide what reaches the hosting
Git repository.
Vortex writes .gitignore.artifact as a deny list: every file deploys
by default, and the file lists only what stays out of production. The
pre-configured
.gitignore.artifact
deploys everything a production Drupal site needs:
vendor/- The built webroot: Drupal core, compiled theme assets, contributed modules and contributed themes
config/drush/scripts/.env
It excludes these groups, shown here with their main entries:
- Version control, IDE and OS files (
.git,.idea,.vscode,.DS_Store). - Development, continuous integration and AI configuration (
.ahoy.yml,.circleci,.claude,.docker,.github,CLAUDE.md,docker-compose.yml), plus the database cache key files that the GitHub Actions workflow writes (db_cache_*). - Documentation and testing configuration (
docs,tests,behat.php,phpunit.xml,phpcs.xml). - Dependency manifests and lock files not needed at runtime
(
composer.lock,package.json,package-lock.json). - Drupal scaffold's non-production files (
default.settings.local.php,example.services.local.yml). - Credentials, local overrides, caches and content files (
auth.json,.env.local,settings.local.php,.data,web/sites/*/files). - Custom theme asset sources, since only the theme's compiled
build/output is deployed.
Customize the artifact
Because the file is a deny list, a new file you add to the project deploys
automatically. Edit .gitignore.artifact only to keep an additional file
out of the artifact, or to re-include something that a broader rule
excludes:
# Keep an additional development file out of the artifact.
/RELEASE.md
# Re-include theme images that the artifact excludes by default.
!/web/themes/custom/your_site_theme/images
See also
The following page covers the hosting side of an artifact deployment:
- Acquia hosting - Acquia platform integration