mirror of
https://github.com/actions/setup-go.git
synced 2024-11-29 08:00:56 -05:00
16a646f523
Skip to main content GitHub Docs GitHub Actions/Using workflows/Cache dependencies Caching dependencies to speed up workflows In this article About caching workflow dependencies Comparing artifacts and dependency caching Restrictions for accessing a cache Using the cache action Matching a cache key Usage limits and eviction policy Managing caches To make your workflows faster and more efficient, you can create and use caches for dependencies and other commonly reused files. About caching workflow dependencies Workflow runs often reuse the same outputs or downloaded dependencies from one run to another. For example, package and dependency management tools such as Maven, Gradle, npm, and Yarn keep a local cache of downloaded dependencies. Jobs on GitHub-hosted runners start in a clean runner image and must download dependencies each time, causing increased network utilization, longer runtime, and increased cost. To help speed up the time it takes to recreate files like dependencies, GitHub can cache files you frequently use in workflows. To cache dependencies for a job, you can use GitHub's cache action. The action creates and restores a cache identified by a unique key. Alternatively, if you are caching the package managers listed below, using their respective setup-* actions requires minimal configuration and will create and restore dependency caches for you. Package managers setup-* action for caching npm, Yarn, pnpm setup-node pip, pipenv, Poetry setup-python Gradle, Maven setup-java RubyGems setup-ruby Go go.sum setup-go Warning: Be mindful of the following when using caching with GitHub Actions: We recommend that you don't store any sensitive information in the cache. For example, sensitive information can include access tokens or login credentials stored in a file in the cache path. Also, command line interface (CLI) programs like docker login can save access credentials in a configuration file. Anyone with read access can create a pull request on a repository and access the contents of a cache. Forks of a repository can also create pull requests on the base branch and access caches on the base branch. When using self-hosted runners, caches from workflow runs are stored on GitHub-owned cloud storage. A customer-owned storage solution is only available with GitHub Enterprise Server. Comparing artifacts and dependency caching Artifacts and caching are similar because they provide the ability to store files on GitHub, but each feature offers different use cases and cannot be used interchangeably. Use caching when you want to reuse files that don't change often between jobs or workflow runs, such as build dependencies from a package management system. Use artifacts when you want to save files produced by a job to view after a workflow run has ended, such as built binaries or build logs. For more information on workflow run artifacts, see "Storing workflow data as artifacts." Restrictions for accessing a cache Access restrictions provide cache isolation and security by creating a logical boundary between different branches or tags. Workflow runs can restore caches created in either the current branch or the default branch (usually main). If a workflow run is triggered for a pull request, it can also restore caches created in the base branch, including base branches of forked repositories. For example, if the branch feature-b has the base branch feature-a, a workflow run triggered on a pull request would have access to caches created in the default main branch, the base feature-a branch, and the current feature-b branch. Workflow runs cannot restore caches created for child branches or sibling branches. For example, a cache created for the child feature-b branch would not be accessible to a workflow run triggered on the parent main branch. Similarly, a cache created for the feature-a branch with the base main would not be accessible to its sibling feature-c branch with the base main. Workflow runs also cannot restore caches created for different tag names. For example, a cache created for the tag release-a with the base main would not be accessible to a workflow run triggered for the tag release-b with the base main. When a cache is created by a workflow run triggered on a pull request, the cache is created for the merge ref (refs/pull/.../merge). Because of this, the cache will have a limited scope and can only be restored by re-runs of the pull request. It cannot be restored by the base branch or other pull requests targeting that base branch. Multiple workflow runs in a repository can share caches. A cache created for a branch in a workflow run can be accessed and restored from another workflow run for the same repository and branch. Using the cache action The cache action will attempt to restore a cache based on the key you provide. When the action finds a cache that exactly matches the key, the action restores the cached files to the path you configure. You can optionally provide a list of restore-keys to use in case the key doesn't match an existing cache. A list of restore-keys is useful when you are restoring a cache from another branch because restore-keys can partially match cache keys. For more information about matching restore-keys, see "Matching a cache key." If there is an exact match to the provided key, this is considered a cache hit. If no cache exactly matches the provided key, this is considered a cache miss. On a cache miss, the action automatically creates a new cache if the job completes successfully. The new cache will use the key you provided and contains the files you specify in path. For more information about how this is handled, see "Cache hits and misses." You cannot change the contents of an existing cache. Instead, you can create a new cache with a new key. Input parameters for the cache action key: Required The key created when saving a cache and the key used to search for a cache. It can be any combination of variables, context values, static strings, and functions. Keys have a maximum length of 512 characters, and keys longer than the maximum length will cause the action to fail. path: Required The path(s) on the runner to cache or restore. You can specify a single path, or you can add multiple paths on separate lines. For example: - name: Cache Gradle packages uses: actions/cache@v3 with: path: | ~/.gradle/caches ~/.gradle/wrapper You can specify either directories or single files, and glob patterns are supported. You can specify absolute paths, or paths relative to the workspace directory. restore-keys: Optional A string containing alternative restore keys, with each restore key placed on a new line. If no cache hit occurs for key, these restore keys are used sequentially in the order provided to find and restore a cache. For example: restore-keys: | npm-feature-${{ hashFiles('package-lock.json') }} npm-feature- npm- enableCrossOsArchive: Optional A boolean value that when enabled, allows Windows runners to save or restore caches independent of the operating system the cache was created on. If this parameter is not set, it defaults to false. For more information, see Cross OS cache in the Actions Cache documentation. Output parameters for the cache action cache-hit: A boolean value to indicate an exact match was found for the key. Cache hits and misses When key exactly matches an existing cache, it's called a cache hit, and the action restores the cached files to the path directory. When key doesn't match an existing cache, it's called a cache miss, and a new cache is automatically created if the job completes successfully. When a cache miss occurs, the action also searches your specified restore-keys for any matches: If you provide restore-keys, the cache action sequentially searches for any caches that match the list of restore-keys. When there is an exact match, the action restores the files in the cache to the path directory. If there are no exact matches, the action searches for partial matches of the restore keys. When the action finds a partial match, the most recent cache is restored to the path directory. The cache action completes and the next step in the job runs. If the job completes successfully, the action automatically creates a new cache with the contents of the path directory. For a more detailed explanation of the cache matching process, see "Matching a cache key." Example using the cache action This example creates a new cache when the packages in package-lock.json file change, or when the runner's operating system changes. The cache key uses contexts and expressions to generate a key that includes the runner's operating system and a SHA-256 hash of the package-lock.json file. YAML name: Caching with npm on: push jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Cache node modules id: cache-npm uses: actions/cache@v3 env: cache-name: cache-node-modules with: # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }} name: List the state of node modules continue-on-error: true run: npm list - name: Install dependencies run: npm install - name: Build run: npm run build - name: Test run: npm test Using contexts to create cache keys A cache key can include any of the contexts, functions, literals, and operators supported by GitHub Actions. For more information, see "Contexts" and "Expressions." Using expressions to create a key allows you to automatically create a new cache when dependencies change. For example, you can create a key using an expression that calculates the hash of an npm package-lock.json file. So, when the dependencies that make up the package-lock.json file change, the cache key changes and a new cache is automatically created. npm-${{ hashFiles('package-lock.json') }} GitHub evaluates the expression hash "package-lock.json" to derive the final key. npm-d5ea0750 Using the output of the cache action You can use the output of the cache action to do something based on whether a cache hit or miss occurred. When an exact match is found for a cache for the specified key, the cache-hit output is set to true. In the example workflow above, there is a step that lists the state of the Node modules if a cache miss occurred: - if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }} name: List the state of node modules continue-on-error: true run: npm list Matching a cache key The cache action first searches for cache hits for key and the cache version in the branch containing the workflow run. If there is no hit, it searches for restore-keys and the version. If there are still no hits in the current branch, the cache action retries same steps on the default branch. Please note that the scope restrictions apply during the search. For more information, see "Restrictions for accessing a cache." Cache version is a way to stamp a cache with metadata of the path and the compression tool used while creating the cache. This ensures that the consuming workflow run uniquely matches a cache it can actually decompress and use. For more information, see Cache Version in the Actions Cache documentation. restore-keys allows you to specify a list of alternate restore keys to use when there is a cache miss on key. You can create multiple restore keys ordered from the most specific to least specific. The cache action searches the restore-keys in sequential order. When a key doesn't match directly, the action searches for keys prefixed with the restore key. If there are multiple partial matches for a restore key, the action returns the most recently created cache. Example using multiple restore keys restore-keys: | npm-feature-${{ hashFiles('package-lock.json') }} npm-feature- npm- The runner evaluates the expressions, which resolve to these restore-keys: restore-keys: | npm-feature-d5ea0750 npm-feature- npm- The restore key npm-feature- matches any key that starts with the string npm-feature-. For example, both of the keys npm-feature-fd3052de and npm-feature-a9b253ff match the restore key. The cache with the most recent creation date would be used. The keys in this example are searched in the following order: npm-feature-d5ea0750 matches a specific hash. npm-feature- matches cache keys prefixed with npm-feature-. npm- matches any keys prefixed with npm-. Example of search priority key: npm-feature-d5ea0750 restore-keys: | npm-feature- npm- For example, if a pull request contains a feature branch and targets the default branch (main), the action searches for key and restore-keys in the following order: Key npm-feature-d5ea0750 in the feature branch Key npm-feature- in the feature branch Key npm- in the feature branch Key npm-feature-d5ea0750 in the main branch Key npm-feature- in the main branch Key npm- in the main branch Usage limits and eviction policy GitHub will remove any cache entries that have not been accessed in over 7 days. There is no limit on the number of caches you can store, but the total size of all caches in a repository is limited to 10 GB. Once a repository has reached its maximum cache storage, the cache eviction policy will create space by deleting the oldest caches in the repository. If you exceed the limit, GitHub will save the new cache but will begin evicting caches until the total size is less than the repository limit. The cache eviction process may cause cache thrashing, where caches are created and deleted at a high frequency. To reduce this, you can review the caches for a repository and take corrective steps, such as removing caching from specific workflows. For more information, see "Managing caches." Managing caches To manage caches created from your workflows, you can: View a list of all cache entries for a repository. Filter and sort the list of caches using specific metadata such as cache size, creation time, or last accessed time. Delete cache entries from a repository. Monitor aggregate cache usage for repositories and organizations. There are multiple ways to manage caches for your repositories: Using the GitHub web interface, as shown below. Using the REST API. For more information, see the "GitHub Actions Cache" REST API documentation. Installing the gh cache subcommand to manage your caches from the command line. For more information, see the GitHub CLI documentation. Note: If you are doing this manually, ensure you have version 2.32.0 or higher of the CLI installed. Viewing cache entries You can use the web interface to view a list of cache entries for a repository. In the cache list, you can see how much disk space each cache is using, when the cache was created, and when the cache was last used. On GitHub.com, navigate to the main page of the repository. Under your repository name, click Actions. Screenshot of the tabs for the "github/docs" repository. The "Actions" tab is highlighted with an orange outline. In the left sidebar, under the "Management" section, click Caches. Review the list of cache entries for the repository. To search for cache entries used for a specific branch, click the Branch dropdown menu and select a branch. The cache list will display all of the caches used for the selected branch. To search for cache entries with a specific cache key, use the syntax key: key-name in the Filter caches field. The cache list will display caches from all branches where the key was used. Screenshot of the list of cache entries. Deleting cache entries Users with write access to a repository can use the GitHub web interface to delete cache entries. On GitHub.com, navigate to the main page of the repository. Under your repository name, click Actions. Screenshot of the tabs for the "github/docs" repository. The "Actions" tab is highlighted with an orange outline. In the left sidebar, under the "Management" section, click Caches. To the right of the cache entry you want to delete, click . Screenshot of the list of cache entries. A trash can icon, used to delete a cache, is highlighted with a dark orange outline. Force deleting cache entries Caches have branch scope restrictions in place, which means some caches have limited usage options. For more information on cache scope restrictions, see "Caching dependencies to speed up workflows." If caches limited to a specific branch are using a lot of storage quota, it may cause caches from the default branch to be created and deleted at a high frequency. For example, a repository could have many new pull requests opened, each with their own caches that are restricted to that branch. These caches could take up the majority of the cache storage for that repository. Once a repository has reached its maximum cache storage, the cache eviction policy will create space by deleting the oldest caches in the repository. In order to prevent cache thrashing when this happens, you can set up workflows to delete caches on a faster cadence than the cache eviction policy will. You can use the gh-actions-cache CLI extension to delete caches for specific branches. This example workflow uses gh-actions-cache to delete up to 100 caches created by a branch once a pull request is closed. name: cleanup caches by a branch on: pull_request: types: - closed jobs: cleanup: runs-on: ubuntu-latest steps: - name: Cleanup run: | gh extension install actions/gh-actions-cache echo "Fetching list of cache key" cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 ) ## Setting this to not fail the workflow while deleting cache keys. set +e echo "Deleting caches..." for cacheKey in $cacheKeysForPR do gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm done echo "Done" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO: ${{ github.rizqpay }} BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge Alternatively, you can use the API to automatically list or delete all caches on your own cadence. For more information, see "GitHub Actions Cache." Press alt+up to activate Help and support Did this doc help you? Privacy policy Help us make these docs great! All GitHub docs are open source. See something that's wrong or unclear? Submit a pull request. Learn how to contribute Still need help? Ask the GitHub community Contact support Legal © 2023 GitHub, Inc. Terms Privacy Status Pricing Expert services Blog
270 lines
9 KiB
Markdown
270 lines
9 KiB
Markdown
# setup-go
|
|
|
|
|
|
[![Basic validation](https://github.com/actions/setup-go/actions/workflows/basic-validation.yml/badge.svg)](https://github.com/actions/setup-go/actions/workflows/basic-validation.yml)
|
|
[![Validate 'setup-go'](https://github.com/actions/setup-go/actions/workflows/versions.yml/badge.svg)](https://github.com/actions/setup-go/actions/workflows/versions.yml)
|
|
|
|
This action sets up a go environment for use in actions by:
|
|
|
|
- Optionally downloading and caching a version of Go by version and adding to `PATH`.
|
|
- Registering problem matchers for error output.
|
|
|
|
# V4
|
|
|
|
The V4 edition of the action offers:
|
|
|
|
- Enabled caching by default
|
|
|
|
The action will try to enable caching unless the `cache` input is explicitly set to false.
|
|
|
|
Please see "[Caching dependency files and build outputs](https://github.com/actions/setup-go#caching-dependency-files-and-build-outputs)" for more information.
|
|
|
|
# V3
|
|
|
|
The V3 edition of the action offers:
|
|
|
|
- Adds `GOBIN` to the `PATH`
|
|
- Proxy support
|
|
- Check latest version
|
|
- Caching packages dependencies
|
|
- stable and oldstable aliases
|
|
- Bug Fixes (including issues around version matching and semver)
|
|
|
|
The action will first check the local cache for a version match. If a version is not found locally, it will pull it from
|
|
the `main` branch of the [go-versions](https://github.com/actions/go-versions/blob/main/versions-manifest.json)
|
|
repository. On miss or failure, it will fall back to downloading directly
|
|
from [go dist](https://storage.googleapis.com/golang). To change the default behavior, please use
|
|
the [check-latest input](#check-latest-version).
|
|
|
|
**Note:** The `setup-go` action uses executable binaries which are built by Golang side. The action does not build
|
|
golang from source code.
|
|
|
|
Matching by [semver spec](https://github.com/npm/node-semver):
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: '^1.13.1' # The Go version to download (if necessary) and use.
|
|
- run: go version
|
|
```
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: '>=1.17.0'
|
|
- run: go version
|
|
```
|
|
|
|
> **Note**: Due to the peculiarities of YAML parsing, it is recommended to wrap the version in single quotation marks:
|
|
>
|
|
> ```yaml
|
|
> go-version: '1.20'
|
|
> ```
|
|
>
|
|
> The recommendation is based on the YAML parser's behavior, which interprets non-wrapped values as numbers and, in the case of version 1.20, trims it down to 1.2, which may not be very obvious.
|
|
Matching an unstable pre-release:
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: '1.18.0-rc.1' # The Go version to download (if necessary) and use.
|
|
- run: go version
|
|
```
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: '1.16.0-beta.1' # The Go version to download (if necessary) and use.
|
|
- run: go version
|
|
```
|
|
|
|
# Usage
|
|
|
|
See [action.yml](action.yml)
|
|
|
|
## Basic
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: '1.16.1' # The Go version to download (if necessary) and use.
|
|
- run: go run hello.go
|
|
```
|
|
|
|
## Check latest version
|
|
|
|
The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability
|
|
and if you want to ensure a specific Go version is always used.
|
|
|
|
If `check-latest` is set to `true`, the action first checks if the cached version is the latest one. If the locally
|
|
cached version is not the most up-to-date, a Go version will then be downloaded. Set `check-latest` to `true` if you
|
|
want the most up-to-date Go version to always be used.
|
|
|
|
> Setting `check-latest` to `true` has performance implications as downloading Go versions is slower than using cached
|
|
> versions.
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: '1.14'
|
|
check-latest: true
|
|
- run: go run hello.go
|
|
```
|
|
|
|
## Using stable/oldstable aliases
|
|
|
|
If `stable` is provided, action will get the latest stable version from
|
|
the [`go-versions`](https://github.com/actions/go-versions/blob/main/versions-manifest.json) repository manifest.
|
|
|
|
If `oldstable` is provided, when current release is 1.19.x, action will resolve version as 1.18.x, where x is the latest
|
|
patch release.
|
|
|
|
**Note:** using these aliases will result in same version as using corresponding minor release with `check-latest` input
|
|
set to `true`
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: 'stable'
|
|
- run: go run hello.go
|
|
```
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: 'oldstable'
|
|
- run: go run hello.go
|
|
```
|
|
|
|
## Caching dependency files and build outputs:
|
|
|
|
The action has a built-in functionality for caching and restoring go modules and build outputs. It
|
|
uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood but requires less configuration settings.
|
|
The `cache` input is optional, and caching is turned on by default.
|
|
|
|
The action defaults to search for the dependency file - go.sum in the repository root, and uses its hash as a part of
|
|
the cache key. Use `cache-dependency-path` input for cases when multiple dependency files are used, or they are located
|
|
in different subdirectories. The input supports glob patterns.
|
|
|
|
If some problem that prevents success caching happens then the action issues the warning in the log and continues the execution of the pipeline.
|
|
|
|
**Caching in monorepos**
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version: '1.17'
|
|
check-latest: true
|
|
cache-dependency-path: |
|
|
subdir/go.sum
|
|
tools/go.sum
|
|
# cache-dependency-path: "**/*.sum"
|
|
|
|
- run: go run hello.go
|
|
```
|
|
|
|
## Getting go version from the go.mod file
|
|
|
|
The `go-version-file` input accepts a path to a `go.mod` file or a `go.work` file that contains the version of Go to be
|
|
used by a project. As the `go.mod` file contains only major and minor (e.g. 1.18) tags, the action will search for the
|
|
latest available patch version sequentially in the runner's directory with the cached tools, in
|
|
the [versions-manifest.json](https://github.com/actions/go-versions/blob/main/versions-manifest.json) file or at the go
|
|
servers.
|
|
|
|
If both the `go-version` and the `go-version-file` inputs are provided then the `go-version` input is used.
|
|
> The action will search for the `go.mod` file relative to the repository root
|
|
|
|
```yaml
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-go@v4
|
|
with:
|
|
go-version-file: 'path/to/go.mod'
|
|
- run: go version
|
|
```
|
|
|
|
## Matrix testing
|
|
|
|
```yaml
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
go: [ '1.14', '1.13' ]
|
|
name: Go ${{ matrix.go }} sample
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Setup go
|
|
uses: actions/setup-go@v4
|
|
with:
|
|
go-version: ${{ matrix.go }}
|
|
- run: go run hello.go
|
|
```
|
|
|
|
### Supported version syntax
|
|
|
|
The `go-version` input supports the following syntax:
|
|
|
|
- Specific versions: `1.15`, `1.16.1`, `1.17.0-rc.2`, `1.16.0-beta.1`
|
|
- SemVer's version range syntax: `^1.13.1`, `>=1.18.0-rc.1`
|
|
|
|
For more information about semantic versioning, please refer to [semver](https://github.com/npm/node-semver)
|
|
documentation.
|
|
|
|
## Using `setup-go` on GHES
|
|
|
|
`setup-go` comes pre-installed on the appliance with GHES if Actions is enabled. When dynamically downloading Go
|
|
distributions, `setup-go` downloads distributions from [`actions/go-versions`](https://github.com/actions/go-versions)
|
|
on github.com (outside of the appliance). These calls to `actions/go-versions` are made via unauthenticated requests,
|
|
which are limited
|
|
to [60 requests per hour per IP](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting). If
|
|
more requests are made within the time frame, then you will start to see rate-limit errors during downloading that looks
|
|
like: `##[error]API rate limit exceeded for...`. After that error the action will try to download versions directly
|
|
from https://storage.googleapis.com/golang, but it also can have rate limit so it's better to put token.
|
|
|
|
To get a higher rate limit, you
|
|
can [generate a personal access token on github.com](https://github.com/settings/tokens/new) and pass it as the `token`
|
|
input for the action:
|
|
|
|
```yaml
|
|
uses: actions/setup-go@v4
|
|
with:
|
|
token: ${{ secrets.GH_DOTCOM_TOKEN }}
|
|
go-version: '1.18'
|
|
```
|
|
|
|
If the runner is not able to access github.com, any Go versions requested during a workflow run must come from the
|
|
runner's tool cache.
|
|
See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)"
|
|
for more information.
|
|
|
|
# License
|
|
|
|
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
|
|
|
# Contributions
|
|
|
|
Contributions are welcome! See [Contributor's Guide](docs/contributors.md)
|
|
|
|
## Code of Conduct
|
|
|
|
:wave: Be nice. See [our code of conduct](CODE_OF_CONDUCT.md)
|