# Contributing to Summon

Thanks for your interest in Summon!


For general contribution and community guidelines, please see the [community repo](https://github.com/cyberark/community).
In particular, before contributing please review our [contributor licensing guide](https://github.com/cyberark/community/blob/main/CONTRIBUTING.md#when-the-repo-does-not-include-the-cla)
to ensure your contribution is compliant with our contributor license agreements.

## Development

### Building and packaging

To build versions for Linux, macOS and Windows:

```
./build --snapshot
```

Binaries will be placed in `dist/goreleaser`.

### Running the project from source

Run the project with:

```
go run cmd/main.go
```

### Unit Testing

Run tests with `go test -v ./...` or `./test` (for CI).

### Smoke Testing

Smoke testing is used to verify that the output generated by our `./build` script
functions as expected.

This is done through running the generated binaries against production or custom
providers and verifying the output manually.

### Generating Mock Providers

For testing purposes, it is often necessary to create a "mock" provider which can verify
input and output. This can be done by creating a script which can be run by Summon and
placing it in the default path, `/usr/local/lib/summon/`

For example, we can create a provider that simply returns the literal variable that is
passed into it:

1. Create a shell script in your Summon path called `mock`:
```bash
$ echo '#!/bin/bash -e \n echo "$@"' > /usr/local/lib/summon/mock
```

2. Make your new script executable
```bash
$ sudo chmod +x /usr/local/lib/summon/mock
```

3. Use your 'provider' with the following command
```bash
$ summon -p mock --yaml 'FOO: !var bar' /bin/bash -ec 'echo $FOO'
bar
```

This mock provider can then be used against locally generated binaries or the source
itself, as needed.

## Releasing

The following checklist should be followed when creating a release:

- [ ] Open a PR with the following changes for `main` branch and wait for it to be merged:
  - [ ] Bump release version in [`pkg/summon/version.go`](pkg/summon/version.go).
  - [ ] Bump version in [`CHANGELOG.md`](CHANGELOG.md).

- [ ] Retrieve artifacts generated by jenkins to perform smoke tests
   - Note: You can manually [`Build`](./build) the release. Output is placed in the `dist` folder
   - [ ] Binaries for smoke testing are found in the following directories
        - Linux:   `dist/goreleaser/summon-linux_linux_amd64_v1`
        - MacOS:   `dist/goreleaser/summon_darwin_amd64_v1`
                   `dist/goreleaser/summon-arm_darwin_arm64`
        - Windows: `dist/goreleaser/summon_windows_amd64_v1`

- [ ] Create an [annotated tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging#_annotated_tags)
      of the merged commit with the name `v<version>` and push it to the
      repository. For example: `git tag -a v<version> -m "Release of v<version>"`
      This will automatically create a draft release with artifacts attached.

- [ ] Publish the draft as "pre-released".

- [ ] Update homebrew tools
  - [ ] In [`cyberark/homebrew-tools`](https://github.com/cyberark/homebrew-tools)
        repo, create a PR to update the [`summon.rb` formula](https://github.com/cyberark/homebrew-tools/blob/main/summon.rb#L4-L6)
        using the file `dist/goreleaser/summon.rb` retrieved from Jenkins artifacts.
        Make sure the SHA hashes for the artifacts match the values in the `SHA256SUMS.txt`
        file attached to the release.

- [ ] Publish the release as a regular release.

- [ ] Perform smoke tests, using this release, on the following platforms:
    - Linux
    - Windows
    - MacOS

## Troubleshooting

The following issues, and their respective solutions, are occasionally encountered when
using Summon for the first time.

Q:  When I run commands like this,
```
$ summon -p <provider> echo $FOO
```
the variable `FOO` appears to be empty.

A:  When running Summon directly in a shell, your current shell(not Summon's shell) interprets
    the value of `FOO` before Summon does. To make sure that the variable is correctly
    expanded, you need to wrap your `echo` command with something that understands
    environment variables passed from summon (like `bash`).
    A working example would be:
```
$ summon -p <provider> /bin/bash -ec 'echo $FOO'
bar
```

Q:  When I run commands like this,
```
summon -p <provider> --yaml "FOO: !var bar" /bin/bash -c 'echo $FOO'
```
I receive the following error:
```
yaml: unmarshal errors:
  line 1: cannot unmarshal !!str `FOO !va...` into map[string]yaml.Node
```
OR my output is empty.

A:  In the first case, the `!` is part of history expansion in bash. To use it in this
    case, the string will need to be enclosed in single quotes.
    In the second case, the `echo` statement should also be enclosed in single quotes, to
    avoid your current shell interpolating the variable before summon can.
    A working example would be:
```
$ summon -p <provider> --yaml 'FOO: !var bar' /bin/bash -ec 'echo $FOO'
bar
```
