Repository: honeycombio/buildevents Branch: main Commit: f16589bedb8c Files: 53 Total size: 163.3 KB Directory structure: gitextract_5ccj5tfq/ ├── .circleci/ │ └── config.yml ├── .github/ │ ├── CODEOWNERS │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ ├── feature_request.md │ │ ├── question-discussion.md │ │ └── security-vulnerability-report.md │ ├── PULL_REQUEST_TEMPLATE.md │ ├── dependabot.yml │ ├── release.yml │ └── workflows/ │ ├── add-to-project-v2.yml │ ├── apply-labels.yml │ ├── stale.yml │ └── validate-pr-title.yml ├── .gitignore ├── .go-version ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── LICENSES/ │ ├── github.com/ │ │ ├── facebookgo/ │ │ │ ├── clock/ │ │ │ │ └── LICENSE │ │ │ ├── limitgroup/ │ │ │ │ └── license │ │ │ └── muster/ │ │ │ └── license │ │ ├── honeycombio/ │ │ │ ├── beeline-go/ │ │ │ │ └── propagation/ │ │ │ │ ├── LICENSE │ │ │ │ └── NOTICE │ │ │ └── libhoney-go/ │ │ │ ├── LICENSE │ │ │ └── NOTICE │ │ ├── jszwedko/ │ │ │ └── go-circleci/ │ │ │ └── LICENSE │ │ ├── klauspost/ │ │ │ └── compress/ │ │ │ ├── LICENSE │ │ │ ├── internal/ │ │ │ │ └── snapref/ │ │ │ │ └── LICENSE │ │ │ └── zstd/ │ │ │ └── internal/ │ │ │ └── xxhash/ │ │ │ └── LICENSE.txt │ │ ├── kr/ │ │ │ └── logfmt/ │ │ │ └── Readme │ │ ├── spf13/ │ │ │ ├── cobra/ │ │ │ │ └── LICENSE.txt │ │ │ └── pflag/ │ │ │ └── LICENSE │ │ └── vmihailenco/ │ │ ├── msgpack/ │ │ │ └── v5/ │ │ │ └── LICENSE │ │ └── tagparser/ │ │ └── v2/ │ │ └── LICENSE │ └── gopkg.in/ │ └── alexcesaro/ │ └── statsd.v2/ │ └── LICENSE ├── Makefile ├── NOTICE ├── OSSMETADATA ├── README.md ├── RELEASING.md ├── SECURITY.md ├── SUPPORT.md ├── cmd_build.go ├── cmd_cmd.go ├── cmd_root.go ├── cmd_step.go ├── cmd_watch.go ├── common.go ├── common_test.go ├── go.mod ├── go.sum └── main.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .circleci/config.yml ================================================ version: 2.1 executors: linuxgo: docker: - image: cimg/go:1.23 commands: go-build: parameters: os: description: Target operating system type: enum enum: ["linux", "darwin", "windows"] default: "linux" arch: description: Target architecture type: enum enum: ["386", "amd64", "arm64"] default: "amd64" suffix: description: Optional suffix type: string default: "" steps: - run: | GOOS=<< parameters.os >> \ GOARCH=<< parameters.arch >> \ CGO_ENABLED=0 \ go build -ldflags "-X main.Version=${CIRCLE_TAG}" \ -o $GOPATH/bin/buildevents-<< parameters.os >>-<< parameters.arch >><< parameters.suffix >> \ ./... jobs: test: executor: linuxgo steps: - checkout - run: name: go_test command: go test -v ./... - run: make verify-licenses build: executor: linuxgo steps: - checkout - go-build: os: linux arch: "386" - go-build: os: linux arch: amd64 - go-build: os: darwin arch: amd64 - go-build: os: darwin arch: arm64 - go-build: os: linux arch: arm64 - go-build: os: windows arch: "386" suffix: ".exe" - go-build: os: windows arch: amd64 suffix: ".exe" - go-build: os: windows arch: arm64 suffix: ".exe" - run: mkdir -v artifacts; cp -v $GOPATH/bin/buildevents-* artifacts/ - run: tar -cvf artifacts/buildevents.tar artifacts/buildevents-* - persist_to_workspace: root: artifacts paths: - buildevents.tar - store_artifacts: path: artifacts/ smoketest: executor: linuxgo steps: - attach_workspace: at: artifacts - run: tar -xvf artifacts/buildevents.tar - run: name: "Subcommand success = success" command: | result=$(artifacts/buildevents-linux-amd64 cmd buildId stepId name -- true >/dev/null && echo "worked") if [ "$result" != "worked" ]; then exit 1 fi - run: name: "Subcommand failure = failure" command: | result=$(artifacts/buildevents-linux-amd64 cmd buildId stepId name -- false > /dev/null || echo "worked" ) if [ "$result" != "worked" ]; then exit 1 fi publish: docker: - image: cibuilds/github:0.13.0 steps: - attach_workspace: at: artifacts - run: name: "Publish Release on GitHub" command: | echo "about to publish to tag ${CIRCLE_TAG}" tar -xvf artifacts/buildevents.tar rm -rf artifacts/buildevents.tar ls -l ./artifacts ghr -draft -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} ${CIRCLE_TAG} ./artifacts workflows: build: jobs: - test: filters: tags: only: /.*/ - build: requires: - test filters: tags: only: /.*/ - smoketest: requires: - build filters: tags: only: /.*/ - publish: context: Honeycomb Secrets for Public Repos requires: - smoketest filters: tags: only: /^v.*/ branches: ignore: /.*/ ================================================ FILE: .github/CODEOWNERS ================================================ # Code owners file. # This file controls who is tagged for review for any given pull request. # For anything not explicitly taken by someone else: * @honeycombio/pipeline-team ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Let us know if something is not working as expected title: '' labels: 'type: bug' assignees: '' --- **Versions** - Go: - Buildevents: **Steps to reproduce** 1. **Additional context** ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: 'type: enhancement' assignees: '' --- **Is your feature request related to a problem? Please describe.** **Describe the solution you'd like** **Describe alternatives you've considered** **Additional context** ================================================ FILE: .github/ISSUE_TEMPLATE/question-discussion.md ================================================ --- name: Question/Discussion about: General question about how things work or a discussion title: '' labels: 'type: discussion' assignees: '' --- ================================================ FILE: .github/ISSUE_TEMPLATE/security-vulnerability-report.md ================================================ --- name: Security vulnerability report about: Let us know if you discover a security vulnerability title: '' labels: 'type: security' assignees: '' --- **Versions** - Go: - Buildevents: **Description** (Please include any relevant CVE advisory links) ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## Which problem is this PR solving? - Closes # ## Short description of the changes ## How to verify that this has the expected result ================================================ FILE: .github/dependabot.yml ================================================ # To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "gomod" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "monthly" labels: - "type: dependencies" commit-message: prefix: "maint" include: "scope" groups: examples: patterns: - "*" ================================================ FILE: .github/release.yml ================================================ # .github/release.yml changelog: exclude: labels: - no-changelog categories: - title: 💥 Breaking Changes 💥 labels: - "version: bump major" - breaking-change - title: 💡 Enhancements labels: - "type: enhancement" - title: 🐛 Fixes labels: - "type: bug" - title: 🛠 Maintenance labels: - "type: maintenance" - "type: dependencies" - "type: documentation" - title: 🤷 Other Changes labels: - "*" ================================================ FILE: .github/workflows/add-to-project-v2.yml ================================================ name: Add to project on: issues: types: [opened] pull_request_target: types: [opened] jobs: add-to-project: runs-on: ubuntu-latest name: Add issues and PRs to project steps: - uses: actions/add-to-project@main with: project-url: https://github.com/orgs/honeycombio/projects/27 github-token: ${{ secrets.GHPROJECTS_TOKEN }} ================================================ FILE: .github/workflows/apply-labels.yml ================================================ name: Apply project labels on: [issues, pull_request_target, label] jobs: apply-labels: runs-on: ubuntu-latest name: Apply common project labels steps: - uses: honeycombio/oss-management-actions/labels@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/stale.yml ================================================ name: 'Close stale issues and PRs' on: schedule: - cron: '30 1 * * *' jobs: stale: name: 'Close stale issues and PRs' runs-on: ubuntu-latest permissions: issues: write pull-requests: write steps: - uses: actions/stale@v4 with: start-date: '2021-09-01T00:00:00Z' stale-issue-message: 'Marking this issue as stale because it has been open 14 days with no activity. Please add a comment if this is still an ongoing issue; otherwise this issue will be automatically closed in 7 days.' stale-pr-message: 'Marking this PR as stale because it has been open 30 days with no activity. Please add a comment if this PR is still relevant; otherwise this PR will be automatically closed in 7 days.' close-issue-message: 'Closing this issue due to inactivity. Please see our [Honeycomb OSS Lifecyle and Practices](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md).' close-pr-message: 'Closing this PR due to inactivity. Please see our [Honeycomb OSS Lifecyle and Practices](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md).' days-before-issue-stale: 14 days-before-pr-stale: 30 days-before-issue-close: 7 days-before-pr-close: 7 any-of-labels: 'status: info needed,status: revision needed' ================================================ FILE: .github/workflows/validate-pr-title.yml ================================================ name: "Validate PR Title" on: pull_request: types: - opened - edited - synchronize jobs: main: name: Validate PR title runs-on: ubuntu-latest steps: - uses: amannn/action-semantic-pull-request@v5 id: lint_pr_title name: "🤖 Check PR title follows conventional commit spec" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: # Have to specify all types because `maint` and `rel` aren't defaults types: | maint rel fix feat chore ci docs style refactor perf test ignoreLabels: | "type: dependencies" # When the previous steps fails, the workflow would stop. By adding this # condition you can continue the execution with the populated error message. - if: always() && (steps.lint_pr_title.outputs.error_message != null) name: "📝 Add PR comment about using conventional commit spec" uses: marocchino/sticky-pull-request-comment@v2 with: header: pr-title-lint-error message: | Thank you for contributing to the project! 🎉 We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted. Make sure to prepend with `feat:`, `fix:`, or another option in the list below. Once you update the title, this workflow will re-run automatically and validate the updated title. Details: ``` ${{ steps.lint_pr_title.outputs.error_message }} ``` # Delete a previous comment when the issue has been resolved - if: ${{ steps.lint_pr_title.outputs.error_message == null }} name: "❌ Delete PR comment after title has been updated" uses: marocchino/sticky-pull-request-comment@v2 with: header: pr-title-lint-error delete: true ================================================ FILE: .gitignore ================================================ # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib # Test binary, build with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out buildevents ================================================ FILE: .go-version ================================================ 1.23.2 ================================================ FILE: CHANGELOG.md ================================================ # buildevents changelog ## v0.18.0 - 2025-06-30 ### Enhancements - feat: return list of failed jobs in cmd watch (#225) | @cewkrupa ### Maintenance - maint(deps): bump github.com/honeycombio/beeline-go from 1.18.0 to 1.19.0 in the examples group (#230) | @dependabot - maint(deps): bump the examples group across 1 directory with 2 updates (#229) | @dependabot - maint(deps): bump the examples group with 3 updates (#227) | @dependabot ## v0.17.0 - 2024-10-16 ### Fixes - fix(watch): not_running is the new queued (#221) | [Liz Fong-Jones](https://github.com/lizthegrey) ### Maintenance - maint: update go version and docs (#223) | [Jamie Danielson](https://github.com/JamieDanielson) - maint(go): update to go1.23 (#222) | [Liz Fong-Jones](https://github.com/lizthegrey) - maint(deps): bump the examples group with 3 updates (#218) | [dependabot[bot]](https://github.com/dependabot[bot]) - docs: update vulnerability reporting process (#219) | [Robb Kidd](https://github.com/robbkidd) - maint: update repo for pipeline team ownership (#217) | [Jamie Danielson](https://github.com/JamieDanielson) - maint(deps): bump github.com/stretchr/testify from 1.8.4 to 1.9.0 (#214) | [dependabot[bot]](https://github.com/dependabot[bot]) - maint(deps): bump github.com/honeycombio/beeline-go from 1.14.0 to 1.15.0 (#212) | [dependabot[bot]](https://github.com/dependabot[bot]) ## 0.16.0 - 2024-02-29 ### Enhancements - upgrade to libhoney-go 1.21.0 to support classic ingest keys (#208) | [@cewkrupa](https://github.com/cewkrupa) ### Maintenance - Bump github.com/honeycombio/beeline-go from 1.13.0 to 1.14.0 (#206) | [dependabot](https://github.com/dependabot) - Bump github.com/spf13/cobra from 1.7.0 to 1.8.0 (#205) | [dependabot](https://github.com/dependabot) - Bump github.com/honeycombio/beeline-go from 1.12.0 to 1.13.0 (#202) | [dependabot](https://github.com/dependabot) ## 0.15.0 - 2023-07-17 ### Enhancements - add `meta.arch` and `meta.os` fields to spans (#200) | [@ismith](https://github.com/ismith) ### Maintenance - Bump github.com/honeycombio/beeline-go from 1.11.1 to 1.12.0 (#198) | [dependabot](https://github.com/dependabot) - Bump github.com/honeycombio/libhoney-go from 1.19.0 to 1.20.0 (#199) | [dependabot](https://github.com/dependabot) ## 0.14.0 - 2023-06-23 ### Enhancements - add support for Windows artifacts (#193) | [@jharley](https://github.com/jharley) ### Maintenance - Bump Go to 1.20 (#193) | [@jharley](https://github.com/jharley) - Bump github.com/spf13/cobra from 1.6.1 to 1.7.0 (#191) | [dependabot](https://github.com/dependabot) - Bump github.com/stretchr/testify from 1.8.0 to 1.8.4 (#178, #187, #192) | [dependabot](https://github.com/dependabot) - Bump github.com/honeycombio/beeline-go from 1.9.0 to 1.11.1 (#170, #179) | [dependabot](https://github.com/dependabot) - Bump github.com/honeycombio/libhoney-go from 1.16.0 to 1.18.0 (#180) | [dependabot](https://github.com/dependabot) - Bump github.com/spf13/cobra from 1.5.0 to 1.7.0 (#181, #191) | [dependabot](https://github.com/dependabot) ## 0.13.0 - 2022-08-25 ### Enhancements - include sending error true for spans representing error states for builds (#168) | [@mjayaram](https://github.com/mjayaram) - Removes checking and warning for when only the dataset is configured for Buildevents; Updates logic to set default is no Dataset is configured for the non-classic use (#167) | [@mjayaram](https://github.com/mjayaram) ### Maintenance - Bump github.com/honeycombio/beeline-go from 1.8.0 to 1.9.0 (#166) | [dependabot](https://github.com/dependabot) ## 0.12.1 - 2022-07-20 ### Maintenance - Re-release to fix OpenSSL CVE | [@kentquirk](https://github.com/kentquirk) ## 0.12.0 - 2022-07-14 ### Enhancements - Add support to send data to environments (#162) | [@MikeGoldsmith](https://github.com/MikeGoldsmith) ## 0.11.0 - 2022-07-13 ### Enhancements - add gha-buildevents as GHA provider alias (#160) | [@dstrelau](https://github.com/dstrelau) ### Maintenance - Bump github.com/spf13/cobra from 1.4.0 to 1.5.0 (#161) | [dependabot](https://github.com/dependabot) ## 0.10.0 - 2022-06-14 ### Enhancements - Build for Darwin ARM64 (#157) | [Kent Quirk](https://github.com/kentquirk) & [John Dorman](https://github.com/boostchicken) ### Maintenance - [docs] Add examples of generated events (#155) | [Kent Quirk](https://github.com/kentquirk) - [docs] Remember to update orb when releasing a new version (#152) | [Vera Reynolds](https://github.com/vreynolds) ## 0.9.2 - 2022-04-25 ### Maintenance - update ci image to cimg/go:1.18 (#150) | [@JamieDanielson](https://github.com/JamieDanielson) - - fixes openSSL CVE ## 0.9.1 - 2022-04-15 - [bug] Fix default value for dataset to be empty so that dataset determination logic works correctly. (#148) [@kentquirk](https://github.com/kentquirk) ## 0.9.0 - 2022-04-14 - Bump cobra to v1.4.0 - Bump beeline to v1.8.0 - Bump libhoney to v1.15.8 - Use cobra.MatchAll instead of identical custom code - Clean up buildURL function to construct URLs more safely - The `service_name` field is mirrored to `service.name` - Detect classic key and change behavior for non-classic mode: - Service Name, if specified, is used as the dataset as well as both `service_name` and `service.name` fields. - If dataset is specified and service name is not, it will be used but will generate a warning (except in quiet mode). - If both are specified, service name will be used, dataset is ignored, and a warning will be emitted (except in quiet mode). - The command name is now sent as command_name (in classic it is still sent as service_name). - The `watch` command now sets the `name` field to merely `watch` rather than a high-cardinality value, making it easier to aggregate queries across different builds. - Dataset name is trimmed of leading/trailing whitespace; if any was found emits a warning (except in quiet mode) ## 0.8.0 - 2022-01-13 ### Fixes - Return underlying exit code when running commands (#137) | [@jhchabran](https://github.com/jhchabran) ## 0.7.2 - 2022-01-07 ### Fixes - Display underlying error when verifying API key (#135) | [@jhchabran](https://github.com/jhchabran) ### Maintenance - Update ci image (#132) | [@vreynolds](https://github.com/vreynolds) - Add re-triage workflow (#131) | [@vreynolds](https://github.com/vreynolds) - Only create one draft gh release (#128) | [@vreynolds](https://github.com/vreynolds) - Bump github.com/spf13/cobra from 0.0.7 to 1.2.1 (#130) - Bump github.com/honeycombio/beeline-go from 1.3.1 to 1.3.2 (#129) - Bump github.com/honeycombio/beeline-go from 1.2.0 to 1.3.1 (#123) ## 0.7.1 - 2021-11-19 ### Fixed - Do not fail the build if `watch` fails to fetch Honeycomb URL (#126) | [@asdvalenzuela](https://github.com/asdvalenzuela) ### Maintenance - Create draft gh release during publish (#124) | [@MikeGoldsmith](https://github.com/MikeGoldsmith) ## 0.7.0 - 2021-11-03 ### Added - Allow specifying an alternative shell (#119) | [@estheruary](https://github.com/estheruary) ### Maintenance - empower apply-labels action to apply labels (#120) - bump libhoney-go to v1.15.6 (#121) - Bump github.com/honeycombio/libhoney-go from 1.15.4 to 1.15.5 (#118) - Change maintenance badge to maintained (#116) - Adds Stalebot (#117) - Add NOTICE (#113) - Bump github.com/honeycombio/beeline-go from 1.1.2 to 1.2.0 (#109) - Bump github.com/honeycombio/libhoney-go from 1.15.3 to 1.15.4 (#108) - Add issue and PR templates (#112) - Add OSS lifecycle badge (#111) - Add community health files (#110) ## 0.6.0 - 2021-07-14 ### Added - Forward stdin. [#99](https://github.com/honeycombio/buildevents/pull/99) | [@shlevy](https://github.com/shlevy) ### Maintenance - Bump github.com/spf13/cobra from 0.0.5 to 0.0.7 [#102](https://github.com/honeycombio/buildevents/pull/102) - Bump github.com/honeycombio/libhoney-go from 1.10.0 to 1.15.3 [#101](https://github.com/honeycombio/buildevents/pull/101) - Bump github.com/jszwedko/go-circleci from 0.2.0 to 0.3.0 [#103](https://github.com/honeycombio/buildevents/pull/103) - stop watching dependabot builds [#106](https://github.com/honeycombio/buildevents/pull/106) ## 0.5.2 - 2021-07-08 ### Added - Add support for Buildkite CI environment detection. [#97](https://github.com/honeycombio/buildevents/pull/97) | [@MikeGoldsmith](https://github.com/MikeGoldsmith) ## 0.5.1 - 2021-03-27 ### Added - Added ARM64 builds. [#91](https://github.com/honeycombio/buildevents/pull/91) | [@ismith](https://github.com/ismith) ## 0.5.0 - 2021-02-09 ### Added - Quiet option to cmd [#80](https://github.com/honeycombio/buildevents/pull/80) | [@tybritten](https://github.com/tybritten) - Bitbucket support [#85](https://github.com/honeycombio/buildevents/pull/85) | [@manjunathb4461](https://github.com/manjunathb4461) - Support for overriding default event fields [#76](https://github.com/honeycombio/buildevents/pull/76) | [@MarilynFranklin](https://github.com/MarilynFranklin) ### Fixed - Azure pipelines constant typo [#84](https://github.com/honeycombio/buildevents/pull/84) | [@manjunathb4461](https://github.com/manjunathb4461) ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Code of Conduct This project has adopted the Honeycomb User Community Code of Conduct to clarify expected behavior in our community. https://www.honeycomb.io/honeycomb-user-community-code-of-conduct/ ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing Guide Please see our [general guide for OSS lifecycle and practices.](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md) ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: LICENSES/github.com/facebookgo/clock/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2014 Ben Johnson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: LICENSES/github.com/facebookgo/limitgroup/license ================================================ BSD License For limitgroup software Copyright (c) 2015, Facebook, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Facebook nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: LICENSES/github.com/facebookgo/muster/license ================================================ BSD License For muster software Copyright (c) 2015, Facebook, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Facebook nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: LICENSES/github.com/honeycombio/beeline-go/propagation/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: LICENSES/github.com/honeycombio/beeline-go/propagation/NOTICE ================================================ Copyright (c) 2016-Present Honeycomb, Hound Technology, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: LICENSES/github.com/honeycombio/libhoney-go/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: LICENSES/github.com/honeycombio/libhoney-go/NOTICE ================================================ Copyright (c) 2016-Present Honeycomb, Hound Technology, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: LICENSES/github.com/jszwedko/go-circleci/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Jesse Szwedko Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: LICENSES/github.com/klauspost/compress/LICENSE ================================================ Copyright (c) 2012 The Go Authors. All rights reserved. Copyright (c) 2019 Klaus Post. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------ Files: gzhttp/* Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2016-2017 The New York Times Company Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ------------------ Files: s2/cmd/internal/readahead/* The MIT License (MIT) Copyright (c) 2015 Klaus Post Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------- Files: snappy/* Files: internal/snapref/* Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------- Files: s2/cmd/internal/filepathx/* Copyright 2016 The filepathx Authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: LICENSES/github.com/klauspost/compress/internal/snapref/LICENSE ================================================ Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: LICENSES/github.com/klauspost/compress/zstd/internal/xxhash/LICENSE.txt ================================================ Copyright (c) 2016 Caleb Spare MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: LICENSES/github.com/kr/logfmt/Readme ================================================ Go package for parsing (and, eventually, generating) log lines in the logfmt style. See http://godoc.org/github.com/kr/logfmt for format, and other documentation and examples. Copyright (C) 2013 Keith Rarick, Blake Mizerany Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: LICENSES/github.com/spf13/cobra/LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ================================================ FILE: LICENSES/github.com/spf13/pflag/LICENSE ================================================ Copyright (c) 2012 Alex Ogier. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: LICENSES/github.com/vmihailenco/msgpack/v5/LICENSE ================================================ Copyright (c) 2013 The github.com/vmihailenco/msgpack Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: LICENSES/github.com/vmihailenco/tagparser/v2/LICENSE ================================================ Copyright (c) 2019 The github.com/vmihailenco/tagparser Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: LICENSES/gopkg.in/alexcesaro/statsd.v2/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Alexandre Cesaro Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ MAKEFLAGS += --warn-undefined-variables MAKEFLAGS += --no-builtin-rules MAKEFLAGS += --no-builtin-variables GOTESTCMD = $(if $(shell command -v gotestsum),gotestsum --junitfile ./test_results/$(1).xml --format testname --,go test) .PHONY: test #: run all tests test: test_with_race test_all .PHONY: test_with_race #: run only tests tagged with potential race conditions test_with_race: test_results @echo @echo "+++ testing - race conditions?" @echo $(call GOTESTCMD,$@) -tags race --race --timeout 60s -v ./... .PHONY: test_all #: run all tests, but with no race condition detection test_all: test_results @echo @echo "+++ testing - all the tests" @echo $(call GOTESTCMD,$@) -tags all --timeout 60s -v ./... test_results: @mkdir -p test_results .PHONY: install-tools install-tools: go install github.com/google/go-licenses/v2@v2.0.0-alpha.1 .PHONY: update-licenses update-licenses: install-tools rm -rf LICENSES; \ #: We ignore the standard library (go list std) as a workaround for \ "https://github.com/google/go-licenses/issues/244." The awk script converts the output \ of `go list std` (line separated modules) to the input that `--ignore` expects (comma separated modules). go-licenses save --save_path LICENSES --ignore "github.com/honeycombio/buildevents" \ --ignore $(shell go list std | awk 'NR > 1 { printf(",") } { printf("%s",$$0) } END { print "" }') ./; .PHONY: verify-licenses verify-licenses: install-tools go-licenses save --save_path temp --ignore "github.com/honeycombio/buildevents" \ --ignore $(shell go list std | awk 'NR > 1 { printf(",") } { printf("%s",$$0) } END { print "" }') ./; \ chmod +r temp; \ if diff temp LICENSES; then \ echo "Passed"; \ rm -rf temp; \ else \ echo "LICENSES directory must be updated. Run make update-licenses"; \ rm -rf temp; \ exit 1; \ fi; \ ================================================ FILE: NOTICE ================================================ Copyright (c) 2016-Present Honeycomb, Hound Technology, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: OSSMETADATA ================================================ osslifecycle=maintained ================================================ FILE: README.md ================================================ # buildevents [![OSS Lifecycle](https://img.shields.io/osslifecycle/honeycombio/buildevents?color=success)](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md) [![CircleCI](https://circleci.com/gh/honeycombio/buildevents.svg?style=shield)](https://circleci.com/gh/honeycombio/buildevents) buildevents is a small binary used to help instrument builds in a build system such as Travis-CI, CircleCI, Jenkins, and so on. It is installed during the setup phase and then invoked as part of each step in order to visualize the build as a trace in Honeycomb The trace that you get at the end represents the entire build. It has spans for each section and subsection of the build, representing groups of actual commands that are run. The duration of each span is how long that stage or specific command took to run, and includes whether or not the command succeeded. Here's an example showing a build that ran on CircleCI. It goes through running go tests, setting up javascript dependencies, triggers js_build and poodle_test in parallel after dependencies are configured, and then continues off below the captured portion of the waterfall. ![CircleCI_Build_Trace](https://user-images.githubusercontent.com/361454/57872910-ac9eea00-77c1-11e9-8bdd-db7a870dcd61.png) # Setup Getting your build ready to use `buildevents` involves: * installing the `buildevents` binary in your build environment * setting a number of environment variables for configuring the tool * choosing a unique trace identifier ## Installation If you have a working go environment in your build, the easiest way to install `buildevents` is via `go get`. ``` go get github.com/honeycombio/buildevents/ ``` There are also built binaries for linux and macOS hosted on Github and available under the [releases](https://github.com/honeycombio/buildevents/releases) tab. The following commands will download and make executable the github-hosted binary. **linux, 32-bit x86:** ``` curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-386 chmod 755 buildevents ``` **linux, 64-bit x86:** ``` curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64 chmod 755 buildevents ``` **linux, arm64:** ``` curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-arm64 chmod 755 buildevents ``` **macOS, amd64:** ``` curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-darwin-amd64 chmod 755 buildevents ``` **macOS, arm64:** ``` curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-darwin-arm64 chmod 755 buildevents ``` **windows, 32-bit x86:** ``` curl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-386.exe ``` **windows, 64-bit x86:** ``` curl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-amd64.exe ``` **windows, arm64:** ``` curl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-arm64.exe ``` If this doesn't work for you, please [let us know](mailto:support@honeycomb.io) - we'd love to hear what would work. ## Environment Variables There is one required environment variable; it will hold your Honeycomb API key (available at https://ui.honeycomb.io/account). If it is absent, events will not be sent to Honeycomb. Set `BUILDEVENT_APIKEY` to hold your API key. There are several other optional enviornment variables that will adjust the behavior of `buildevents`: * `BUILDEVENT_DATASET` sets the Honeycomb dataset to use. The default is `buildevents` * `BUILDEVENT_APIHOST` sets the API target for sending Honeycomb traces. Default is `https://api.honeycomb.io/` * `BUILDEVENT_CIPROVIDER` if set, a field in all spans named `ci_provider` will contain this value. If unset, `buildevents` will inspect the environment to try and detect Travis-CI, CircleCI, GitLab-CI, Buildkite, Jenkins-X, Google-Cloud-Build and Bitbucket-Pipelines (by looking for the environment variables `TRAVIS`, `CIRCLECI`, `BUILDKITE`, `GITLAB_CI`, `JENKINS-X`, `GOOGLE-CLOUD-BUILD` and `BITBUCKET_BUILD_NUMBER` respectively). If either Travis-CI, CircleCI, GitLab-CI, Buildkite, Jenkins-X, Google-Cloud-Build or Bitbucket-Pipelines are detected, `buildevents` will add a number of additional fields from the environment, such as the branch name, the repository, the build number, and so on. If detection fails and you are on Travis-CI, CircleCI, GitLab-CI, Jenkins-X, Google-Cloud-Build or Bitbucket-Pipelines setting this to `Travis-CI`, `CircleCI`, `Buildkite`, `GitLab-CI`, `Jenkins-X`, `Google-Cloud-Build`, or `Bitbucket-Pipelines` precisely will also trigger the automatic field additions. * `BUILDEVENT_FILE` if set, is used as the path of a text file holding arbitrary key=val pairs (multi-line-capable, logfmt style) that will be added to the Honeycomb event. ## Trace Identifier The `buildevents` script needs a unique ID to join together all of the steps and commands with the build. This is the Trace ID. It must be unique within the Honeycomb dataset holding traces. An excellent choice is the Build ID, since it is both unique (even when re-running builds, you will often get a new Build ID) and is also a primary value that the build system uses to identify the build. The Build ID may already be available in the environment for your build: * Travis-CI: `TRAVIS_BUILD_ID` * CircleCI: `CIRCLE_WORKFLOW_ID` (if you're using workflows) * CircleCI: `CIRCLE_BUILD_NUM` (the build number for this job if you're not using workflows) * GitLab-CI: `CI_PIPELINE_ID` * Buildkite: `BUILDKITE_BUILD_ID` * JenkinsX: `JENKINSX_BUILD_NUMBER` * Google-Cloud-Build: `BUILD_ID` * GitHub Actions: `GITHUB_RUN_ID` * Bitbucket Pipelines: `BITBUCKET_BUILD_NUMBER` # Use Now that `buildevents` is installed and configured, actually generating spans to send to Honeycomb involves invoking `buildevents` in various places throughout your build config. `buildevents` is invoked with one of three modes, `build`, `step`, and `cmd`. * The `build` mode sends the root span for the entire build. It should be called when the build finishes and records the duration of the entire build. It emits a URL pointing to the generated trace in Honeycomb to STDOUT. * The `step` mode represents a block of related commands. In Travis-CI, this is one of `install`, `before_script`, `script`, and so on. In CircleCI, this most closely maps to a single job. It should be run at the end of the step. * The `cmd` mode invokes an individual command that is part of the build, such as running DB migrations or running a specific test suite. It must be able to be expressed as a single shell command - either a process like `go test` or a shell script. The command to run is the final argument to `buildevents` and will be launched via `bash -c` using `exec`. You can specify an alternate shell using the `-s/--shell` flag but it must support the the `-c` flag. ## build Though listed first, running `buildevents` in `build` mode should actually be the last command that your build runs so that it can record the total running duration for the build. It does this by having the time the build started as one of the arguments passed in. The output of buildevents in `build` will be a link to the trace within Honeycomb. Take this URL and use it in the notifications your CI system emits to easily jump to the Honeycomb trace for a build. If the API Key used in this run is not valid, no output will be emitted. Note that CircleCI uses an alternate method of creating the root span, so the `build` command should not be used. Use the `watch` command instead. For the `build` step, you must first record the time the build started. * Travis-CI: the `env` section of the config file establishes some global variables in the environment. This is run before anything else, so gets a good start time. The actual invocation of `buildevents build` should be as close to the last thing that the build does as possible. * Travis-CI: the end of the `after_failure` and `after_success` steps Travis-CI example: ```yaml env: global: - BUILD_START=$(date +%s) ... after_failure: - traceURL=$(buildevents build $TRAVIS_BUILD_ID $BUILD_START failure) - echo "Honeycomb Trace: $traceURL" after_success: - traceURL=$(buildevents build $TRAVIS_BUILD_ID $BUILD_START success) - echo "Honeycomb Trace: $traceURL" ``` ### what it generates Given this command: ```bash buildevents $HOST -k $API_KEY build htjebmye $BUILD_STARTTIME success ``` The event that arrives at Honeycomb (which has no trace.parent_id since it is the root of a trace) might look like: ```json { "Timestamp": "2022-05-24T01:49:13Z", "command_name": "build", "duration_ms": 4981, "meta.version": "dev", "name": "build htjebmye", "service.name": "build", "service_name": "build", "source": "buildevents", "status": "success", "trace.span_id": "htjebmye", "trace.trace_id": "htjebmye" } ``` ## watch CirclecI requires use of the CircleCI API to detect when workflows start and stop. There is no facility to always run a job after all others, so what works using the Travis-CI `after_failure` will not work on CircleCI. However, the CircleCI API exposes when the current workflow has started, and can be used intsead. The `watch` command polls the CircleCI API and waits until all jobs have finished (either succeeded, failed, or are blocked). It then reports the final status of the build with the appropriate timers. `watch` should be invoked in a job all on its own, dependent on only the `setup` job, with only the Trace ID to use. After some time, `watch` will timeout waiting for the build to finish and fail. The timeout default is 10 minutes and can be overridden by setting `BUILDEVENT_TIMEOUT` Using the `watch` command requires a personal (not project) CircleCI API token. You can provide this token to `buildevents` via the `BUILDEVENT_CIRCLE_API_TOKEN` environment variable. You can get a personal API token from https://circleci.com/account/api. For more detail on tokens, please see the [CircleCI API Tokens documentation](https://circleci.com/docs/2.0/managing-api-tokens/) The `watch` command will emit a link to the finished trace to the job output in Honeycomb when the build is complete. ```yaml jobs: send_trace: steps: - run: buildevents watch $CIRCLE_WORKFLOW_ID ``` ## step The `step` mode is the outer wrapper that joins a collection of individual `cmd`s together in to a block. Like the `build` command, it should be run at the end of the collection of `cmd`s and needs a start time collected at the beginning. In addition to the trace identifier, it needs a step identifier that will also be passed to all the `cmd`s that are part of this step in order to tie them together in to a block. Because the step identifier must be available to all commands, both it and the start time should be generated at the beginning of the step and recorded. The step identifier must be unique within the trace (but does not need to be globally unique). To avoid being distracting, we use a hash of the step name as the identifier. Travis-CI exmaple: ```yaml before_script: - STEP_START=$(date +%s) - STEP_SPAN_ID=$(echo before_script | sum | cut -f 1 -d \ ) - ... do stuff - buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START before_script ``` CircleCI example: ```yaml jobs: go_test: steps: - run: echo "STEP_START=$(date +%s)" >> $BASH_ENV - run: echo "STEP_SPAN_ID=$(echo go_test | sum | cut -f 1 -d \ )" >> $BASH_ENV - run: ... do stuff - run: name: finishing span for the job command: $GOPATH/bin/buildevents step $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID $STEP_START go_test when: always # ensures the span is always sent, even when something in the job fails ``` ### what it generates Given this command: ```bash buildevents $HOST -k $API_KEY step htjebmye building_htjebmye $STEP_STARTTIME building ``` The event that arrives at Honeycomb might look like: ```json { "Timestamp": "2022-05-24T01:49:14Z", "command_name": "step", "duration_ms": 3064, "meta.version": "dev", "name": "building", "service.name": "step", "service_name": "step", "source": "buildevents", "trace.parent_id": "htjebmye", "trace.span_id": "building_htjebmye", "trace.trace_id": "htjebmye" } ``` ## cmd Running `buildevents cmd` will run the given command, time it, and include the `status` of the command (`success` or `failure`). `buildevents` passes through both STDOUT and STDERR from the process it wraps, and exits with the same exit code as the wrapped process. The actual command to run is separated from the `buildevents` arguments by a double hyphen `--`. This is the most frequent line you'll see in your config file; anything of consequence should generate a span. Travis-CI example: ```yaml script: - buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-test -- go test -timeout 2m -mod vendor ./... ``` CircleCI example: ```yaml jobs: go_test: steps: - run: $GOPATH/bin/buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-test -- go test -timeout 2m -mod vendor ./... ``` ### what it generates Given this command: ```bash buildevents $HOST -k $API_KEY cmd htjebmye building_htjebmye compile -- sleep 1 ``` The event that arrives at Honeycomb might look like: ```json { "Timestamp": "2022-05-24T01:49:14.653182Z", "cmd": "\"sleep\" \"1\"", "command_name": "cmd", "duration_ms": 1008, "meta.version": "dev", "name": "compile", "service.name": "cmd", "service_name": "cmd", "source": "buildevents", "status": "success", "trace.parent_id": "building_htjebmye", "trace.span_id": "6facde6ac6a95e704b9ec1c837270578", "trace.trace_id": "htjebmye" } ``` ## Attaching more traces from your build and test process Every command running through `buildevents cmd` will receive a `HONEYCOMB_TRACE` environment variable that contains a marshalled trace propagation context. This can be used to connect more spans to this trace. Ruby Beeline example: ```ruby # at the very start of the command # establish a command-level span, linking to the buildevent process_span = Honeycomb.start_span(name: File.basename($PROGRAM_NAME), serialized_trace: ENV['HONEYCOMB_TRACE']) Honeycomb.add_field_to_trace('process.full_name', $PROGRAM_NAME) # if you're not passing sensitive information through CLI args, enable this for more insights. #Honeycomb.add_field_to_trace('process.args', ARGV) # override the HONEYCOMB_TRACE for sub-processes ENV['HONEYCOMB_TRACE'] = process_span.to_trace_header # ensure that the process_span is sent before the process terminates at_exit do if $ERROR_INFO&.is_a?(SystemExit) process_span.add_field('process.exit_code', $ERROR_INFO.status) elsif $ERROR_INFO process_span.add_field('process.exit_code', $ERROR_INFO.class.name) else process_span.add_field('process.exit_code', 'unknown') end process_span.send end ``` # Putting it all together We've covered each of the three modes in which `buildevents` is invoked and shown abbreviated examples for each one. Now it's time to look at an entire config to see how they interact: installation, running a build, and finally reporting the whole thing. In both of these examples, the `BUILDEVENT_APIKEY` should be set in the protected environment variable section of the CI config so that your API key is not checked in to your source. Travis-CI example: ```yaml env: global: - BUILD_START=$(date +%s) install: - STEP_START=$(date +%s) - STEP_SPAN_ID=$(echo install | sum | cut -f 1 -d \ ) - curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64 - chmod 755 buildevents - # ... any other setup necessary for your build - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START install script: - STEP_START=$(date +%s) - STEP_SPAN_ID=$(echo script | sum | cut -f 1 -d \ ) - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-tests -- go test ./... - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID js-tests -- yarn test - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START script after_failure: - ./buildevents build $TRAVIS_BUILD_ID $BUILD_START failure after_success: - STEP_START=$(date +%s) - STEP_SPAN_ID=$(echo after_success | sum | cut -f 1 -d \ ) - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID build -- go install ./... - # ... tar up artifacts, upload them, etc. - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START after_success - ./buildevents build $TRAVIS_BUILD_ID $BUILD_START success ``` CircleCI example: ```yaml version: 2.1 # factored out start/finish_job_span commands here so we don't have every one of our build jobs duplicating them commands: with_job_span: parameters: steps: type: steps steps: - attach_workspace: at: buildevents - run: name: starting span for job command: | echo "STEP_START=$(date +%s)" >> $BASH_ENV echo "STEP_SPAN_ID=$(echo $CIRCLE_JOB | sum | cut -f 1 -d \ )" >> $BASH_ENV - run: echo "PATH=$PATH:buildevents/bin/" >> $BASH_ENV - steps: << parameters.steps >> - run: name: finishing span for job command: buildevents step $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID $STEP_START $CIRCLE_JOB when: always jobs: setup: steps: - run: | mkdir -p buildevents/bin date +%s > buildevents/build_start - run: go get github.com/honeycombio/buildevents - run: cp $GOPATH/bin/buildevents buildevents/bin/ - persist_to_workspace: root: buildevents paths: - build_start - bin/buildevents send_trace: steps: - attach_workspace: at: buildevents - run: buildevents watch $CIRCLE_WORKFLOW_ID test: steps: - with_job_span: steps: - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID go-tests -- go test ./... - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID js-tests -- yarn test build: steps: - with_job_span: steps: - run: mkdir artifacts - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID build -- go install ./... - run: # publish your build artifacts workflows: test-and-build: jobs: - setup - send_trace: requires: - setup - test: requires: - setup - build: requires: - test ``` GitLab CI example: ```yaml # Not a huge fan of YAML anchors, but it's the easiest way to # extend the scripts in jobs where you need other before_script and after_script .default_before_script: &default_before_script - STEP_START=$(date +%s) - STEP_SPAN_ID=$(echo $CI_JOB_NAME | sum | cut -f 1 -d \ ) - echo "export STEP_START=$STEP_START" >> buildevents/env - echo "export STEP_SPAN_ID=$STEP_SPAN_ID" >> buildevents/env - echo "export PATH=\"$PATH:buildevents/bin/\"" >> buildevents/env - source buildevents/env - cat buildevents/env .default_after_script: &default_after_script - source buildevents/env - cat buildevents/env - buildevents step $CI_PIPELINE_ID $STEP_SPAN_ID $STEP_START $CI_JOB_NAME default: image: golang:latest before_script: - *default_before_script after_script: - *default_after_script stages: # .pre and .post are guaranteed to be first and last run jobs # https://docs.gitlab.com/ee/ci/yaml/README.html#pre-and-post - .pre - build - test - .post setup: before_script: - mkdir -p buildevents/bin/ - *default_before_script script: - curl -L -o main https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64 - chmod 755 main - mv main buildevents/bin/buildevents - export BUILD_START=$(date +%s) - echo "export BUILD_START=$(date +%s)" >> buildevents/env artifacts: paths: - buildevents stage: .pre go_build: script: - buildevents cmd $CI_PIPELINE_ID $STEP_SPAN_ID build -- go install ./... stage: build go_test: script: - buildevents cmd $CI_PIPELINE_ID $STEP_SPAN_ID build -- go test ./... stage: test send_success_trace: script: - "traceURL=$(buildevents build $CI_PIPELINE_ID $BUILD_START success)" - "echo \"Honeycomb Trace: $traceURL\"" stage: .post rules: - when: on_success send_failure_trace: script: - "traceURL=$(buildevents build $CI_PIPELINE_ID $BUILD_START failure)" - "echo \"Honeycomb Trace: $traceURL\"" stage: .post rules: - when: on_failure ``` # Positional argument reference All the arguments to the various `buildevents` modes are listed above, but for convenience, here is a summary of the modes and the arguments that each requires. The first argument is the running mode for this invocation of buildevents: `build`, `watch`, `step`, or `cmd` The remaining arguments differ depending on the mode. arguments for the `build` mode: 1. `build_id` this is used as both the trace ID and to generate a URL to link back to the build 2. `start_time` used to calculate the total duration of the build 3. `status` should be `success` or `failure` and indicates whether the overall build succeeeded or failed arguments for the `watch` mode: 1. `build_id` this is used as the trace ID arguments for the `step` mode: 1. `build_id` this is used as both the trace ID and to generate a URL to link back to the build 1. `step_id` buildevents expects a build to contain steps, and each step to have commands. The step ID is used to help construct this tree 1. `start_time` used to calculate the total duration of running this step in the build 1. `name` the last argument is the name for this step or command, used in the Honeycomb UI arguments for the `cmd` mode: 1. `build_id` this is used as both the trace ID and to generate a URL to link back to the build 1. `step_id` buildevents expects a build to contain steps, and each step to have commands. The step ID is used to help construct this tree 1. `name` the name for this command, used in the Honeycomb UI 1. `--` double hyphen indicates the rest of the line will be the command to run ## Note `name` is most useful if it is a low-cardinality value, usually something like the name of a step in your process. Using a low-cardinality value makes it valuable to do things like `GROUP BY name` in your queries. ## Differences between Classic and non-Classic environments For "Honeycomb Classic", `buildevents` works almost the same as it always has. It has added service.name in addition to service_name; both fields have the same value. In a non-Classic environment, there are several differences: * Service Name, if specified, is used as the dataset as well as both `service_name` and `service.name` fields. * if dataset is specified and service name is not, it will be used but will generate a warning. * if both are specified, service name will be used, dataset is ignored, and a warning will be emitted (except in quiet mode) * the command name is now sent as command_name (in classic it is sent as service_name) * the watch command now sets the `name` field to merely `watch` rather than a high-cardinality value, making it easier to aggregate queries across different builds ================================================ FILE: RELEASING.md ================================================ # Releasing - Check that licenses are current with `make verify-licenses` - If there are any changes, submit a separate PR to update licenses using `make update-licenses`. - Prep update PR for the [orb](https://github.com/honeycombio/buildevents-orb) with the new version of buildevents. - Update `CHANGELOG.md` with the changes since the last release. - Use below command to get a list of all commits since last release ```sh git log ..HEAD --pretty='%Creset- %s | [%an](https://github.com/%an)' ``` - Copy the output from the command above into the top of [changelog](./CHANGELOG.md) - fix each `https://github.com/` to point to the correct github username (the `git log` command can't do this automatically) - organize each commit based on their prefix into below three categories: ```sh ### Features - ### Fixes - ### Maintenance - ``` - Commit changes, push, and open a release preparation pull request for review. - Once the pull request is merged, fetch the updated `main` branch. - Apply a tag for the new version on the merged commit (e.g. `git tag -a v2.3.1 -m "v2.3.1"`) - Push the tag upstream (this will kick off the release pipeline in CI) e.g. `git push origin v2.3.1` - Ensure that there is a draft GitHub release created as part of CI publish steps. - Click "generate release notes" in GitHub for full changelog notes and any new contributors. ================================================ FILE: SECURITY.md ================================================ # Security Policy This security policy applies to public projects under the [honeycombio organization][gh-organization] on GitHub. For security reports involving the services provided at `(ui|ui-eu|api|api-eu).honeycomb.io`, refer to the [Honeycomb Bug Bounty Program][bugbounty] for scope, expectations, and reporting procedures. ## Security/Bugfix Versions Security and bug fixes are generally provided only for the last minor version. Fixes are released either as part of the next minor version or as an on-demand patch version. Security fixes are given priority and might be enough to cause a new version to be released. ## Reporting a Vulnerability We encourage responsible disclosure of security vulnerabilities. If you find something suspicious, we encourage and appreciate your report! ### Ways to report In order for the vulnerability reports to reach maintainers as soon as possible, the preferred way is to use the "Report a vulnerability" button under the "Security" tab of the associated GitHub project. This creates a private communication channel between the reporter and the maintainers. If you are absolutely unable to or have strong reasons not to use GitHub's vulnerability reporting workflow, please reach out to the Honeycomb security team at [security@honeycomb.io](mailto:security@honeycomb.io). [gh-organization]: https://github.com/honeycombio [bugbounty]: https://www.honeycomb.io/bugbountyprogram ================================================ FILE: SUPPORT.md ================================================ # How to Get Help This project uses GitHub issues to track bugs, feature requests, and questions about using the project. Please search for existing issues before filing a new one. ================================================ FILE: cmd_build.go ================================================ package main import ( "fmt" "os" "strings" "time" "github.com/spf13/cobra" libhoney "github.com/honeycombio/libhoney-go" ) func commandBuild(cfg *libhoney.Config, filename *string, ciProvider *string) *cobra.Command { // BUILD - eg: buildevents build $TRAVIS_BUILD_ID $BUILD_START success buildCmd := &cobra.Command{ Use: "build [flags] BUILD_ID BUILD_START OUTCOME", Short: "Sends the root span for the entire build", Long: ` The build mode sends the root span for the entire build. It should be called when the build finishes and records the duration of the entire build. It emits a URL pointing to the generated trace in Honeycomb to STDOUT.`, Args: argOptions(2, "success", "failure"), DisableFlagsInUseLine: true, RunE: func(cmd *cobra.Command, args []string) error { traceID := strings.TrimSpace(args[0]) startTime := parseUnix(strings.TrimSpace(args[1])) outcome := strings.TrimSpace(args[2]) ev := createEvent(cfg, *ciProvider, traceID) defer ev.Send() providerInfo(*ciProvider, ev) ev.Add(map[string]interface{}{ "service_name": ifClassic(cfg, "build", cfg.Dataset), "service.name": ifClassic(cfg, "build", cfg.Dataset), "command_name": "build", "trace.span_id": traceID, "name": "build " + traceID, "status": outcome, "duration_ms": time.Since(startTime) / time.Millisecond, "source": "buildevents", }) ev.Timestamp = startTime arbitraryFields(*filename, ev) url, err := buildURL(cfg, traceID, startTime.Unix()) if err != nil { fmt.Fprintf(os.Stderr, "Unable to create trace URL: %v\n", err) } else { fmt.Println(url) } return nil }, } return buildCmd } func argOptions(pos int, opts ...string) cobra.PositionalArgs { return cobra.MatchAll( cobra.MinimumNArgs(pos+1), func(cmd *cobra.Command, args []string) error { for _, opt := range opts { if strings.TrimSpace(args[pos]) == opt { return nil } } if len(opts) == 1 { return fmt.Errorf("argument at index %d (%q) must be %q", pos, strings.TrimSpace(args[pos]), opts[0]) } return fmt.Errorf("argument at index %d (%q) must be one of %v", pos, strings.TrimSpace(args[pos]), opts) }, ) } ================================================ FILE: cmd_cmd.go ================================================ package main import ( "crypto/rand" "fmt" "os" "os/exec" "strings" "time" "github.com/spf13/cobra" propagation "github.com/honeycombio/beeline-go/propagation" libhoney "github.com/honeycombio/libhoney-go" ) func commandCmd(cfg *libhoney.Config, filename *string, ciProvider *string) *cobra.Command { // CMD eg: buildevents cmd $TRAVIS_BUILD_ID $STAGE_SPAN_ID go-test -- go test github.com/honeycombio/hound/... execCmd := &cobra.Command{ Use: "cmd [flags] BUILD_ID STEP_ID NAME -- [shell command to execute]", Short: "Invoke an individual command that is part of the build.", Long: ` The cmd mode invokes an individual command that is part of the build, such as running DB migrations or running a specific test suite. It must be able to be expressed as a single shell command - either a process like "go test" or a shell script. The command to run is the final argument to buildevents and will be launched via "bash -c" using "exec". The shell can be changed with the -s/--shell flag.`, Args: cobra.MatchAll( cobra.MinimumNArgs(4), func(cmd *cobra.Command, args []string) error { if cmd.ArgsLenAtDash() != 3 { return fmt.Errorf("use `--` to signify shell command") } return nil }, ), DisableFlagsInUseLine: true, RunE: func(cmd *cobra.Command, args []string) error { // Don't show usage if RunE returns an error. This set in RunE // instead of when we instantiate the cmd so we don't suppress usage // for errors from Args. cmd.SilenceUsage = true traceID := strings.TrimSpace(args[0]) stepID := strings.TrimSpace(args[1]) name := strings.TrimSpace(args[2]) quiet, _ := cmd.Flags().GetBool("quiet") shell, _ := cmd.Flags().GetString("shell") var quoted []string for _, s := range args[3:] { quoted = append(quoted, fmt.Sprintf("\"%s\"", strings.Replace(s, "\"", "\\\"", -1))) } subcmd := strings.Join(quoted, " ") ev := createEvent(cfg, *ciProvider, traceID) defer ev.Send() providerInfo(*ciProvider, ev) spanBytes := make([]byte, 16) rand.Read(spanBytes) start := time.Now() // copy out the current set of fields to avoid later modification localFields := map[string]interface{}{} for k, v := range ev.Fields() { localFields[k] = v } var spanID = fmt.Sprintf("%x", spanBytes) prop := &propagation.PropagationContext{ TraceID: traceID, ParentID: spanID, TraceContext: localFields, } err := runCommand(subcmd, prop, quiet, shell) dur := time.Since(start) ev.Add(map[string]interface{}{ "trace.parent_id": stepID, "trace.span_id": spanID, "service_name": ifClassic(cfg, "cmd", cfg.Dataset), "service.name": ifClassic(cfg, "cmd", cfg.Dataset), "command_name": "cmd", "name": name, "duration_ms": dur / time.Millisecond, "cmd": subcmd, "source": "buildevents", }) ev.Timestamp = start // Annotate with arbitrary fields after the command runs // this way we can consume a file if the command itself generated one arbitraryFields(*filename, ev) if err == nil { ev.AddField("status", "success") } else { ev.Add(map[string]interface{}{ "error": true, "status": "failure", "failure_reason": err.Error(), }) } return err }, } var quiet bool var shell string execCmd.Flags().BoolVarP(&quiet, "quiet", "q", false, "silence non-cmd output") execCmd.Flags().StringVarP(&shell, "shell", "s", "/bin/bash", "path of shell executable to use for command, must accept -c as an argument") return execCmd } func runCommand(subcmd string, prop *propagation.PropagationContext, quiet bool, shell string) error { if !quiet { fmt.Println("running", shell, "-c", subcmd) } cmd := exec.Command(shell, "-c", subcmd) cmd.Env = append(os.Environ(), "HONEYCOMB_TRACE="+propagation.MarshalHoneycombTraceContext(prop), ) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin return cmd.Run() } ================================================ FILE: cmd_root.go ================================================ package main import ( "fmt" "os" "strings" "github.com/spf13/cobra" libhoney "github.com/honeycombio/libhoney-go" ) func commandRoot(cfg *libhoney.Config, filename *string, ciProvider *string, serviceName *string) *cobra.Command { root := &cobra.Command{ Version: Version, Use: "buildevents", Short: "buildevents creates events for your CI builds", Long: ` The buildevents executable creates Honeycomb events and tracing information about your Continuous Integration builds.`, PersistentPreRun: func(cmd *cobra.Command, args []string) { quiet, _ := cmd.Flags().GetBool("quiet") if cfg.IsClassic() { // if we're in classic mode, we want to behave the same as we always have if cfg.Dataset == "" { cfg.Dataset = "buildevents" } if *serviceName != "" && !quiet { fmt.Fprintf(os.Stderr, "WARN: classic mode ignores the service name parameter.\n") } } else { // This is the non-classic behavior if *serviceName != "" { // service name was specified, so use it as the dataset if cfg.Dataset != "" && !quiet { // warn if we're going to ignore a specified dataset fmt.Fprintf(os.Stderr, "WARN: service name was specified, dataset is ignored.\n") } trimmed := strings.TrimSpace(*serviceName) if trimmed != *serviceName && !quiet { fmt.Fprintf(os.Stderr, "WARN: service name contained leading or trailing whitespace, sending to '%s'.\n", trimmed) } cfg.Dataset = trimmed } else { // service_name was not specified if cfg.Dataset == "" { // neither was specified, so just use the default cfg.Dataset = "buildevents" } } } }, } root.PersistentFlags().StringVarP(&cfg.APIKey, "apikey", "k", "", "[env.BUILDEVENT_APIKEY] the Honeycomb authentication token") if apikey, ok := os.LookupEnv("BUILDEVENT_APIKEY"); ok { // https://github.com/spf13/viper/issues/461#issuecomment-366831834 root.PersistentFlags().Lookup("apikey").Value.Set(apikey) } root.PersistentFlags().StringVarP(&cfg.Dataset, "dataset", "d", "", "[env.BUILDEVENT_DATASET] the name of the Honeycomb dataset to which to send these events") if dataset, ok := os.LookupEnv("BUILDEVENT_DATASET"); ok { root.PersistentFlags().Lookup("dataset").Value.Set(dataset) } root.PersistentFlags().StringVarP(serviceName, "service_name", "n", "", "[env.BUILDEVENT_SERVICE_NAME] the name of the service to which to send these events; overrides dataset") if service_name, ok := os.LookupEnv("BUILDEVENT_SERVICE_NAME"); ok { root.PersistentFlags().Lookup("service_name").Value.Set(service_name) } root.PersistentFlags().StringVarP(&cfg.APIHost, "apihost", "a", "https://api.honeycomb.io", "[env.BUILDEVENT_APIHOST] the hostname for the Honeycomb API server to which to send this event") if apihost, ok := os.LookupEnv("BUILDEVENT_APIHOST"); ok { root.PersistentFlags().Lookup("apihost").Value.Set(apihost) } root.PersistentFlags().StringVarP(filename, "filename", "f", "", "[env.BUILDEVENT_FILE] the path of a text file holding arbitrary key=val pairs (multi-line-capable, logfmt style) to be added to the Honeycomb event") if fname, ok := os.LookupEnv("BUILDEVENT_FILE"); ok { root.PersistentFlags().Lookup("filename").Value.Set(fname) } root.PersistentFlags().StringVarP(ciProvider, "provider", "p", "", "[env.BUILDEVENT_CIPROVIDER] if unset, will inspect the environment to try to detect common CI providers.") prov := os.Getenv("BUILDEVENT_CIPROVIDER") if prov == "" { if _, present := os.LookupEnv("TRAVIS"); present { prov = providerTravis } else if _, present := os.LookupEnv("CIRCLECI"); present { prov = providerCircle } else if _, present := os.LookupEnv("GITLAB_CI"); present { prov = providerGitLab } else if _, present := os.LookupEnv("BUILDKITE"); present { prov = providerBuildkite } else if _, present := os.LookupEnv("JENKINS-X"); present { prov = providerJenkinsX } else if _, present := os.LookupEnv("GOOGLE-CLOUD-BUILD"); present { prov = providerGoogleCloudBuild } else if _, present := os.LookupEnv("TF_BUILD"); present { prov = providerAzurePipelines } else if _, present := os.LookupEnv("GITHUB_ACTIONS"); present { prov = providerGitHubActions } else if _, present := os.LookupEnv("BITBUCKET_BUILD_NUMBER"); present { prov = providerBitbucketPipelines } } if prov != "" { root.PersistentFlags().Lookup("provider").Value.Set(prov) } return root } ================================================ FILE: cmd_step.go ================================================ package main import ( "strings" "time" "github.com/spf13/cobra" libhoney "github.com/honeycombio/libhoney-go" ) func commandStep(cfg *libhoney.Config, filename *string, ciProvider *string) *cobra.Command { // STEP - eg: buildevents step $TRAVIS_BUILD_ID $STAGE_SPAN_ID $STAGE_START script stepCmd := &cobra.Command{ Use: "step [flags] BUILD_ID STEP_ID START_TIME NAME", Short: "Joins a collection of individual commands", Long: ` The step mode represents a block of related commands. In Travis-CI, this is one of "install", "before_script", "script", and so on. In CircleCI, this most closely maps to a single job. It should be run at the end of the step.`, Args: cobra.ExactArgs(4), DisableFlagsInUseLine: true, RunE: func(cmd *cobra.Command, args []string) error { traceID := strings.TrimSpace(args[0]) stepID := strings.TrimSpace(args[1]) startTime := parseUnix(strings.TrimSpace(args[2])) name := strings.TrimSpace(args[3]) ev := createEvent(cfg, *ciProvider, traceID) defer ev.Send() providerInfo(*ciProvider, ev) ev.Add(map[string]interface{}{ "trace.parent_id": traceID, "trace.span_id": stepID, "service_name": ifClassic(cfg, "step", cfg.Dataset), "service.name": ifClassic(cfg, "step", cfg.Dataset), "command_name": "step", "name": name, "duration_ms": time.Since(startTime) / time.Millisecond, "source": "buildevents", }) ev.Timestamp = startTime arbitraryFields(*filename, ev) return nil }, } return stepCmd } ================================================ FILE: cmd_watch.go ================================================ package main import ( "context" "fmt" "os" "sort" "strconv" "strings" "time" circleci "github.com/jszwedko/go-circleci" "github.com/spf13/cobra" libhoney "github.com/honeycombio/libhoney-go" ) // numChecks is the number of times to verify that we're finished before // declaring success in case we enter a transient state with blocked jobs that // really will start soon. This can be long - wait for up to 2 minutes (5sec * // 24 = 120sec). It's ok for this to be long because it only covers the time // when there are existing jobs that are not going to run. Most builds finish // with all jobs finishing, so this timer will not caused delayed builds in // those cases. const numChecks = 24 type watchConfig struct { timeoutMin int circleKey string workflowID string jobName string } func commandWatch(cfg *libhoney.Config, filename *string, ciProvider *string, wcfg *watchConfig) *cobra.Command { // WATCH eg: buildevents watch $TRAVIS_BUILD_ID watchCmd := &cobra.Command{ Use: "watch BUILD_ID", Short: "Polls the CircleCI API and waits until all jobs have finished.", Long: ` Polls the CircleCI API and waits until all jobs have finished (either succeeded, failed, or are blocked). It then reports the final status of the build with the appropriate timers.`, Args: cobra.MatchAll( cobra.ExactArgs(1), func(cmd *cobra.Command, args []string) error { if *ciProvider != providerCircle { return fmt.Errorf("watch command only valid for %s", providerCircle) } return nil }, ), RunE: func(cmd *cobra.Command, args []string) error { traceID := strings.TrimSpace(args[0]) ev := createEvent(cfg, *ciProvider, traceID) defer ev.Send() providerInfo(*ciProvider, ev) ok, startTime, endTime, jobsFailed, err := waitCircle(context.Background(), *wcfg) if err != nil { fmt.Printf("buildevents - Error detected: %s\n", err.Error()) return err } status := "failed" if ok { status = "success" } ev.Add(map[string]interface{}{ "service_name": ifClassic(cfg, "watch", cfg.Dataset), "service.name": ifClassic(cfg, "watch", cfg.Dataset), "command_name": "watch", "trace.span_id": traceID, "name": ifClassic(cfg, "watch "+traceID, "watch"), "status": status, "duration_ms": endTime.Sub(startTime) / time.Millisecond, "source": "buildevents", "jobs_failed": strings.Join(jobsFailed, ","), }) ev.Timestamp = startTime arbitraryFields(*filename, ev) // TODO: consider - move this until after the watch timeout?? url, err := buildURL(cfg, traceID, startTime.Unix()) if err != nil { fmt.Fprintf(os.Stderr, "Unable to create trace URL: %v\n", err) } else { fmt.Println(url) } return nil }, } watchCmd.Flags().IntVarP(&wcfg.timeoutMin, "timeout", "t", 10, "[env.BUILDEVENT_TIMEOUT] maximum time (in minutes) that watch should wait before timing out") if ts, ok := os.LookupEnv("BUILDEVENT_TIMEOUT"); ok { // This will end up ignoring non-integer values in the envvar if _, err := strconv.Atoi(ts); err == nil { watchCmd.Flags().Lookup("timeout").Value.Set(ts) } } watchCmd.Flags().StringVarP(&wcfg.circleKey, "circlekey", "c", "", "[env.BUILDEVENT_CIRCLE_API_TOKEN] CircleCI API token used for watching builds for private repositories") if tok, ok := os.LookupEnv("BUILDEVENT_CIRCLE_API_TOKEN"); ok { watchCmd.Flags().Lookup("circlekey").Value.Set(tok) } watchCmd.Flags().StringVarP(&wcfg.workflowID, "workflowid", "w", "", "[env.CIRCLE_WORKFLOW_ID] CircleCI identifier for the current workflow") if wfid, ok := os.LookupEnv("CIRCLE_WORKFLOW_ID"); ok { watchCmd.Flags().Lookup("workflowid").Value.Set(wfid) } watchCmd.Flags().StringVarP(&wcfg.jobName, "jobname", "j", "", "[env.CIRCLE_JOB] CircleCI identifier for the current job") if jnm, ok := os.LookupEnv("CIRCLE_JOB"); ok { watchCmd.Flags().Lookup("jobname").Value.Set(jnm) } return watchCmd } // waitCircle polls the CircleCI API checking for the status of this workflow // and the jobs it contains. It returns whether the workflow build succeeded, // the time it started, and the time it ended (which will be either nowish or // sometime in the past if we timed out). The err returned is for errors polling // the CircleCI API, not errors in the build itself. func waitCircle(parent context.Context, cfg watchConfig) (passed bool, started, ended time.Time, jobsFailed []string, err error) { // we need a token to query anything; give a helpful error if we have no token if cfg.circleKey == "" { return false, time.Now(), time.Now().Add(time.Second), nil, fmt.Errorf("circle token required to poll the API") } client := &circleci.Client{Token: cfg.circleKey} wf, err := client.GetWorkflowV2(cfg.workflowID) if err != nil { return false, time.Now(), time.Now().Add(time.Second), nil, err } started = wf.CreatedAt ended = time.Now() // set a default in case we early exit // set up cancellation timeout based on the configured timout duration done := make(chan struct{}) ctx, cxl := context.WithTimeout(parent, time.Duration(cfg.timeoutMin)*time.Minute) defer cxl() // sometimes there's a gap between when a job finishes and the next one starts. // In that case there are no jobs running and some jobs blocked that could // still run. If we think the build has passed and finished, let's give it a // buffer to spin up new jobs before really considering it done. This buffer // will check for up to 2 minutes checksLeft := numChecks + 1 // +1 because we decrement at the beginning of the loop go func() { defer close(done) tk := time.NewTicker(5 * time.Second).C for range tk { // check for timeout or pause before the next iteration select { case <-ctx.Done(): // TODO add the fact that it timed out to the trace to say why it failed fmt.Fprintf(os.Stderr, "Timeout reached waiting for the workflow to finish\n") ended = time.Now() return default: } resp, err := evalWorkflow(client, cfg.workflowID, cfg.jobName) if !resp.anyRunning { // if this is the first time we think we're finished store the timestamp if checksLeft >= numChecks { ended = time.Now() } if !resp.anyBlocked && err == nil { // we are legit done. passed = !resp.anyFailed if passed { fmt.Println("Build passed!") } else { fmt.Println("Build failed!") jobsFailed = resp.failedJobs } return } // ok, carry on checksLeft-- if checksLeft <= 0 { // we're done checking. passed = !resp.anyFailed if passed { fmt.Println("Build passed!") } else { fmt.Println("Build failed!") jobsFailed = resp.failedJobs } return } if err != nil { // we previously successfully queried for the workflow; this is likely a // transient error fmt.Printf("Querying the CirlceCI API failed with %s; trying %d more times before giving up.\n", err.Error(), checksLeft) continue } if resp.anyFailed { // don't bother rechecking if a job has failed fmt.Printf("Build failed!\n") jobsFailed = resp.failedJobs ended = time.Now() return } // yay looks like maybe we're done? fmt.Printf("Build appears finished; checking %d more times to make sure.\n", checksLeft) continue } // if we previously thought we were finished but now realize we weren't, // reset the check counter so we try 3 times again next time we think we're // finished. passed = false checksLeft = numChecks } }() <-done return passed, started, ended, jobsFailed, nil } type evalWorkflowResponse struct { anyRunning bool anyFailed bool anyBlocked bool failedJobs []string } // evalWorkflow looks at the CircleCI API for the list of jobs in this workflow // and decides whether the build has finished and if finished, whether it // failed. If an error is returned, it represents an error talking to the // CircleCI API, not an error with the workflow. func evalWorkflow(client *circleci.Client, wfID string, jobName string) (evalWorkflowResponse, error) { fmt.Printf("%s: polling for jobs: ", time.Now().Format(time.StampMilli)) wfJobs, err := getJobs(client, wfID) if err != nil { fmt.Printf("error polling: %s\n", err.Error()) return evalWorkflowResponse{ anyRunning: true, anyFailed: true, }, err } fmt.Println(summarizeJobList(wfJobs)) // defaults all to false resp := evalWorkflowResponse{} for _, job := range wfJobs { // skip ourself so we don't wait if we're the only job running if job.Name == jobName { continue } switch job.Status { case "success": // success means it finished and passed, don't keep track of it continue case "blocked": // blocked means it can't yet run, but that could be because either // it's waiting on a running job, depends on a failed job, or // it's not configured to run this build (because of a tag or something) resp.anyBlocked = true continue case "not_running": // not_running is the same as queued fallthrough case "queued": // queued means a job is due to start running soon, so we consider it running // already. resp.anyRunning = true case "failed": resp.anyFailed = true resp.failedJobs = append(resp.failedJobs, job.Name) continue case "running": resp.anyRunning = true } } return resp, nil } // getJobs queries the CircleCI API for a list of all jobs in the current workflow func getJobs(client *circleci.Client, wfID string) ([]*circleci.WorkflowJob, error) { // get the list of jobs, paging if necessary wfJobs, more, err := client.ListWorkflowV2Jobs(wfID, nil) if err != nil { return nil, err } for more != nil { // TODO only print this in debug mode fmt.Printf("getting more jobs! next page is %s\n", *more) var moreJobs []*circleci.WorkflowJob moreJobs, more, err = client.ListWorkflowV2Jobs(wfID, nil) if err != nil { return nil, err } wfJobs = append(wfJobs, moreJobs...) } return wfJobs, nil } // summarizeJobList takes a list of jobs and returns a string summary func summarizeJobList(wfJobs []*circleci.WorkflowJob) string { if len(wfJobs) == 0 { return "no jobs found" } // look at all the jobs and count how many are in each status state countByStatus := map[string]int{} for _, job := range wfJobs { countByStatus[job.Status]++ } // sort the statuses present to print them in a consistent order sortedStatusList := make([]string, 0, len(countByStatus)) for key := range countByStatus { sortedStatusList = append(sortedStatusList, key) } sort.Strings(sortedStatusList) // create a list of printable status counts statusStrings := make([]string, 0, len(countByStatus)) for i := 0; i < len(countByStatus); i++ { status := sortedStatusList[i] count := countByStatus[status] statusStrings = append(statusStrings, fmt.Sprintf("%d %s", count, status)) } // join the list of printable statuses to make one nice line return strings.Join(statusStrings, ", ") } ================================================ FILE: common.go ================================================ package main import ( "fmt" "io/ioutil" "net/url" "os" "path" "regexp" "runtime" "strconv" "strings" "time" "github.com/kr/logfmt" libhoney "github.com/honeycombio/libhoney-go" "github.com/honeycombio/libhoney-go/transmission" ) func createEvent(cfg *libhoney.Config, provider string, traceID string) *libhoney.Event { libhoney.UserAgentAddition = fmt.Sprintf("buildevents/%s", Version) if provider != "" { libhoney.UserAgentAddition += fmt.Sprintf(" (%s)", provider) } if cfg.APIKey == "" { cfg.Transmission = &transmission.WriterSender{} } libhoney.Init(*cfg) ev := libhoney.NewEvent() if provider != "" { ev.AddField("ci_provider", provider) } ev.AddField("trace.trace_id", traceID) ev.AddField("meta.version", Version) ev.AddField("meta.os", runtime.GOOS) ev.AddField("meta.arch", runtime.GOARCH) return ev } // providerInfo adds a bunch of fields to every span with useful information // about the build, gleaned from known providers func providerInfo(provider string, ev *libhoney.Event) { // envVars is a map of environment variable to event field name var envVars map[string]string switch strings.ToLower(provider) { case "circleci", "circle-ci", "circle": envVars = map[string]string{ "CIRCLE_BRANCH": "branch", "CIRCLE_BUILD_NUM": "build_num", "CIRCLE_BUILD_URL": "build_url", // overwrites buildevent_url+traceID "CIRCLE_JOB": "job_name", "CIRCLE_PR_NUMBER": "pr_number", "CIRCLE_PR_REPONAME": "pr_repo", "CIRCLE_PR_USER": "pr_user", "CIRCLE_REPOSITORY_URL": "repo", } case "travis-ci", "travisci", "travis": envVars = map[string]string{ "TRAVIS_BRANCH": "branch", "TRAVIS_BUILD_NUMBER": "build_num", "TRAVIS_BUILD_WEB_URL": "build_url", "TRAVIS_PULL_REQUEST": "pr_number", "TRAVIS_PULL_REQUEST_BRANCH": "pr_branch", "TRAVIS_PULL_REQUEST_SLUG": "pr_repo", "TRAVIS_REPO_SLUG": "repo", } case "gitlab-ci", "gitlabci", "gitlab": envVars = map[string]string{ "CI_COMMIT_REF_NAME": "branch", "CI_PIPELINE_ID": "build_num", "CI_PIPELINE_URL": "build_url", "CI_MERGE_REQUEST_ID": "pr_number", "CI_MERGE_REQUEST_SOURCE_BRANCH_NAME": "pr_branch", "CI_MERGE_REQUEST_SOURCE_PROJECT_PATH": "pr_repo", "CI_PROJECT_URL": "repo", } case "buildkite", "buildkiteci", "build-kite": envVars = map[string]string{ "BUILDKITE_BRANCH": "branch", "BUILDKITE_BUILD_NUMBER": "build_num", "BUILDKITE_BUILD_URL": "build_url", "BUILDKITE_PULL_REQUEST": "pr_number", "BUILDKITE_PULL_REQUEST_REPO": "pr_repo", "BUILDKITE_REPO": "repo", } case "jenkinsx", "jenkins-x": envVars = map[string]string{ "BRANCH_NAME": "branch", "BUILD_NUMBER": "build_num", "PULL_NUMBER": "pr_number", "REPO_NAME": "repo", } case "google-cloud-build", "cloud-build", "gcb": envVars = map[string]string{ "BRANCH_NAME": "branch", "BUILD_ID": "build_num", "HEAD_BRANCH": "pr_branch", "REPO_OWNER": "pr_user", "REPO_NAME": "repo", } case "azure-pipelines", "azure-devops", "vsts", "tfs": envVars = map[string]string{ "BUILD_SOURCEBRANCHNAME": "branch", "BUILD_BUILDID": "build_id", "BUILD_BUILDNUMBER": "build_number", "SYSTEM_JOBDISPLAYNAME": "job_name", "SYSTEM_STAGEDISPLAYNAME": "stage_name", "SYSTEM_PULLREQUEST_PULLREQUESTID": "pr_id", "SYSTEM_PULLREQUEST_PULLREQUESTNUMBER": "pr_number", "SYSTEM_PULLREQUEST_SOURCEBRANCH": "pr_branch", "BUILD_REQUESTEDFOR": "build_user", "BUILD_REPOSITORY_URI": "repo", } case "github-actions", "githubactions", "github", "gha-buildevents": envVars = map[string]string{ "GITHUB_REF": "branch", "GITHUB_RUN_ID": "build_num", "GITHUB_WORKFLOW": "workflow_name", "GITHUB_HEAD_REF": "pr_branch", "GITHUB_ACTOR": "pr_user", "GITHUB_REPOSITORY": "repo", } case "bitbucket-pipelines", "bitbucketpipelines", "bitbucket": envVars = map[string]string{ "BITBUCKET_BRANCH": "branch", "BITBUCKET_PIPELINE_UUID": "pipeline_id", "BITBUCKET_BUILD_NUMBER": "build_num", "BITBUCKET_REPO_FULL_NAME": "repo", "BITBUCKET_PR_ID": "pr_id", "BITBUCKET_STEP_TRIGGERER_UUID": "build_user", } } for envVar, fieldName := range envVars { if val, ok := os.LookupEnv(envVar); ok { ev.AddField(fieldName, val) } } } // arbitraryFields adds an arbitrary set of fields provided by the end user func arbitraryFields(loc string, ev *libhoney.Event) { if loc == "" { return } data, err := ioutil.ReadFile(loc) if err != nil { fmt.Fprintf(os.Stderr, "unable to read %q: %v\n", loc, err) return } err = logfmt.Unmarshal( data, logfmt.HandlerFunc(func(key, val []byte) error { if f, err := strconv.ParseFloat(string(val), 64); err == nil { ev.AddField(string(key), f) return nil } if b, err := strconv.ParseBool(string(val)); err == nil { ev.AddField(string(key), b) return nil } ev.AddField(string(key), string(val)) return nil }), ) if err != nil { fmt.Fprintf(os.Stderr, "problems loading from %q: %v\n", loc, err) } } // parseUnix reads the input text as a Unix timestamp (to the second) func parseUnix(ts string) time.Time { secondsSinceEpoch, _ := strconv.ParseInt(strings.TrimSpace(ts), 10, 64) unix := time.Unix(secondsSinceEpoch, 0) if unix == time.Unix(0, 0) { fmt.Fprintf(os.Stderr, "couldn't parse startTime of %q\n", ts) unix = time.Now() } return unix } // slugify turns a name into a slug. It is idempotent to things that are already slugs. func slugify(name string) string { slugReplaceRegex := regexp.MustCompile(`[^a-z0-9_~\.-]`) return slugReplaceRegex.ReplaceAllString(strings.ToLower(name), "-") } func buildURL(cfg *libhoney.Config, traceID string, ts int64) (string, error) { team, environment, err := libhoney.GetTeamAndEnvironment(*cfg) if err != nil { return "", fmt.Errorf("unable to verify API key: %w", err) } uiHost := strings.Replace(cfg.APIHost, "api", "ui", 1) u, err := url.Parse(uiHost) if err != nil { return "", fmt.Errorf("unable to infer UI host: %s", uiHost) } pathSegments := []string{team} if !cfg.IsClassic() { pathSegments = append(pathSegments, "environments", environment) } pathSegments = append(pathSegments, "datasets", slugify(cfg.Dataset), "trace") u.Path = path.Join(pathSegments...) endTime := time.Now().Add(10 * time.Minute).Unix() v := url.Values{} v.Set("trace_id", traceID) v.Set("trace_start_ts", strconv.FormatInt(ts, 10)) v.Set("trace_end_ts", strconv.FormatInt(endTime, 10)) u.RawQuery = v.Encode() return u.String(), nil } func ifClassic(cfg *libhoney.Config, classicVal, elseVal string) string { if cfg.IsClassic() { return classicVal } return elseVal } ================================================ FILE: common_test.go ================================================ package main import ( "net/http" "net/http/httptest" "strings" "testing" "time" "github.com/honeycombio/libhoney-go" "github.com/stretchr/testify/assert" ) func TestBuildUrl(t *testing.T) { testCases := []struct { Name string APIKey string Classic bool expectedUrl string }{ {Name: "classic", Classic: true, APIKey: "25f7d47575430a8fafea5b7d70a6af09", expectedUrl: "test_team/datasets/test_dataset/trace"}, {Name: "classic ingest key", Classic: true, APIKey: "hcaic_1234567890123456789012345678901234567890123456789012345678", expectedUrl: "test_team/datasets/test_dataset/trace"}, {Name: "non classic v2 configuration key", Classic: false, APIKey: "lcYrFflRUR6rHbIifwqhfG", expectedUrl: "test_team/environments/test_env/datasets/test_dataset/trace"}, {Name: "non classic ingest key", Classic: false, APIKey: "hcxik_01hqk4k20cjeh63wca8vva5stw70nft6m5n8wr8f5mjx3762s8269j50wc", expectedUrl: "test_team/environments/test_env/datasets/test_dataset/trace"}, } for _, tc := range testCases { t.Run(tc.Name, func(t *testing.T) { server := httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/1/auth", r.URL.Path) assert.Equal(t, []string{tc.APIKey}, r.Header["X-Honeycomb-Team"]) if tc.Classic { w.Write([]byte(`{"team":{"slug":"test_team"}}`)) } else { w.Write([]byte(`{"team":{"slug":"test_team"},"environment":{"slug":"test_env"}}`)) } }), ) defer server.Close() config := libhoney.Config{ APIKey: tc.APIKey, APIHost: server.URL, Dataset: "test_dataset", } url, err := buildURL(&config, "trace_id", time.Now().UTC().UnixNano()) assert.Nil(t, err) expectedUrl := server.URL + "/" + tc.expectedUrl assert.Equal(t, expectedUrl, url[:strings.IndexByte(url, '?')]) }) } } ================================================ FILE: go.mod ================================================ module github.com/honeycombio/buildevents go 1.23.0 toolchain go1.24.1 require ( github.com/honeycombio/beeline-go v1.19.0 github.com/honeycombio/libhoney-go v1.25.0 github.com/jszwedko/go-circleci v0.3.0 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 github.com/spf13/cobra v1.9.1 github.com/stretchr/testify v1.10.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect github.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01 // indirect github.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect gopkg.in/alexcesaro/statsd.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) replace github.com/jszwedko/go-circleci => github.com/maplebed/go-circleci v0.0.0-20191121000249-089ef54587e5 ================================================ FILE: go.sum ================================================ github.com/DataDog/zstd v1.5.6 h1:LbEglqepa/ipmmQJUDnSsfvA8e8IStVcGaFWDuxvGOY= github.com/DataDog/zstd v1.5.6/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01 h1:IeaD1VDVBPlx3viJT9Md8if8IxxJnO+x0JCGb054heg= github.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01/go.mod h1:ypD5nozFk9vcGw1ATYefw6jHe/jZP++Z15/+VTMcWhc= github.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52 h1:a4DFiKFJiDRGFD1qIcqGLX/WlUMD9dyLSLDt+9QZgt8= github.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52/go.mod h1:yIquW87NGRw1FU5p5lEkpnt/QxoH5uPAOUlOVkAUuMg= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/honeycombio/beeline-go v1.19.0 h1:FikgbX3PgivINs5kQHby6aVzhXZt6RtKvH6TGDSWV4c= github.com/honeycombio/beeline-go v1.19.0/go.mod h1:NsFeKTliw5xrG4s1/P3sOCaip+gcBYZktY5SuS4xKao= github.com/honeycombio/libhoney-go v1.25.0 h1:r33tlX90HtafK0bgRcjfNnsrJ9ZMTKuI/1DYaOFCc1o= github.com/honeycombio/libhoney-go v1.25.0/go.mod h1:Fc0HjqlwYf5xy6H34EItpOverAGbCixnYOX3YTUQovg= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/maplebed/go-circleci v0.0.0-20191121000249-089ef54587e5 h1:MkahNIXXDmLmqo3rHm8lS6OwiXSNHQdlrSAd/V9ywhc= github.com/maplebed/go-circleci v0.0.0-20191121000249-089ef54587e5/go.mod h1:OW/yiyLmpZqdbYUHRuFS83n1TpphzLe6sDFvOa8xX4w= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc= gopkg.in/alexcesaro/statsd.v2 v2.0.0/go.mod h1:i0ubccKGzBVNBpdGV5MocxyA/XlLUJzA7SLonnE4drU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= ================================================ FILE: main.go ================================================ package main import ( "errors" "os" "os/exec" libhoney "github.com/honeycombio/libhoney-go" ) // Version will be set by CircleCI based on a git tag and the commit hash var Version = "dev" const ( providerTravis = "Travis-CI" providerCircle = "CircleCI" providerGitLab = "GitLab-CI" providerBuildkite = "Buildkite" providerJenkinsX = "Jenkins-X" providerGoogleCloudBuild = "Google-Cloud-Build" providerAzurePipelines = "Azure-Pipelines" providerGitHubActions = "GitHub-Actions" providerBitbucketPipelines = "Bitbucket-Pipelines" ) func main() { defer libhoney.Close() var config libhoney.Config var filename string var ciProvider string var wcfg watchConfig var serviceName string root := commandRoot(&config, &filename, &ciProvider, &serviceName) // Put 'em all together root.AddCommand( commandBuild(&config, &filename, &ciProvider), commandStep(&config, &filename, &ciProvider), commandCmd(&config, &filename, &ciProvider), commandWatch(&config, &filename, &ciProvider, &wcfg), ) // Do the work if err := root.Execute(); err != nil { libhoney.Close() // If the underlying command returned a specific exit code, we need // to exit it with it as well to act transparently. var cmdErr *exec.ExitError if errors.As(err, &cmdErr) { os.Exit(cmdErr.ExitCode()) } os.Exit(1) } }