Skip to content

Repository files navigation

A mock Git server that creates ephemeral Git repos for testing.

Every request from an unknown user is against a fresh copy of a Git repo, so no changes are preserved.

The service accepts any username and password.

The repo copies are created when they are first accessed, so the workflow is:

  1. Clone a repo (e.g. git clone http://localhost:8080/repo/platformhubrepo)
  2. The server creates a temporary copy of the git repo for that request.
  3. The client can interact with the repo as normal (e.g. git add, git commit, git push), and the temporary directory will be modified.
  4. The temporary directory is immediately deleted after the request is complete.

Known users

The git repo for known users will persit for a short amount of time providing an ephemeral repo. The repos are either explicitly cleaned up, or are deleted as the hosting environment scales to 0, so the lifetime of the ephemeral repos is not guaranteed.

Sample repos

The sample repos exist in repotemplate.tar.bz2. This is to prevent Git from complaining about nested Git repositories in the project. The unpacktemplate.sh and packtemplate.sh scripts are used to unpack and pack the template repository.

Working around the unique git repo limitation in Octopus

Octopus has a restriction that means a git repo can only be used by one project in any space.

This can be worked around by pointing the project to the repo https://mockgit.octopusdemos.com/uniquerepo/id/projectrepo, where <id> is a unique identifier (e.g. a number). This way, each project can have its own copy of the repo, and they won't conflict with each other.

Repos

  • platformhubrepo: A sample Octopus Platform Hub repo
  • projectrepo: A sample Octopus CaC project configured to use the process template in platformhubrepo
  • argocd: A sample Argo CD project repo.
  • blank#: Blank repos. Replace # with a number between 1 and 10.

Repos are cloned with the command:

git clone https://<unique user name>@mockgit.octopusdemos.com/repo/<repo name>

For example:

git clone https://whatever@mockgit.octopusdemos.com/repo/platformhubrepo

Usage

Start the server using the pre-built image from GitHub Container Registry:

docker run -d --name mockgitserver -p 8080:8080 ghcr.io/OctopusSolutionsEngineering/mockgitrepo:latest

Or with Podman:

podman run -d --name mockgitserver -p 8080:8080 ghcr.io/OctopusSolutionsEngineering/mockgitrepo:latest

Configuration environment variables:

  • GIT_PROJECT_ROOT: Base path containing source repositories (default: /data/repos).
  • GIT_TEMP_ROOT: Base path for temporary repository copies created per request (default: system temp directory).

GIT_TEMP_ROOT usually points at a mounted network file share, where the first copy of a repository for a user is slow enough to time out the request that triggers it. Clones and fetches do not write to the repository, so when the copy on the share is missing they are served from a second copy under /tmp while the share is populated in the background. Pushes always use the copy on the share, and once that copy exists every request uses it.

Anonymous users are only ever served from /tmp, because their copy is deleted as soon as the request that created it finishes and so never needs to reach the share.

Clone the repository (you must provide a username in the URL):

cd /tmp
git clone http://myusername@localhost:8080/repo/platformhubrepo

Building Locally

Build the Docker image:

docker build -t mockgitserver .

Run the locally built image:

docker run -d --name mockgitserver -p 8080:8080 mockgitserver

Using the hosted version

This application is hosted on Azure. The follow commands demonstrate how you can clone and then interact with the repo.

git clone https://blahblah@mockgit.octopusdemos.com/repo/platformhubrepo
cd platformhubrepo
touch newfile.txt
git add newfile.txt
git commit -m "Add new file to test commit"
git push origin main
git pull
# Git will report a "forced update" with the changes reverted

Adding new sample repos

  1. Run unpacktemplate.sh to unpack the template repo into repotemplate
  2. Add a directory in repotemplate
  3. Run git init in the new directory
  4. Run git config http.receivepack true in the new directory
  5. Add template files
  6. Run git add . and git commit -m "Add new sample repo"
  7. Run git checkout -b main to create the main branch
  8. Run git config --bool core.bare true
  9. Run git config receive.denyNonFastForwards false to allow non-fast-forward pushes (e.g. force pushes)
  10. Enter the root of the template repo e.g. cd ../..
  11. Run packtemplate.sh to pack the template repo into repotemplate.tar.bz2

Update sample repo

  1. Run unpacktemplate.sh to unpack the template repo into repotemplate
  2. Enter the directory of the repo you want to update e.g. cd repotemplate/argocd
  3. Run git config --bool core.bare false
  4. Make changes to the repo
  5. Run git add . and git commit -m "Update sample repo"
  6. Run git config --bool core.bare true
  7. Enter the root of the template repo e.g. cd ../..
  8. Run packtemplate.sh to pack the template repo into repotemplate.tar.bz2

These are the commands chained up:

git config --bool core.bare false; git add .; git commit -m "Update sample repo"; git config --bool core.bare true; cd ../..

Persisting credentials

curl -X PUT -H "X_MOCKGIT_SERVICE_API_KEY: tokengoeshere" -d '{"data":{"type": "credentials", "id": "user1", "attributes": {"password": "blah"}}}' http://localhost:8080/api/credentials 

Deployment notes

You must enable session affinity (sticky sessions) on the Azure App Service to ensure that all requests from a client go to the same instance of the application. This is necessary because the application creates and maintains a temporary copy of the Git repo for each user, and switching between instances means you persist changes to one instance and then read the repo from another instance where the changes don't exist.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages