Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions bin/git-crypt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

# Wrapper to call \`git-crypt\` via docker
#
# Usage: git-crypt COMMAND [OPTIONS...]
#
# The command and its potential options are forwarded verbatim to the \`git-crypt\` call within the docker container.

set -euo pipefail

docker_image="git-crypt:latest"

if ! command -v docker &> /dev/null; then
echo "❌ Error: docker is not available."
exit 1
fi

# Run git-crypt via docker
echo "🔓 Running git-crypt $* (via docker)..."

if ! docker images -q "$docker_image" | grep -q .; then
# Pull the git-crypt image if it's not already present locally
if ! docker pull "$docker_image" >/dev/null 2>&1; then
# Build the git-crypt image locally if pulling failed
echo "🔨 Building docker image locally..."
plugin_root="$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")"
docker build -q -t "$docker_image" "$plugin_root/git-crypt"
fi
fi

docker_volumes=(-v "$(pwd)"/:/repo)
# If the repository uses `git` alternates (typically because it has been cloned using `--reference` to use a local git mirror to speed up clones from CI),
# we need to mount each of the entries as a `-v` volume with the same path in the container.
alternates_file="$(pwd)/.git/objects/info/alternates"
if [ -f "$alternates_file" ]; then
while read -r alternate; do
docker_volumes+=(-v "$alternate":"$alternate")
done < "$alternates_file"
fi

# Run git-crypt via docker (Note: `-i` option is necessary if we want to be able to pipe the encryption key through stdin for the `unlock` command)
docker run -i --rm "${docker_volumes[@]}" "$docker_image" "$@"
48 changes: 48 additions & 0 deletions git-crypt/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
ARG VERSION=0.8.0

####################
# Build Layer
####################

FROM amazonlinux:latest AS builder
ARG VERSION

RUN dnf install -y \
make \
gcc-c++ \
openssl-devel \
tar \
gzip

RUN curl -L https://github.com/AGWA/git-crypt/archive/$VERSION.tar.gz | tar -zxv

RUN cd git-crypt-$VERSION \
&& make \
&& make install PREFIX=/usr/local

####################
# Runtime Layer
####################

FROM amazonlinux:latest
ARG VERSION

LABEL org.opencontainers.image.title="git-crypt"
LABEL org.opencontainers.image.version="$VERSION"
LABEL org.opencontainers.image.documentation="https://github.com/AGWA/git-crypt/blob/master/README.md"
LABEL org.opencontainers.image.authors="Automattic <[email protected]>"
LABEL org.opencontainers.image.source="https://github.com/Automattic/a8c-ci-toolkit-buildkite-plugin"

COPY --from=builder /usr/local/bin/git-crypt /usr/local/bin/git-crypt

RUN dnf install -y git

WORKDIR /repo
VOLUME /repo

# Note: It's important for the entrypoint to be just `git-crypt` instead of the full `/usr/local/bin/git-crypt` path,
# because the $0 used to call the binary during `unlock` will also be used by git-crypt to set up the commands for
# the git filters, and we want those filters to rely on $PATH to find the binary. That way, we can provide a wrapper
# (reachable via $PATH) outside the container so that git operations can work from outside the container too.
ENV PATH="/usr/local/bin:$PATH"
ENTRYPOINT ["git-crypt"]
49 changes: 49 additions & 0 deletions git-crypt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# git-crypt Docker image

## Why?

The `Dockerfile` in this folder is used to be able to run [`git-crypt`](https://github.com/AGWA/git-crypt) on any platform.

Indeed, while `git-crypt` is easy to install on macOS platforms via a simple `brew install git-crypt`, it is not always as easy to install on all other platforms:
- While some Linux distributions may have versions of `git-crypt` available via `yum install`/`dnf install`/`apk add`/…, they might not always have the latest version.
- Support for `git-crypt` on Windows platforms is at its infancy, less tested and harder to compile on that platform to begin with.
Comment on lines +7 to +9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation 👍


## How to use

### Build the docker image

Run this command from this directory:
```sh
$ docker build -t git-crypt .
```

To build a specific version other than the one defined in the `Dockerfile`:
```sh
$ docker build -t git-crypt --build-arg 0.8.0 .
```

To build for a specific platform:
```sh
$ docker build -t git-crypt --platform linux/amd64 .
```

### Publish the image

> TODO: Ideally this should be done by our CI on this repo, publishing it to our AWS ECR repository when the Dockerfile changes. WIP.

### Run git-crypt via docker

```sh
$ docker run --rm -v <path-to-repo>:/repo git-crypt <subcommand>
```
e.g.
```sh
$ docker run --rm -v ./:/repo git-crypt unlock
```

> [!NOTE]
> If your repository uses `git` alternates—typically because it has been cloned using `--reference` to use a local git mirror to speed up clones from CI—
> you will have to also mount the alternate object stores as a volume in the docker container.
> For each line in the `.git/objects/info/alternates` file in your repo, mount each of the entries as a `-v` volume with the same path in the container.
>
> This is already habdled by the [`git-crypt-unlock`](../bin/git-crypt-unlock) helper script from this repo.