├── .gitignore ├── toodaloo.md ├── src ├── tcld │ ├── NOTES.md │ ├── README.md │ ├── devcontainer-feature.json │ └── install.sh ├── cobra-cli │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ └── install.sh └── buf │ ├── NOTES.md │ ├── devcontainer-feature.json │ ├── README.md │ ├── install.sh │ └── library_scripts.sh ├── .markdownlint.json ├── .vscode └── settings.json ├── .editorconfig ├── images ├── base │ └── .devcontainer │ │ ├── gitconfig │ │ ├── direnv.toml │ │ ├── bash_aliases │ │ ├── devcontainer.json │ │ └── Dockerfile ├── temporal_min │ └── .devcontainer │ │ └── devcontainer.json └── full │ └── .devcontainer │ └── devcontainer.json ├── .licenserc.yaml ├── .cruft.json ├── .devcontainer └── devcontainer.json ├── .github └── workflows │ ├── release.yml │ ├── stale.yml │ ├── update-documentation.yml │ └── build.yml ├── .commitlintrc.yaml ├── Makefile ├── .pre-commit-config.yaml ├── README.md ├── CODE_OF_CONDUCT.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | tmp 3 | 4 | node_modules 5 | 6 | .idea 7 | .DS_Store 8 | Thumbs.db 9 | .commit 10 | .envrc 11 | -------------------------------------------------------------------------------- /toodaloo.md: -------------------------------------------------------------------------------- 1 | # List of todos 2 | 3 | > Generated by [Toodaloo](https://toodaloo.dev) 4 | 5 | 🎉🎉🎉 Woohoo! Nothing to do 🎉🎉🎉 6 | -------------------------------------------------------------------------------- /src/tcld/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Temporal Cloud CLI 2 | 3 | This feature installs the [Temporal Cloud CLI](https://github.com/temporalio/tcld) 4 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD007": { 3 | "indent": 2 4 | }, 5 | "MD013": { 6 | "code_blocks": false, 7 | "tables": false 8 | }, 9 | "MD032": false, 10 | "MD033": false, 11 | "default": true 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.rulers": [ 4 | 80 5 | ], 6 | "yaml.schemas": { 7 | "https://json.schemastore.org/github-workflow.json": [ 8 | ".github/workflows/*.{yml,yaml}" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.go] 13 | indent_style = tab 14 | indent_size = 4 15 | 16 | [Makefile] 17 | indent_style = tab 18 | indent_size = 4 19 | -------------------------------------------------------------------------------- /src/cobra-cli/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Cobra CLI 2 | 3 | This Feature includes [the Cobra CLI](https://github.com/spf13/cobra-cli/) 4 | 5 | ## OS Support 6 | 7 | This Feature should work on recent versions of Debian/Ubuntu-based distributions 8 | with the `apt` package manager installed. Golang is also required in the container. 9 | 10 | `bash` is required to execute the `install.sh` script. 11 | -------------------------------------------------------------------------------- /src/buf/NOTES.md: -------------------------------------------------------------------------------- 1 | ## Buf 2 | 3 | This is forked from [@marcozac's repo](https://github.com/marcozac/devcontainer-features/tree/main/src/buf) 4 | with a couple of bugfixes: 5 | 6 | * Changed the installation script to use `ghcr.io/devcontainers-extra/features/gh-release` 7 | since `ghcr.io/devcontainers-contrib/features/gh-release` is now removed. 8 | * Fixed [#28](https://github.com/marcozac/devcontainer-features/issues/28) 9 | -------------------------------------------------------------------------------- /images/base/.devcontainer/gitconfig: -------------------------------------------------------------------------------- 1 | [alias] 2 | cp = cherry-pick 3 | co = checkout 4 | ci = commit 5 | st = status 6 | lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an - %ae>%Creset' --abbrev-commit 7 | [core] 8 | pager = diff-so-fancy | less --tabs=4 -RFX 9 | [init] 10 | defaultBranch = main 11 | [interactive] 12 | diffFilter = diff-so-fancy --patch 13 | [push] 14 | autoSetupRemote = true 15 | [pull] 16 | rebase = true 17 | -------------------------------------------------------------------------------- /.licenserc.yaml: -------------------------------------------------------------------------------- 1 | header: 2 | license: 3 | spdx-id: Apache-2.0 4 | copyright-owner: Simon Emms 5 | copyright-year: 2023 6 | paths-ignore: 7 | - "**/dist" 8 | - "**/tmp" 9 | - LICENSE 10 | - "**/.*" 11 | - "**/go.*" 12 | - "**/*.{json,md,yml,yaml}" 13 | - gitconfig 14 | - "**/.gitkeep" 15 | comment: on-failure 16 | language: 17 | Go: 18 | extensions: 19 | - ".go" 20 | comment_style_id: SlashAsterisk 21 | 22 | dependency: 23 | files: 24 | - go.mod # If this is a Go project. 25 | -------------------------------------------------------------------------------- /.cruft.json: -------------------------------------------------------------------------------- 1 | { 2 | "template": "https://github.com/mrsimonemms/new", 3 | "commit": "12e795a5cac56f7b4525274df94dbd947930187f", 4 | "checkout": null, 5 | "context": { 6 | "cookiecutter": { 7 | "project_name": "devcontainers", 8 | "description": "Prebuilt Dev Container images", 9 | "author": "Simon Emms ", 10 | "_template": "https://github.com/mrsimonemms/new", 11 | "_commit": "12e795a5cac56f7b4525274df94dbd947930187f" 12 | } 13 | }, 14 | "directory": "blank", 15 | "skip": [ 16 | ".git" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/cobra-cli/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Cobra CLI", 3 | "id": "cobra-cli", 4 | "version": "1.0.0", 5 | "description": "Install the Cobra CLI", 6 | "documentationURL": "https://github.com/mrsimonemms/devcontainers/tree/main/features/cobra-cli", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "proposals": [ 11 | "latest", 12 | "v1.3.0" 13 | ], 14 | "default": "latest", 15 | "description": "Select the version you would like to install" 16 | } 17 | }, 18 | "installsAfter": [ 19 | "ghcr.io/devcontainers/features/common-utils", 20 | "ghcr.io/devcontainers/features/go" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "ghcr.io/mrsimonemms/devcontainers/full", 3 | "name": "devcontainer", 4 | "features": {}, 5 | "customizations": { 6 | "vscode": { 7 | "settings": { 8 | "json.schemas": [ 9 | { 10 | "fileMatch": [ 11 | "*/devcontainer-feature.json" 12 | ], 13 | "url": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainerFeature.schema.json" 14 | } 15 | ] 16 | }, 17 | "extensions": [ 18 | "tamasfe.even-better-toml" 19 | ] 20 | } 21 | }, 22 | "updateContentCommand": "npm install -g @devcontainers/cli" 23 | } 24 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release dev container features 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | permissions: 8 | contents: write 9 | packages: write 10 | jobs: 11 | deploy: 12 | if: ${{ github.ref == 'refs/heads/main' }} 13 | runs-on: ubuntu-latest 14 | permissions: 15 | packages: write 16 | contents: write 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Publish 21 | uses: devcontainers/action@v1 22 | with: 23 | publish-features: "true" 24 | base-path-to-features: "./src" 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Close stale issues and PRs 2 | on: 3 | schedule: 4 | - cron: 0 2 * * * 5 | workflow_dispatch: 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | contents: write 11 | issues: write 12 | pull-requests: write 13 | steps: 14 | - uses: actions/stale@v9 15 | with: 16 | days-before-stale: 60 17 | days-before-close: 7 18 | stale-issue-message: | 19 | This issue is stale because it has been open 60 days with no activity. It will be closed in 7 days if no further activity. 20 | stale-pr-message: | 21 | This PR is stale because it has been open 60 days with no activity. It will be closed in 7 days if no further activity. 22 | -------------------------------------------------------------------------------- /images/base/.devcontainer/direnv.toml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Simon Emms 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Documentation 16 | # @link https://direnv.net/man/direnv.toml.1.html 17 | 18 | [whitelist] 19 | # Automatically apply all .envrc files under /workspaces 20 | prefix = ["/workspaces"] 21 | -------------------------------------------------------------------------------- /images/base/.devcontainer/bash_aliases: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Simon Emms 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Collection of aliases 16 | # 17 | # This is run every time a new terminal window opens, so 18 | # ensure these commands are fast! 19 | 20 | alias k=kubectl 21 | alias kns=kubens 22 | alias ktx=kubectx 23 | -------------------------------------------------------------------------------- /.commitlintrc.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | extends: 19 | - "@commitlint/config-conventional" 20 | -------------------------------------------------------------------------------- /src/tcld/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Temporal Cloud CLI (tcld) (tcld) 3 | 4 | A CLI tool for managing Temporal Cloud namespaces. 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/mrsimonemms/devcontainers/tcld:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | git_repo | Git clone repo to use | string | https://github.com/temporalio/tcld.git | 19 | | target_path | Location to save the tcld binary | string | /usr/local/bin | 20 | | version | Select the version you would like to install | string | latest | 21 | 22 | ## Temporal Cloud CLI 23 | 24 | This feature installs the [Temporal Cloud CLI](https://github.com/temporalio/tcld) 25 | 26 | 27 | --- 28 | 29 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/mrsimonemms/devcontainers/blob/main/src/tcld/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 30 | -------------------------------------------------------------------------------- /src/cobra-cli/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Cobra CLI (cobra-cli) 3 | 4 | Install the Cobra CLI 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/mrsimonemms/devcontainers/cobra-cli:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select the version you would like to install | string | latest | 19 | 20 | ## Cobra CLI 21 | 22 | This Feature includes [the Cobra CLI](https://github.com/spf13/cobra-cli/) 23 | 24 | ## OS Support 25 | 26 | This Feature should work on recent versions of Debian/Ubuntu-based distributions 27 | with the `apt` package manager installed. Golang is also required in the container. 28 | 29 | `bash` is required to execute the `install.sh` script. 30 | 31 | 32 | --- 33 | 34 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/mrsimonemms/devcontainers/blob/main/src/cobra-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 35 | -------------------------------------------------------------------------------- /images/temporal_min/.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "temporal_min", 3 | "image": "ghcr.io/mrsimonemms/devcontainers/base", 4 | "features": { 5 | "ghcr.io/devcontainers-extra/features/poetry:2": {}, 6 | "ghcr.io/devcontainers-extra/features/pre-commit:2": {}, 7 | "ghcr.io/devcontainers-extra/features/pipx-package:1": { 8 | "package": "cruft" 9 | }, 10 | "ghcr.io/devcontainers/features/python:1": {}, 11 | "ghcr.io/devcontainers-extra/features/temporal-cli:1": {} 12 | }, 13 | "containerEnv": { 14 | "PRE_COMMIT_HOME": "/home/vscode/.cache/pre-commit", 15 | "TEMPORAL_ADDRESS": "localhost:7233" 16 | }, 17 | "mounts": [ 18 | "source=${localEnv:HOME}${localEnv:USERPROFILE}/.cache,target=/home/vscode/.cache,type=bind,consistency=cached" 19 | ], 20 | "initializeCommand": { 21 | "init-pre-commit-cache": "mkdir -p ${localEnv:HOME}${localEnv:USERPROFILE}/.cache" 22 | }, 23 | "postCreateCommand": { 24 | "pre-commit": "pre-commit install --install-hooks -t pre-commit -t commit-msg --allow-missing-config || true" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/buf/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "buf", 3 | "version": "1.0.0", 4 | "name": "Buf CLI (via Github Releases)", 5 | "description": "The [Buf CLI](https://buf.build/product/cli) enables building and management of Protobuf APIs - forked from [@marcozac](https://github.com/marcozac/devcontainer-features/tree/main/src/buf).", 6 | "documentationURL": "https://github.com/mrsimonemms/devcontainers/tree/main/src/buf", 7 | "options": { 8 | "version": { 9 | "type": "string", 10 | "proposals": [ 11 | "latest" 12 | ], 13 | "default": "latest", 14 | "description": "Select or enter a Buf version." 15 | }, 16 | "installProtocGenBufBreaking": { 17 | "type": "boolean", 18 | "default": true, 19 | "description": "Install also protoc-gen-buf-breaking" 20 | }, 21 | "installProtocGenBufLint": { 22 | "type": "boolean", 23 | "default": true, 24 | "description": "Install also protoc-gen-buf-lint" 25 | } 26 | }, 27 | "installsAfter": [ 28 | "ghcr.io/devcontainers-extra/features/gh-release" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /images/base/.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "base", 3 | "dockerFile": "Dockerfile", 4 | "features": { 5 | "ghcr.io/devcontainers/features/common-utils:2": { 6 | "installZsh": true, 7 | "configureZshAsDefaultShell": true, 8 | "installOhMyZsh": true, 9 | "installOhMyZshConfig": true, 10 | "upgradePackages": true, 11 | "username": "none" 12 | }, 13 | "ghcr.io/devcontainers/features/docker-in-docker:2": {}, 14 | "ghcr.io/eitsupi/devcontainer-features/jq-likes:2": { 15 | "yqVersion": "4" 16 | } 17 | }, 18 | "customizations": { 19 | "vscode": { 20 | "extensions": [ 21 | "donjayamanne.git-extension-pack", 22 | "EditorConfig.EditorConfig", 23 | "waderyan.gitblame", 24 | "GitHub.vscode-github-actions", 25 | "ms-vscode.makefile-tools", 26 | "ms-vsliveshare.vsliveshare" 27 | ] 28 | } 29 | }, 30 | "shutdownAction": "stopContainer", 31 | "remoteUser": "vscode", 32 | "postCreateCommand": { 33 | "docker-completion": "docker completion bash | sudo tee -a /etc/bash_completion.d/docker > /dev/null" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/tcld/devcontainer-feature.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Temporal Cloud CLI (tcld)", 3 | "id": "tcld", 4 | "version": "1.0.2", 5 | "description": "A CLI tool for managing Temporal Cloud namespaces.", 6 | "options": { 7 | "git_repo": { 8 | "type": "string", 9 | "default": "https://github.com/temporalio/tcld.git", 10 | "description": "Git clone repo to use" 11 | }, 12 | "target_path": { 13 | "type": "string", 14 | "default": "/usr/local/bin", 15 | "description": "Location to save the tcld binary" 16 | }, 17 | "version": { 18 | "type": "string", 19 | "proposals": [ 20 | "latest", 21 | "v0.40.0", 22 | "v0.39.0", 23 | "v0.38.0", 24 | "v0.37.0", 25 | "v0.36.0", 26 | "v0.34.0", 27 | "v0.33.0", 28 | "v0.32.0", 29 | "v0.31.0", 30 | "v0.30.0" 31 | ], 32 | "default": "latest", 33 | "description": "Select the version you would like to install" 34 | } 35 | }, 36 | "dependsOn": { 37 | "ghcr.io/devcontainers/features/go:1": {}, 38 | "ghcr.io/jungaretti/features/make:1": {} 39 | }, 40 | "installsAfter": [ 41 | "ghcr.io/devcontainers/features/common-utils", 42 | "ghcr.io/devcontainers/features/go", 43 | "ghcr.io/jungaretti/features/make" 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /src/buf/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Buf CLI (via Github Releases) (buf) 3 | 4 | The [Buf CLI](https://buf.build/product/cli) enables building and management of Protobuf APIs - forked from [@marcozac](https://github.com/marcozac/devcontainer-features/tree/main/src/buf). 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/mrsimonemms/devcontainers/buf:1": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | version | Select or enter a Buf version. | string | latest | 19 | | installProtocGenBufBreaking | Install also protoc-gen-buf-breaking | boolean | true | 20 | | installProtocGenBufLint | Install also protoc-gen-buf-lint | boolean | true | 21 | 22 | ## Buf 23 | 24 | This is forked from [@marcozac's repo](https://github.com/marcozac/devcontainer-features/tree/main/src/buf) 25 | with a couple of bugfixes: 26 | 27 | * Changed the installation script to use `ghcr.io/devcontainers-extra/features/gh-release` 28 | since `ghcr.io/devcontainers-contrib/features/gh-release` is now removed. 29 | * Fixed [#28](https://github.com/marcozac/devcontainer-features/issues/28) 30 | 31 | 32 | --- 33 | 34 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/mrsimonemms/devcontainers/blob/main/src/buf/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 35 | -------------------------------------------------------------------------------- /images/full/.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "full", 3 | "image": "ghcr.io/mrsimonemms/devcontainers/base", 4 | "features": { 5 | "ghcr.io/devcontainers/features/go:1": {}, 6 | "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {}, 7 | "ghcr.io/devcontainers-extra/features/kubectx-kubens:1": {}, 8 | "ghcr.io/rio/features/k9s:1": {}, 9 | "ghcr.io/devcontainers/features/node:1": {}, 10 | "ghcr.io/devcontainers-extra/features/pre-commit:2": {}, 11 | "ghcr.io/devcontainers-extra/features/pipx-package:1": { 12 | "package": "cruft" 13 | }, 14 | "ghcr.io/devcontainers/features/python:1": {} 15 | }, 16 | "customizations": { 17 | "vscode": { 18 | "extensions": [ 19 | "ms-kubernetes-tools.vscode-kubernetes-tools" 20 | ] 21 | } 22 | }, 23 | "containerEnv": { 24 | "PRE_COMMIT_HOME": "/home/vscode/.cache/pre-commit" 25 | }, 26 | "mounts": [ 27 | "source=${localEnv:HOME}${localEnv:USERPROFILE}/.cache,target=/home/vscode/.cache,type=bind,consistency=cached" 28 | ], 29 | "initializeCommand": { 30 | "init-pre-commit-cache": "mkdir -p ${localEnv:HOME}${localEnv:USERPROFILE}/.cache" 31 | }, 32 | "postCreateCommand": { 33 | "helm-completion": "helm completion bash | sudo tee -a /etc/bash_completion.d/helm > /dev/null", 34 | "pre-commit": "pre-commit install --install-hooks -t pre-commit -t commit-msg --allow-missing-config || true" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/tcld/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2023 Simon Emms 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -e 17 | 18 | GIT_REPO=${GIT_REPO:-"https://github.com/temporalio/tcld.git"} 19 | VERSION=${VERSION:-"latest"} 20 | TARGET_PATH=${TARGET_PATH:-"/usr/local/bin"} 21 | TCLD_DIR=/tmp/tcld 22 | # Prevent pollution of main /go dir as this is run as sudo 23 | GOPATH=/tmp/go 24 | GOCACHE=/tmp/gocache 25 | 26 | rm -rf "${TCLD_DIR}" 27 | 28 | if [ "${VERSION}" = "latest" ]; then 29 | echo "Getting latest tag version" 30 | 31 | API_URL=https://api.github.com/repos/temporalio/tcld/releases/latest 32 | else 33 | echo "Getting tag version for ${VERSION}" 34 | 35 | API_URL="https://api.github.com/repos/temporalio/tcld/releases/tags/${VERSION}" 36 | fi 37 | 38 | TAG=$(curl -sL "${API_URL}" | grep tag_name | cut -d : -f 2,3 | tr -d \", | tr -d '[:space:]') 39 | 40 | echo "Cloning and building tcld" 41 | mkdir -p "${TCLD_DIR}" 42 | cd "${TCLD_DIR}" 43 | git clone "${GIT_REPO}" "${TCLD_DIR}" 44 | git checkout "${TAG}" 45 | # make test breaks on linux/arm64 under QEMU 46 | make clean bins 47 | ./tcld version 48 | mv ./tcld "${TARGET_PATH}" 49 | -------------------------------------------------------------------------------- /.github/workflows/update-documentation.yml: -------------------------------------------------------------------------------- 1 | name: "Update Documentation" 2 | on: 3 | push: 4 | branches: 5 | - main 6 | workflow_dispatch: 7 | permissions: 8 | contents: write 9 | jobs: 10 | generate: 11 | runs-on: ubuntu-latest 12 | environment: documentation 13 | if: ${{ github.ref == 'refs/heads/main' }} 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - name: Generate Documentation 18 | uses: devcontainers/action@v1 19 | with: 20 | generate-docs: "true" 21 | base-path-to-features: "./src" 22 | 23 | - name: Create a PR for Documentation 24 | id: push_image_info 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 27 | run: | 28 | set -e 29 | echo "Start." 30 | 31 | # Configure git and Push updates 32 | git config --global user.email github-actions@github.com 33 | git config --global user.name github-actions 34 | git config pull.rebase false 35 | 36 | branch=automated-documentation-update-$GITHUB_RUN_ID 37 | git checkout -b $branch 38 | message='docs(features): automated documentation update' 39 | 40 | # Add / update and commit 41 | git add */**/README.md 42 | git commit -m "${message}" || export NO_UPDATES=true 43 | 44 | # Push 45 | if [ "$NO_UPDATES" != "true" ] ; then 46 | git push origin "$branch" 47 | gh api \ 48 | --method POST \ 49 | -H "Accept: application/vnd.github+json" \ 50 | /repos/${GITHUB_REPOSITORY}/pulls \ 51 | -f title="$message" \ 52 | -f body="Automated documentation update" \ 53 | -f head="$branch" \ 54 | -f base='main' 55 | fi 56 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Simon Emms 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | DOCKER_REPO ?= ghcr.io/mrsimonemms/devcontainers 16 | IMG_DIR = images 17 | PLATFORM ?= linux/amd64 18 | 19 | all: build-all 20 | 21 | build-all: 22 | @$(MAKE) install-devcontainers 23 | 24 | @$(MAKE) build-base build-images 25 | .PHONY: build-all 26 | 27 | build: 28 | devcontainer build \ 29 | --platform=${PLATFORM} \ 30 | --image-name=${DOCKER_REPO}/${IMG_NAME} \ 31 | --workspace-folder=${CONTEXT} 32 | .PHONY: build 33 | 34 | build-base: 35 | $(MAKE) build IMG_NAME="base" CONTEXT="${IMG_DIR}/base" 36 | .PHONY: build-base 37 | 38 | build-images: 39 | @for img_path in $(shell ls -d ${IMG_DIR}/* | grep -v '/base'); do \ 40 | name=$$(echo $${img_path} | sed "s/${IMG_DIR}\///"); \ 41 | \ 42 | $(MAKE) build IMG_NAME="$${name}" CONTEXT="$${img_path}"; \ 43 | done 44 | .PHONY: build-images 45 | 46 | cruft-update: 47 | ifeq (,$(wildcard .cruft.json)) 48 | @echo "Cruft not configured" 49 | else 50 | @cruft check || cruft update --skip-apply-ask --refresh-private-variables 51 | endif 52 | .PHONY: cruft-update 53 | 54 | install-devcontainers: 55 | @if ! command devcontainer --version; then \ 56 | echo "Installing Dev Containers CLI"; \ 57 | npm i -g @devcontainers/cli; \ 58 | fi 59 | .PHONY: install-devcontainers 60 | -------------------------------------------------------------------------------- /src/cobra-cli/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2023 Simon Emms 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -e 18 | 19 | TARGET_GOPATH="${TARGET_GOPATH:-"/go"}" 20 | USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" 21 | VERSION="${VERSION:-latest}" 22 | 23 | if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then 24 | USERNAME="" 25 | POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") 26 | for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do 27 | if id -u ${CURRENT_USER} > /dev/null 2>&1; then 28 | USERNAME=${CURRENT_USER} 29 | break 30 | fi 31 | done 32 | if [ "${USERNAME}" = "" ]; then 33 | USERNAME=root 34 | fi 35 | elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then 36 | USERNAME=root 37 | fi 38 | 39 | if [ "${VERSION}" != "latest" ]; then 40 | if [ $(echo "${VERSION}" | cut -c1-1) != "v" ]; then 41 | VERSION="v${VERSION}" 42 | fi 43 | fi 44 | 45 | echo "Installing feature 'cobra-cli' - version=${VERSION}" 46 | go install github.com/spf13/cobra-cli@${VERSION} 47 | 48 | chown -R "${USERNAME}:golang" "${TARGET_GOPATH}" 49 | chmod -R g+r+w "${TARGET_GOPATH}" 50 | 51 | cobra-cli completion bash > /etc/bash_completion.d/cobra-cli 52 | 53 | echo "Symlinking $PWD/.cobra.yaml to $HOME/.cobra.yaml" 54 | ln -s $PWD/.cobra.yaml $HOME/.cobra.yaml 55 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | 18 | repos: 19 | - repo: https://github.com/mrsimonemms/pre-commit-hooks 20 | rev: v1.2.1 21 | hooks: 22 | - id: license-eye 23 | - repo: https://github.com/pre-commit/pre-commit-hooks 24 | rev: v5.0.0 25 | hooks: 26 | - id: pretty-format-json 27 | args: 28 | - --autofix 29 | - --no-sort-keys 30 | - id: check-json 31 | - id: check-yaml 32 | args: 33 | - --allow-multiple-documents 34 | - id: end-of-file-fixer 35 | - id: trailing-whitespace 36 | - repo: https://github.com/compilerla/conventional-pre-commit 37 | rev: v4.2.0 38 | hooks: 39 | - id: conventional-pre-commit 40 | stages: 41 | - commit-msg 42 | - repo: https://github.com/trussworks/pre-commit-hooks 43 | rev: v2.0.0 44 | hooks: 45 | - id: markdown-toc 46 | exclude: ^src 47 | - repo: https://github.com/DavidAnson/markdownlint-cli2 48 | rev: v0.18.1 49 | hooks: 50 | - id: markdownlint-cli2 51 | exclude: ^src 52 | - repo: https://github.com/mrsimonemms/toodaloo 53 | rev: v0.2.4 54 | hooks: 55 | - id: scan 56 | -------------------------------------------------------------------------------- /src/buf/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -i 2 | # Copyright 2023 Simon Emms 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -e 18 | 19 | INSTALL_PROTOC_GEN_BUF_BREAKING="${INSTALLPROTOCGENBUFBREAKING:-"true"}" 20 | INSTALL_PROTOC_GEN_BUF_LINT="${INSTALLPROTOCGENBUFLINT:-"true"}" 21 | 22 | binary_names="buf" 23 | if [[ "$INSTALL_PROTOC_GEN_BUF_BREAKING" == "true" ]]; then 24 | binary_names="$binary_names,protoc-gen-buf-breaking" 25 | fi 26 | if [[ "$INSTALL_PROTOC_GEN_BUF_LINT" == "true" ]]; then 27 | binary_names="$binary_names,protoc-gen-buf-lint" 28 | fi 29 | 30 | source ./library_scripts.sh 31 | 32 | # nanolayer is a cli utility which keeps container layers as small as possible 33 | # source code: https://github.com/devcontainers-contrib/nanolayer 34 | # `ensure_nanolayer` is a bash function that will find any existing nanolayer installations, 35 | # and if missing - will download a temporary copy that automatically get deleted at the end 36 | # of the script 37 | ensure_nanolayer nanolayer_location "v0.4.45" 38 | 39 | $nanolayer_location \ 40 | install \ 41 | devcontainer-feature \ 42 | "ghcr.io/devcontainers-extra/features/gh-release:1.0.26" \ 43 | --option repo='bufbuild/buf' \ 44 | --option binaryNames="$binary_names" \ 45 | --option version="$VERSION" \ 46 | --option assetRegex='.*\.tar\.gz' \ 47 | --option libName='buf' 48 | 49 | rm /usr/local/bin/buf 50 | 51 | ln -s /usr/local/lib/buf/buf/bin/buf /usr/local/bin/buf 52 | 53 | echo 'Done!' 54 | -------------------------------------------------------------------------------- /images/base/.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Simon Emms 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # @link https://github.com/devcontainers/images/tree/main/src/base-ubuntu 16 | FROM mcr.microsoft.com/devcontainers/base:ubuntu 17 | 18 | USER root 19 | 20 | # Base 21 | RUN apt-get update \ 22 | && apt-get -y install \ 23 | bash-completion \ 24 | build-essential \ 25 | ca-certificates \ 26 | direnv \ 27 | emacs-nox \ 28 | fish \ 29 | git \ 30 | git-core \ 31 | git-lfs \ 32 | htop \ 33 | iputils-ping \ 34 | less \ 35 | locales \ 36 | lsof \ 37 | man-db \ 38 | multitail \ 39 | nano \ 40 | ninja-build \ 41 | ripgrep \ 42 | software-properties-common \ 43 | ssl-cert \ 44 | stow \ 45 | sudo \ 46 | time \ 47 | unzip \ 48 | vim \ 49 | zip \ 50 | zsh \ 51 | && locale-gen en_GB.UTF-8 52 | 53 | ENV LANG=en_GB.UTF-8 54 | 55 | # Update packages 56 | RUN apt-get -y autoremove \ 57 | && apt-get -y autoclean \ 58 | && apt-get -y clean 59 | RUN rm -rf \ 60 | /var/cache/debconf/* \ 61 | /var/lib/apt/lists/* \ 62 | /tmp/* \ 63 | /var/tmp/* 64 | 65 | # Configure git-lfs 66 | RUN git lfs install --system --skip-repo 67 | 68 | # Install diff-so-fancy 69 | # @link https://github.com/so-fancy/diff-so-fancy 70 | RUN add-apt-repository ppa:aos1/diff-so-fancy \ 71 | && apt-get update \ 72 | && apt-get install -y diff-so-fancy 73 | 74 | USER vscode 75 | WORKDIR /home/vscode 76 | 77 | # Configure direnv 78 | # @link https://direnv.net/docs/hook.html 79 | RUN touch $HOME/.bashrc $HOME/.zshrc \ 80 | && echo 'eval "$(direnv hook bash)"' >> $HOME/.bashrc \ 81 | && echo 'eval "$(direnv hook zsh)"' >> $HOME/.zshrc 82 | 83 | RUN { echo && echo "PS1='\[\033[01;32m\]\u\[\033[00m\] \[\033[01;34m\]\w\[\033[00m\]\$(__git_ps1 \" (%s)\") $ '" ; } >> $HOME/.bashrc 84 | 85 | COPY --chown=vscode:vscode bash_aliases .bash_aliases 86 | COPY --chown=vscode:vscode gitconfig .config/git/config 87 | COPY --chown=vscode:vscode direnv.toml .config/direnv/direnv.toml 88 | 89 | # Custom PATH additions 90 | ENV PATH=$HOME/.local/bin:$PATH 91 | 92 | WORKDIR /workspaces 93 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dev Containers 2 | 3 | Pre-build [Development Containers](https://containers.dev/) 4 | 5 | 6 | 7 | * [Purpose](#purpose) 8 | * [Features](#features) 9 | * [Images](#images) 10 | * [Base](#base) 11 | * [Full](#full) 12 | * [Temporal Min](#temporal-min) 13 | * [Temporal Full](#temporal-full) 14 | * [Usage](#usage) 15 | * [Contributing](#contributing) 16 | * [Open in a container](#open-in-a-container) 17 | * [Commit style](#commit-style) 18 | 19 | 20 | 21 | 22 | 23 | ## Purpose 24 | 25 | This is a series of pre-built Devcontainer image to allow local development. 26 | 27 | ## Features 28 | 29 | * [Buf](./src/buf) 30 | * [Cobra CLI](./src/cobra-cli) 31 | * [Temporal Cloud CLI](./src/tcld) 32 | 33 | ## Images 34 | 35 | There are a number of images that exist. 36 | 37 | ### Base 38 | 39 | > `ghcr.io/mrsimonemms/devcontainers/base` 40 | 41 | This provides a base image to use for all your development environment need. 42 | This is an Ubuntu image with sensible defaults, including 43 | [the best-looking Git diffs](https://github.com/so-fancy/diff-so-fancy), 44 | Docker support, tab-completion and useful Git aliases. 45 | 46 | ### Full 47 | 48 | > `ghcr.io/mrsimonemms/devcontainers/full` 49 | 50 | An image with some modern tooling installed. 51 | 52 | * [Go](https://github.com/devcontainers/features/tree/main/src/go) ✅ 53 | * [Kubernetes, Helm and Minikube](https://github.com/devcontainers/features/tree/main/src/kubectl-helm-minikube) 54 | ✅ 55 | * [Kubectx](https://github.com/devcontainers-extra/features/tree/main/src/kubectx-kubens) 56 | ✅ 57 | * [K9s](https://github.com/rio/features/tree/main/src/k9s) ✅ 58 | * [Node.js](https://github.com/devcontainers/features/tree/main/src/node) ✅ 59 | * [Pre-Commit](https://github.com/devcontainers-extra/features/tree/main/src/pre-commit) 60 | ✅ 61 | * [Python](https://github.com/devcontainers/features/tree/main/src/python) ✅ 62 | 63 | The advantage of using this image is that the features are pre-built which shifts 64 | the build effort into GitHub Actions rather than on your local machine. 65 | 66 | This can be easily extended with additional features by adding them to your 67 | `.devcontainer/devcontainer.json` file. 68 | 69 | This is built to both `linux/amd64` and `linux/arm64` to cover use with both a 70 | "standard" 64 bit machine and a modern Mac. 71 | 72 | Both [Homebrew](https://github.com/meaningful-ooo/devcontainer-features/tree/main/src/homebrew) 73 | and [Nix](https://github.com/devcontainers/features/tree/main/src/nix) were in 74 | the original builds, but I found that I rarely (if ever) used them in my devcontainers 75 | so removed them. This reduced the image size by around 2.5GB. These are also not 76 | supported by the `linux/arm64` platform. 77 | 78 | ### Temporal Min 79 | 80 | > `ghcr.io/mrsimonemms/devcontainers/temporal_min` 81 | 82 | An image designed to make working with [Temporal](https://temporal.io/) easier 83 | with the minimum Temporal dependencies installed. This image should be used for 84 | all Temporal work and adding the required [features](https://containers.dev/features) 85 | in your `.devcontainer/devcontainer.json`. 86 | 87 | * [Pre-Commit](https://github.com/devcontainers-extra/features/tree/main/src/pre-commit) 88 | ✅ 89 | * [Poetry](https://github.com/devcontainers-extra/features/tree/main/src/poetry) 90 | ✅ 91 | * [Python](https://github.com/devcontainers/features/tree/main/src/python) ✅ 92 | * [Temporal CLI](https://github.com/devcontainers-extra/features/tree/main/src/temporal-cli) 93 | ✅ 94 | 95 | ### Temporal Full 96 | 97 | > `ghcr.io/mrsimonemms/devcontainers/temporal_full` 98 | 99 | An image designed to make working with [Temporal](https://temporal.io/) easier, 100 | with native support for all official SDKs. 101 | 102 | * [Dotnet](https://github.com/devcontainers/features/tree/main/src/dotnet) 103 | * [Go](https://github.com/devcontainers/features/tree/main/src/go) ✅ 104 | * [Java](https://github.com/devcontainers/features/tree/main/src/java) ✅ 105 | * [Node.js](https://github.com/devcontainers/features/tree/main/src/node) ✅ 106 | * [PHP](https://github.com/devcontainers/features/tree/main/src/php) ✅ 107 | * [Pre-Commit](https://github.com/devcontainers-extra/features/tree/main/src/pre-commit) 108 | ✅ 109 | * [Poetry](https://github.com/devcontainers-extra/features/tree/main/src/poetry) 110 | ✅ 111 | * [Python](https://github.com/devcontainers/features/tree/main/src/python) ✅ 112 | * [Ruby](https://github.com/devcontainers/features/tree/main/src/ruby) ✅ 113 | * [Temporal CLI](https://github.com/devcontainers-extra/features/tree/main/src/temporal-cli) 114 | ✅ 115 | 116 | This image is quite large. Unless full support for everything is required, 117 | use the [Temporal Min](#temporal-min) image and adding the required [features](https://containers.dev/features) 118 | in your `.devcontainer/devcontainer.json`. 119 | 120 | ## Usage 121 | 122 | These images can be used in any way that Dev Containers supports. Typically, 123 | this would be by specifying the `image` in your `devcontainer.json` file: 124 | 125 | ```json 126 | { 127 | "name": "devcontainer", 128 | "image": "ghcr.io/mrsimonemms/devcontainers/full" 129 | } 130 | ``` 131 | 132 | As this image is pre-built, it will vastly speed up your workflow. 133 | 134 | ## Contributing 135 | 136 | ### Open in a container 137 | 138 | * [Open in a container](https://code.visualstudio.com/docs/devcontainers/containers) 139 | 140 | ### Commit style 141 | 142 | All commits must be done in the [Conventional Commit](https://www.conventionalcommits.org) 143 | format. 144 | 145 | ```git 146 | [optional scope]: 147 | 148 | [optional body] 149 | 150 | [optional footer(s)] 151 | ``` 152 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | [simon@simonemms.com]. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | . 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | . Translations are available at 128 | . 129 | -------------------------------------------------------------------------------- /src/buf/library_scripts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -i 2 | # Copyright 2023 Simon Emms 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | clean_download() { 17 | # The purpose of this function is to download a file with minimal impact on container layer size 18 | # this means if no valid downloader is found (curl or wget) then we install a downloader (currently wget) in a 19 | # temporary manner, and making sure to 20 | # 1. uninstall the downloader at the return of the function 21 | # 2. revert back any changes to the package installer database/cache (for example apt-get lists) 22 | # The above steps will minimize the leftovers being created while installing the downloader 23 | # Supported distros: 24 | # debian/ubuntu/alpine 25 | 26 | url=$1 27 | output_location=$2 28 | tempdir=$(mktemp -d) 29 | downloader_installed="" 30 | 31 | function _apt_get_install() { 32 | tempdir=$1 33 | 34 | # copy current state of apt list - in order to revert back later (minimize contianer layer size) 35 | cp -p -R /var/lib/apt/lists $tempdir 36 | apt-get update -y 37 | apt-get -y install --no-install-recommends wget ca-certificates 38 | } 39 | 40 | function _apt_get_cleanup() { 41 | tempdir=$1 42 | 43 | echo "removing wget" 44 | apt-get -y purge wget --auto-remove 45 | 46 | echo "revert back apt lists" 47 | rm -rf /var/lib/apt/lists/* 48 | rm -r /var/lib/apt/lists && mv $tempdir/lists /var/lib/apt/lists 49 | } 50 | 51 | function _apk_install() { 52 | tempdir=$1 53 | # copy current state of apk cache - in order to revert back later (minimize contianer layer size) 54 | cp -p -R /var/cache/apk $tempdir 55 | 56 | apk add --no-cache wget 57 | } 58 | 59 | function _apk_cleanup() { 60 | tempdir=$1 61 | 62 | echo "removing wget" 63 | apk del wget 64 | } 65 | # try to use either wget or curl if one of them already installer 66 | if type curl >/dev/null 2>&1; then 67 | downloader=curl 68 | elif type wget >/dev/null 2>&1; then 69 | downloader=wget 70 | else 71 | downloader="" 72 | fi 73 | 74 | # in case none of them is installed, install wget temporarly 75 | if [ -z $downloader ] ; then 76 | if [ -x "/usr/bin/apt-get" ] ; then 77 | _apt_get_install $tempdir 78 | elif [ -x "/sbin/apk" ] ; then 79 | _apk_install $tempdir 80 | else 81 | echo "distro not supported" 82 | exit 1 83 | fi 84 | downloader="wget" 85 | downloader_installed="true" 86 | fi 87 | 88 | if [ $downloader = "wget" ] ; then 89 | wget -q $url -O $output_location 90 | else 91 | curl -sfL $url -o $output_location 92 | fi 93 | 94 | # NOTE: the cleanup procedure was not implemented using `trap X RETURN` only because 95 | # alpine lack bash, and RETURN is not a valid signal under sh shell 96 | if ! [ -z $downloader_installed ] ; then 97 | if [ -x "/usr/bin/apt-get" ] ; then 98 | _apt_get_cleanup $tempdir 99 | elif [ -x "/sbin/apk" ] ; then 100 | _apk_cleanup $tempdir 101 | else 102 | echo "distro not supported" 103 | exit 1 104 | fi 105 | fi 106 | 107 | } 108 | 109 | 110 | ensure_nanolayer() { 111 | # Ensure existance of the nanolayer cli program 112 | local variable_name=$1 113 | 114 | local required_version=$2 115 | # normalize version 116 | if ! [[ $required_version == v* ]]; then 117 | required_version=v$required_version 118 | fi 119 | 120 | local nanolayer_location="" 121 | 122 | # If possible - try to use an already installed nanolayer 123 | if [[ -z "${NANOLAYER_FORCE_CLI_INSTALLATION}" ]]; then 124 | if [[ -z "${NANOLAYER_CLI_LOCATION}" ]]; then 125 | if type nanolayer >/dev/null 2>&1; then 126 | echo "Found a pre-existing nanolayer in PATH" 127 | nanolayer_location=nanolayer 128 | fi 129 | elif [ -f "${NANOLAYER_CLI_LOCATION}" ] && [ -x "${NANOLAYER_CLI_LOCATION}" ] ; then 130 | nanolayer_location=${NANOLAYER_CLI_LOCATION} 131 | echo "Found a pre-existing nanolayer which were given in env variable: $nanolayer_location" 132 | fi 133 | 134 | # make sure its of the required version 135 | if ! [[ -z "${nanolayer_location}" ]]; then 136 | local current_version 137 | current_version=$($nanolayer_location --version) 138 | if ! [[ $current_version == v* ]]; then 139 | current_version=v$current_version 140 | fi 141 | 142 | if ! [ $current_version == $required_version ]; then 143 | echo "skipping usage of pre-existing nanolayer. (required version $required_version does not match existing version $current_version)" 144 | nanolayer_location="" 145 | fi 146 | fi 147 | 148 | fi 149 | 150 | # If not previuse installation found, download it temporarly and delete at the end of the script 151 | if [[ -z "${nanolayer_location}" ]]; then 152 | 153 | if [ "$(uname -sm)" == "Linux x86_64" ] || [ "$(uname -sm)" == "Linux aarch64" ]; then 154 | tmp_dir=$(mktemp -d -t nanolayer-XXXXXXXXXX) 155 | 156 | clean_up () { 157 | ARG=$? 158 | rm -rf $tmp_dir 159 | exit $ARG 160 | } 161 | trap clean_up EXIT 162 | 163 | 164 | if [ -x "/sbin/apk" ] ; then 165 | clib_type=musl 166 | else 167 | clib_type=gnu 168 | fi 169 | 170 | tar_filename=nanolayer-"$(uname -m)"-unknown-linux-$clib_type.tgz 171 | 172 | # clean download will minimize leftover in case a downloaderlike wget or curl need to be installed 173 | clean_download https://github.com/devcontainers-contrib/cli/releases/download/$required_version/$tar_filename $tmp_dir/$tar_filename 174 | 175 | tar xfzv $tmp_dir/$tar_filename -C "$tmp_dir" 176 | chmod a+x $tmp_dir/nanolayer 177 | nanolayer_location=$tmp_dir/nanolayer 178 | 179 | 180 | else 181 | echo "No binaries compiled for non-x86-linux architectures yet: $(uname -m)" 182 | exit 1 183 | fi 184 | fi 185 | 186 | # Expose outside the resolved location 187 | declare -g ${variable_name}=$nanolayer_location 188 | 189 | } 190 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - main 6 | tags: 7 | - "v*.*.*" 8 | pull_request: 9 | branches: 10 | - main 11 | schedule: 12 | - cron: 0 1 * * 1 13 | workflow_dispatch: 14 | permissions: 15 | contents: write 16 | packages: write 17 | pull-requests: read 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | jobs: 21 | commitlint: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 # fetch-depth is required 27 | 28 | - uses: wagoid/commitlint-github-action@v5 29 | 30 | pre-commit: 31 | runs-on: ubuntu-latest 32 | steps: 33 | - uses: actions/checkout@v4 34 | with: 35 | fetch-depth: 0 # fetch-depth is required 36 | 37 | - name: Set up Go without go.mod 38 | uses: actions/setup-go@v5 39 | if: ${{ hashFiles('go.mod') == '' }} 40 | with: 41 | check-latest: true 42 | 43 | - name: Set up Go with go.mod 44 | uses: actions/setup-go@v5 45 | if: ${{ hashFiles('go.mod') != '' }} 46 | with: 47 | go-version-file: go.mod 48 | 49 | - uses: actions/setup-python@v5 50 | with: 51 | python-version: 3.x 52 | 53 | - name: Setup JS 54 | uses: actions/setup-node@v4 55 | with: 56 | node-version: lts/* 57 | 58 | - name: Install dependencies 59 | run: | 60 | go install ./... || true 61 | npm ci || true 62 | 63 | - uses: pre-commit/action@v3.0.1 64 | 65 | list_images: 66 | runs-on: ubuntu-latest 67 | outputs: 68 | list: ${{ steps.tags.outputs.list }} 69 | steps: 70 | - uses: actions/checkout@v4 71 | 72 | - name: Generate Docker tag 73 | id: tags 74 | run: | 75 | echo "list={\"img\": $(jq -ncR '[inputs]' <<< $(ls -d images/* | grep -v '/base'))}" >> "$GITHUB_OUTPUT" 76 | 77 | list_runners: 78 | runs-on: ubuntu-latest 79 | outputs: 80 | list: ${{ steps.runners.outputs.list }} 81 | steps: 82 | - id: runners 83 | run: |- 84 | if [ ${{ github.ref == 'refs/heads/main' }} = "true" ]; then 85 | echo "list={\"runner\":[{\"image\": \"ubuntu-latest\", \"platform\": \"linux/amd64\" }, { \"image\": \"ubuntu-24.04-arm\", \"platform\": \"linux/arm64\" }]}" >> "$GITHUB_OUTPUT" 86 | else 87 | echo "list={\"runner\":[{\"image\": \"ubuntu-latest\", \"platform\": \"linux/amd64\" }]}" >> "$GITHUB_OUTPUT" 88 | fi 89 | 90 | base: 91 | runs-on: ${{ matrix.runner.image }} 92 | needs: 93 | - commitlint 94 | - list_runners 95 | - pre-commit 96 | outputs: 97 | docker_registry: ${{ steps.tags.outputs.docker_registry }} 98 | tag: ${{ steps.tags.outputs.tag }} 99 | strategy: 100 | fail-fast: true 101 | matrix: ${{ fromJSON(needs.list_runners.outputs.list) }} 102 | steps: 103 | - uses: actions/checkout@v4 104 | 105 | - name: Setup JS 106 | uses: actions/setup-node@v4 107 | with: 108 | node-version: lts/* 109 | 110 | - name: Set up Docker Buildx 111 | uses: docker/setup-buildx-action@v3 112 | 113 | - name: Login to GitHub Container Registry 114 | uses: docker/login-action@v3 115 | with: 116 | registry: ghcr.io 117 | username: ${{ github.actor }} 118 | password: ${{ secrets.GITHUB_TOKEN }} 119 | 120 | - name: Generate Docker tag 121 | id: tags 122 | run: | 123 | echo "docker_registry=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" 124 | echo "tag=$(date --iso-8601)" >> "$GITHUB_OUTPUT" 125 | 126 | - name: Install Dev Container CLI 127 | run: | 128 | npm install -g @devcontainers/cli 129 | devcontainer --version 130 | 131 | - name: Build Dev Container 132 | run: | 133 | ADDITIONAL_BUILD_COMMANDS="" 134 | if [ ${{ github.ref == 'refs/heads/main' }} = "true" ]; then 135 | ADDITIONAL_BUILD_COMMANDS="--push" 136 | fi 137 | 138 | devcontainer build \ 139 | ${ADDITIONAL_BUILD_COMMANDS} \ 140 | --platform=${{ matrix.runners.platform }} \ 141 | --image-name=${{ steps.tags.outputs.docker_registry }}/base:${{ github.sha }}-${{ matrix.runner.image }} \ 142 | --workspace-folder=images/base 143 | 144 | if [ ${{ github.ref == 'refs/heads/main' }} = "false" ]; then 145 | echo "Saving base image" 146 | docker save ${{ steps.tags.outputs.docker_registry }}/base:${{ github.sha }}-${{ matrix.runner.image }} -o base.tar.gz 147 | fi 148 | 149 | - name: Archive Docker image 150 | uses: actions/upload-artifact@v4 151 | if: ${{ github.ref != 'refs/heads/main' }} 152 | with: 153 | name: docker-image-${{ matrix.runner.image }} 154 | path: base.tar.gz 155 | if-no-files-found: error 156 | retention-days: 1 157 | compression-level: 0 158 | overwrite: true 159 | 160 | base_manifest: 161 | runs-on: ubuntu-latest 162 | needs: 163 | - base 164 | - list_runners 165 | - list_images 166 | outputs: 167 | matrix: ${{ steps.matrix.outputs.matrix }} 168 | steps: 169 | - name: Generate image matrix 170 | id: matrix 171 | run: | 172 | echo ${{ toJson(needs.list_runners.outputs.list) }} | jq -rc > runners.json 173 | echo ${{ toJson(needs.list_images.outputs.list) }} | jq -rc > images.json 174 | 175 | echo "matrix=$(jq -c -s 'map(to_entries) | flatten | group_by(.key) | map({key: .[0].key, value: map(.value) | add}) | from_entries' <<< "$(cat runners.json)$(cat images.json)")" >> "$GITHUB_OUTPUT" 176 | 177 | inputs="" 178 | for row in $(cat runners.json | jq -rc '.runner[] | @base64'); do 179 | inputs="${inputs},${{ needs.base.outputs.docker_registry }}/base:${{ github.sha }}-$(echo "${row}" | base64 -d | jq -r '.image')" 180 | done 181 | 182 | echo "inputs=${inputs}" >> "$GITHUB_OUTPUT" 183 | 184 | - name: Set up Docker Buildx 185 | uses: docker/setup-buildx-action@v3 186 | 187 | - name: Login to GitHub Container Registry 188 | uses: docker/login-action@v3 189 | with: 190 | registry: ghcr.io 191 | username: ${{ github.actor }} 192 | password: ${{ secrets.GITHUB_TOKEN }} 193 | 194 | - uses: Noelware/docker-manifest-action@v1 195 | if: ${{ github.ref == 'refs/heads/main' }} 196 | with: 197 | inputs: ${{ steps.matrix.outputs.inputs }} 198 | tags: ${{ needs.base.outputs.docker_registry }}/base:${{ needs.base.outputs.tag }},${{ needs.base.outputs.docker_registry }}/base:latest 199 | push: true 200 | annotations: index:org.opencontainers.image.source=https://github.com/${{ github.repository }} 201 | 202 | images: 203 | runs-on: ${{ matrix.runner.image }} 204 | needs: 205 | - base 206 | - base_manifest 207 | strategy: 208 | fail-fast: true 209 | matrix: ${{ fromJSON(needs.base_manifest.outputs.matrix) }} 210 | steps: 211 | - uses: actions/checkout@v4 212 | 213 | - name: Setup JS 214 | uses: actions/setup-node@v4 215 | with: 216 | node-version: lts/* 217 | 218 | - name: Set up Docker Buildx 219 | uses: docker/setup-buildx-action@v3 220 | 221 | - name: Login to GitHub Container Registry 222 | uses: docker/login-action@v3 223 | with: 224 | registry: ghcr.io 225 | username: ${{ github.actor }} 226 | password: ${{ secrets.GITHUB_TOKEN }} 227 | 228 | - name: Generate Docker tag 229 | id: tags 230 | run: | 231 | echo "name=$(echo ${{ matrix.img }} | sed 's/images\///' )" >> "$GITHUB_OUTPUT" 232 | 233 | - name: Install Dev Container CLI 234 | run: | 235 | npm install -g @devcontainers/cli 236 | devcontainer --version 237 | 238 | - name: Import Docker image 239 | uses: actions/download-artifact@v4 240 | if: ${{ github.ref != 'refs/heads/main' }} 241 | with: 242 | name: docker-image-${{ matrix.runner.image }} 243 | 244 | - name: Build Dev Container 245 | run: | 246 | ADDITIONAL_BUILD_COMMANDS="" 247 | if [ ${{ github.ref == 'refs/heads/main' }} = "true" ]; then 248 | ADDITIONAL_BUILD_COMMANDS="--push" 249 | else 250 | echo "Importing image from cache" 251 | docker import base.tar.gz ${{ needs.base.outputs.docker_registry }}/base 252 | fi 253 | 254 | devcontainer build \ 255 | ${ADDITIONAL_BUILD_COMMANDS} \ 256 | --platform=${{ matrix.runners.platform }} \ 257 | --image-name=${{ needs.base.outputs.docker_registry }}/${{ steps.tags.outputs.name }}:${{ github.sha }}-${{ matrix.runner.image }} \ 258 | --workspace-folder=${{ matrix.img }} 259 | 260 | images_manifest: 261 | runs-on: ubuntu-latest 262 | needs: 263 | - base 264 | - list_images 265 | - list_runners 266 | - images 267 | strategy: 268 | fail-fast: true 269 | matrix: ${{ fromJSON(needs.list_images.outputs.list) }} 270 | steps: 271 | - name: Generate Docker tag 272 | id: tags 273 | run: | 274 | img_name=$(echo ${{ matrix.img }} | sed 's/images\///') 275 | echo "name=${img_name}" >> "$GITHUB_OUTPUT" 276 | 277 | echo ${{ toJson(needs.list_runners.outputs.list) }} | jq -rc > runners.json 278 | 279 | inputs="" 280 | for row in $(cat runners.json | jq -rc '.runner[] | @base64'); do 281 | inputs="${inputs},${{ needs.base.outputs.docker_registry }}/${img_name}:${{ github.sha }}-$(echo "${row}" | base64 -d | jq -r '.image')" 282 | done 283 | 284 | echo "inputs=${inputs}" >> "$GITHUB_OUTPUT" 285 | echo "name=${img_name}" >> "$GITHUB_OUTPUT" 286 | 287 | - name: Set up Docker Buildx 288 | uses: docker/setup-buildx-action@v3 289 | 290 | - name: Login to GitHub Container Registry 291 | uses: docker/login-action@v3 292 | with: 293 | registry: ghcr.io 294 | username: ${{ github.actor }} 295 | password: ${{ secrets.GITHUB_TOKEN }} 296 | 297 | - uses: Noelware/docker-manifest-action@v1 298 | if: ${{ github.ref == 'refs/heads/main' }} 299 | with: 300 | inputs: ${{ steps.tags.outputs.inputs }} 301 | tags: ${{ needs.base.outputs.docker_registry }}/${{ steps.tags.outputs.name }}:${{ needs.base.outputs.tag }},${{ needs.base.outputs.docker_registry }}/${{ steps.tags.outputs.name }}:latest 302 | push: true 303 | annotations: index:org.opencontainers.image.source=https://github.com/${{ github.repository }} 304 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------