DEVELOPING.md
This document contains information on how to develop Atlantis locally. For the contribution process, see CONTRIBUTING.md.
npm install, then npm run website:dev and open your browser to http://localhost:8080.Clone the repo from https://github.com/runatlantis/atlantis/
Compile Atlantis:
go install
Run Atlantis:
atlantis server --gh-user <your username> --gh-token <your token> --repo-allowlist <your repo> --gh-webhook-secret <your webhook secret> --log-level debug
If you get an error like command not found: atlantis, ensure that $GOPATH/bin is in your $PATH.
Docker compose is set up to start an atlantis container and ngrok container in the same network in order to expose the atlantis instance to the internet. In order to do this, create a file in the repository called atlantis.env and add the required env vars for the atlantis server configuration.
e.g.
NGROK_AUTHTOKEN=1234567890
ATLANTIS_GH_APP_ID=123
ATLANTIS_GH_APP_KEY_FILE="/.ssh/somekey.pem"
ATLANTIS_GH_WEBHOOK_SECRET=12345
Note: ~/.ssh is mounted to allow for referencing any local ssh keys.
Following this just run:
make build-service
docker-compose up --detach
docker-compose logs --follow
If the ngrok container is restarted, the url will change which is a hassle. Fortunately, when we make a code change, we can rebuild and restart the atlantis container easily without disrupting ngrok.
e.g.
make build-service
docker-compose up --detach --build
make test. If you want to run the integration tests that actually run real terraform commands, run make test-all.
docker run --rm -v $(pwd):/atlantis -w /atlantis ghcr.io/runatlantis/testing-env:latest make test
Or to run the integration tests
docker run --rm -v $(pwd):/atlantis -w /atlantis ghcr.io/runatlantis/testing-env:latest make test-all
Create a test terraform repository in your GitHub.
Create a personal access token for Atlantis. See Create a GitHub token.
Start Atlantis in server mode using that token:
atlantis server --gh-user <your username> --gh-token <your token> --repo-allowlist <your repo> --gh-webhook-secret <your webhook secret> --log-level debug
Download ngrok from https://ngrok.com/download. This will enable you to expose Atlantis running on your laptop to the internet so GitHub can call it.
When you've downloaded and extracted ngrok, run it on port 4141:
ngrok http 4141
Create a Webhook in your repo and use the https url that ngrok printed out after running ngrok http 4141. Be sure to append /events so your webhook url looks something like https://efce3bcd.ngrok.io/events. See Add GitHub Webhook.
Create a pull request and type atlantis help. You should see the request in the ngrok and Atlantis logs and you should also see Atlantis comment back.
ctx.Log should be available in most methods. If not, pass it down.ctx.Log.Info("cleaning clone dir %q", dir) => Cleaning clone directory "/tmp/atlantis/lkysow/atlantis-terraform-test/3":" in a log since that's used to separate error descriptions and causes
- or , ex. failed to clean directory, continuing regardlessALWAYS use lowercase unless the word requires it
ALWAYS use fmt.Errorf("additional context: %w", err)" instead of fmt.Errorf("additional context: %s", err) because it is less likely to result in mistakes and gives us the ability to trace calls
NEVER use the words "error occurred when...", or "failed to..." or "unable to...", etc. Instead, describe what was occurring at time of the error, ex. "cloning repository", "creating AWS session". This will prevent errors from looking like
Error setting up workspace: failed to run git clone: could find git
and will instead look like
Error: setting up workspace: running git clone: no executable "git"
This is easier to read and more consistent.
{package under test}_test to enforce testing the external interfaces{file under test}_internal_test.goimport . "github.com/runatlantis/atlantis/testing" and then use Assert(), Equals() and Ok()We use pegomock for mocking. If you're modifying any interfaces that are mocked, you'll need to regen the mocks for that interface.
Install using go install github.com/petergtz/pegomock/v4/pegomock@latest
If you see errors like:
# github.com/runatlantis/atlantis/server/events [github.com/runatlantis/atlantis/server/events.test]
server/events/project_command_builder_internal_test.go:567:5: cannot use workingDir (type *MockWorkingDir) as type WorkingDir in field value:
*MockWorkingDir does not implement WorkingDir (missing ListAllFiles method)
Then you've likely modified an interface and now need to update the mocks.
Each interface that is mocked has a go:generate command above it, e.g.
//go:generate pegomock generate -m --package mocks -o mocks/mock_project_command_builder.go ProjectCommandBuilder
type ProjectCommandBuilder interface {
BuildAutoplanCommands(ctx *command.Context) ([]command.ProjectContext, error)
}
To regen the mock, run go generate on that file, e.g.
go generate server/events/project_command_builder.go
Alternatively, you can run make go-generate to execute go generate across all packages.