Skip to content

Commit

Permalink
Merge pull request #1423 from carolynvs/contrib-tutorial-feedback
Browse files Browse the repository at this point in the history
Update contributing tutorial
  • Loading branch information
carolynvs authored Jan 25, 2021
2 parents a5ade4f + 6aa9644 commit 8e03c7d
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 70 deletions.
53 changes: 53 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,59 @@ Below are the most common developer tasks. Run a target with `make TARGET`, e.g.
* `setup-dco` installs a git commit hook that automatically signsoff your commit
messages per the DCO requirement.

## Test Porter

We have a few different kinds of tests in Porter. You can run all tests types
with `make test`.

### Unit Tests

```
make test-unit
```

Should not rely on Docker, or try to really run bundles without key components
mocked. Most structs have test functions, e.g. `porter.NewTestPorter` that are
appropriate for unit tests.

Fast! 🏎💨 This takes about 15s - 3 minutes, depending on your computer hardware.

### Integration Tests

```
make test-integration
```

These tests run parts of Porter, using the Porter structs instead of the cli.
They can use Docker, expect that a cluster is available, etc. These tests all
use functions like `porter.SetupIntegrationTest()` to update the underlying
components so that they hit the real filesystem, and don't mock out stuff like
Docker.

You must have Docker on your computer to run these tests. The test setup handles
creating a Kubernetes cluster and Docker registry. Since they are slow, it is
perfectly fine to not run these locally and rely on the CI build that's triggered
when you push commits to your pull request instead.

When I am troubleshooting an integration test, I will run just the single test
locally by using `go test -run TESTNAME ./...`. If the test needs infrastructure,
we have scripts that you can use, like `mage StartDockerRegistry` or
`make -f Makefile.kind install-kind create-kind-cluster`.

Slow! 🐢 This takes between 8-16 minutes, depending on your computer hardware.

### End to End Tests

```
mage teste2e
```

End to End tests test Porter using the cli and are used as smoke tests that
should quickly identify big problems with a build that would make it unusable.

Short! We want this to always be something you can run in about 1-3 minutes.


## Install mixins

When you run `make build`, the canary\* build of mixins are automatically
Expand Down
163 changes: 107 additions & 56 deletions docs/content/contribute/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,60 +72,41 @@ order to use them that directory needs to be included in your PATH environment
variable. This is a standard Go developer environment configuration and will be
useful for other Go projects.

1. Open your ~/.bash_profile or ~/.bashrc file (depending on your OS you will
have one or the other) and add the following line to the file:
1. Open your shell profile file* and add the following line to the file:

**Posix shells like bash and zsh**
```bash
export PATH=$(go env GOPATH)/bin:$PATH
```
1. Now load the changes to your bash profile with `source ~/.bash_profile` or
`source ~/.bashrc`.

### Install Mage

We are transitioning from Make to [Mage]. Installing mage isn't strictly required,
you can always run `go run mage.go TARGET` instead of `mage TARGET`. However having
the tool saves typing and time!
Mage targets are not case-sensitive, but in our docs we use camel case to make
it easier to read. Run the following commands to install mage:
```bash
$ go run mage.go EnsureMage
$ mage
This is a magefile, and is a "makefile for go". See https://magefile.org/
Targets:
configureAgent sets up an Azure DevOps agent with Mage and ensures that GOPATH/bin is in PATH.
ensureMage Ensure Mage is installed and on the PATH.
setBinExecutable Run `chmod +x -R bin`.
startDocker Ensure the docker daemon is started and ready to accept connections.
testE2E Run end-to-end (e2e) tests
useXBuildBinaries Copy the cross-compiled binaries from xbuild into bin.
```
You know that your $GOPATH/bin is configured correctly if you see the output above
listing the defined mage targets.

**PowerShell**
```powershell
$env:PATH="$(go env GOPATH)\bin;$env:PATH"
```

1. Now load the changes to your bash profile with the source command or
open a new terminal.

**Posix shells like bash and zsh**

Replace PROFILE_PATH with the path to your profile
```bash
source PROFILE_PATH
```

**PowerShell**
```powershell
. $profile
```

You can enable tab completion for mage as well, so that you can type
`mage t[TAB]` and it will complete it with the name of matching targets.
\* There are a bunch of different shell profiles depending on your shell and customizations.
The default locations are:

1. Install bash-completion if it isn't already installed with either `brew install
bash-completion` (macOS) or `apt install bash-completion` (debian/ubuntu) depending
on your operating system.
1. Copy the mage-completion.sh script to a local directory:
```bash
cp scripts/mage-completion.sh ~
```
1. Open your ~/.bash_profile or ~/.bashrc file and add the following line to the
file:
* ~/.bash_profile or ~/.bashrc
* ~/.zshrc
* PowerShell doesn't have a profile by default. Here's how to find or create a [PowerShell profile].

```bash
source ~/mage-completion.sh
```
1. Now load the changes to your bash profile with `source ~/.bash_profile` or
`source ~/.bashrc`.
[PowerShell profile]: https://www.howtogeek.com/126469/how-to-create-a-powershell-profile/

## Checkout Code

Expand Down Expand Up @@ -183,6 +164,48 @@ the original porter repository and `origin` to refer to your fork:
main 7e120aab [upstream/main] Bump cnab-go
```
### Install Mage
We are transitioning from Make to [Mage]. Installing mage isn't strictly required,
you can always run `go run mage.go TARGET` instead of `mage TARGET`. However, having
the tool saves typing and time!

Mage targets are not case-sensitive, but in our docs we use camel case to make
it easier to read. Run the following commands from the porter directory to install mage:

```bash
$ go run mage.go EnsureMage
$ mage
This is a magefile, and is a "makefile for go". See https://magefile.org/
Targets:
<List of available targets>
```

You know that your $GOPATH/bin is configured correctly if you see a list of mage
targets.

You can enable tab completion for mage as well, so that you can type
`mage t[TAB]` and it will complete it with the name of matching targets.

1. Install bash-completion if it isn't already installed with either `brew install
bash-completion` (macOS) or `apt install bash-completion` (debian/ubuntu) depending
on your operating system.
1. Copy the mage-completion.sh script to a local directory:
```bash
cp scripts/mage-completion.sh ~
```
1. Open your ~/.bash_profile or ~/.bashrc file and add the following line to the
file:
```bash
source ~/mage-completion.sh
```
1. Now load the changes to your bash profile with `source ~/.bash_profile` or
`source ~/.bashrc`.
## Configure Signing
Porter requires that [all commits are signed][dco]. Run the following command to
Expand All @@ -207,6 +230,7 @@ You may see a message about your Go bin not being in your PATH. If that happens,
[Add $GOPATH/bin to your PATH](#add-gopathbin-to-your-path) and then run
`make build` again. It should work now but if it doesn't, please let us know!
## Verify Porter
After you have built Porter, the resulting `porter` command-line tool is placed
Expand All @@ -221,15 +245,30 @@ Docker is installed and configured properly too. This is an abbreviated version
of our [QuickStart]. If you are new to Porter, we recommend trying the
QuickStart as well to learn how Porter works.
[QuickStart]: /quickstart/
### Use the locally built porter
First let's do some quick configuration so that you can use the porter
executable that you just built, instead of the installed porter. This change
isn't permanent and only affects your current shell session.
isn't permanent and only affects your current shell session.
If you skip this set up, and `./bin/porter` without PORTER_HOME set it
will use the files in the `~/.porter` instead of what you built. This can
result in not actually using your local binaries in bin.
**Bash**
```bash
export PORTER_HOME=`pwd`/bin
alias porter=`pwd`/bin/porter
```
**PowerShell**
```powershell
$env:PORTER_HOME="$pwd\bin"
Set-Alias -Name porter -Value "$pwd\bin\porter.exe"
```
Let's use what you just built and verify that everything is working:

1. Make a temporary directory for your bundle:
Expand All @@ -254,8 +293,6 @@ Let's use what you just built and verify that everything is working:
porter list
```
[QuickStart]: /quickstart/
## Change Porter
Let's make a change to Porter by adding a new command, `porter hello --name
Expand Down Expand Up @@ -342,21 +379,35 @@ YOURNAME` that prints `Hello YOURNAME!`.
## Test Your Changes
After you have modified Porter, let's rebuild and test your changes.
After you have modified Porter, and [aliased the `porter` command to use your
local changes](#use-the-locally-built-porter), let's rebuild and test your changes.
1. Build porter to incorporate your new command by running `make build`.
1. Run `./bin/porter hello --help` to see the helptext for your command.
1. Run `./bin/porter --name YOURNAME` to try out your new command.
1. Run `porter hello --help` to see the helptext for your command.
1. Run `porter --name YOURNAME` to try out your new command.
```bash
$ porter hello --name Carolyn
Hello Carolyn!
```
That verifies your change but let's also run the [unit tests] and [end-to-end] tests
to make sure there aren't any regressions.
```
make test-unit
mage teste2e
```
[unit tests]: /contribute/#unit-tests
[end-to-end]: /contribute/#end-to-end-tests
## Celebrate!
You can now build Porter, modify its code and try out your changes! 🎉 You are
now ready to [find an issue] and contribute to Porter.
You can now build Porter, modify its code and try out your changes! 🎉 Your next
steps should be to read our [Contributing Guide] to understand how to [find an
issue] and contribute to Porter.
[Contributing Guide]: /contribute/
[find an issue]: /contribute/guide/#find-an-issue
[Mage]: https://magefile.org
[Mage]: https://magefile.org
22 changes: 12 additions & 10 deletions docs/content/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ porter create
This will create a file called **porter.yaml** which contains the configuration
for your bundle. Modify and customize this file for your application's needs.

Here is a very basic **porter.yaml** file:
This is a snippet of the **porter.yaml** file made by `porter create` to give you
an idea of what it will look like. This bundle is using a helper script, **helpers.sh**,
so that we aren't trying to embed bash inside yaml.

```yaml
name: porter-hello
Expand All @@ -33,23 +35,23 @@ mixins:
install:
- exec:
description: "Install Hello World"
command: bash
flags:
c: echo Hello World
command: ./helpers.sh
arguments:
- install

upgrade:
- exec:
description: "World 2.0"
command: bash
flags:
c: echo World 2.0
command: ./helpers.sh
arguments:
- upgrade

uninstall:
- exec:
description: "Uninstall Hello World"
command: bash
flags:
c: echo Goodbye World
command: ./helpers.sh
arguments:
- uninstall
```
## Build the bundle
Expand Down
10 changes: 6 additions & 4 deletions magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ func porter(args ...string) sh.PreparedCommand {

// Run end-to-end (e2e) tests
func TestE2E() error {
mg.Deps(startLocalDockerRegistry)
defer stopLocalDockerRegistry()
mg.Deps(StarlDockerRegistry)
defer StopDockerRegistry()

// Only do verbose output of tests when called with `mage -v TestE2E`
v := ""
Expand Down Expand Up @@ -215,7 +215,8 @@ func isDockerReady() (bool, error) {
return err == nil, nil
}

func startLocalDockerRegistry() error {
// Start a Docker registry to use with the tests.
func StarlDockerRegistry() error {
mg.Deps(StartDocker)
if isContainerRunning(registryContainer) {
return nil
Expand All @@ -230,7 +231,8 @@ func startLocalDockerRegistry() error {
return shx.RunE("docker", "run", "-d", "-p", "5000:5000", "--name", registryContainer, "registry:2")
}

func stopLocalDockerRegistry() error {
// Stop the Docker registry used by the tests.
func StopDockerRegistry() error {
if containerExists(registryContainer) {
fmt.Println("Stopping local docker registry")
return removeContainer(registryContainer)
Expand Down

0 comments on commit 8e03c7d

Please sign in to comment.