├── .github ├── dependabot.yml ├── release.yml └── workflows │ ├── ci.yml │ └── tagpr.yml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yml ├── .octocov.yml ├── .pinact.yaml ├── .tagpr ├── CHANGELOG.md ├── CREDITS ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── action.yml ├── cmd ├── gh-setup │ └── main.go └── root.go ├── gh-setup ├── gh ├── client.go ├── client_test.go ├── gh.go └── gh_test.go ├── go.mod ├── go.sum ├── scripts ├── entrypoint.sh ├── install-gh-setup.sh └── run-gh-setup.sh ├── setup ├── setup.go └── setup_test.go └── version └── version.go /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | groups: 7 | dependencies: 8 | patterns: 9 | - "*" 10 | schedule: 11 | interval: "weekly" 12 | time: "08:00" 13 | timezone: "Asia/Tokyo" 14 | commit-message: 15 | prefix: "chore" 16 | include: "scope" 17 | open-pull-requests-limit: 10 18 | assignees: 19 | - "k1LoW" 20 | 21 | - package-ecosystem: "gomod" 22 | directory: "/" 23 | groups: 24 | dependencies: 25 | patterns: 26 | - "*" 27 | schedule: 28 | interval: "weekly" 29 | time: "08:00" 30 | timezone: "Asia/Tokyo" 31 | commit-message: 32 | prefix: "chore" 33 | include: "scope" 34 | open-pull-requests-limit: 10 35 | assignees: 36 | - "k1LoW" 37 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - tagpr 5 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | jobs: 10 | job-test: 11 | name: Test 12 | runs-on: ubuntu-latest 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | steps: 16 | - name: Check out source code 17 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 21 | with: 22 | go-version-file: go.mod 23 | cache: true 24 | 25 | - name: Run lint 26 | uses: reviewdog/action-golangci-lint@f9bba13753278f6a73b27a56a3ffb1bfda90ed71 # v2.8.0 27 | with: 28 | fail_level: warning 29 | go_version_file: go.mod 30 | 31 | - name: Run tests 32 | run: make ci 33 | 34 | - name: Run octocov 35 | uses: k1LoW/octocov-action@73d561f65d59e66899ed5c87e4621a913b5d5c20 # v1.5.0 36 | 37 | job-run-test: 38 | name: Setup test 39 | strategy: 40 | matrix: 41 | os: [ubuntu-latest, windows-latest, macos-latest] 42 | runs-on: ${{ matrix.os }} 43 | env: 44 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 45 | DEBUG: true 46 | steps: 47 | - name: Check out source code 48 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 49 | 50 | - name: Set up Go 51 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 52 | with: 53 | go-version-file: go.mod 54 | cache: true 55 | 56 | - name: Run setup test 57 | run: | 58 | go run cmd/gh-setup/main.go --repo k1LoW/colr --version v1.1.1 --force 59 | colr -v 60 | shell: bash 61 | env: 62 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 63 | 64 | - name: Get latest version 65 | id: latest_version 66 | run: | 67 | echo -n 'version=' > $GITHUB_OUTPUT 68 | gh release list --exclude-drafts --exclude-pre-releases --limit 1 | cut -f 1 >> $GITHUB_OUTPUT 69 | cat $GITHUB_OUTPUT 70 | shell: bash 71 | 72 | - name: Run setup as a action (1/2) 73 | uses: ./ 74 | with: 75 | repo: k1LoW/tbls 76 | force: true 77 | strict: true 78 | gh-setup-version: ${{ steps.latest_version.outputs.version }} 79 | 80 | - name: Run setup as a action (2/2) 81 | run: tbls version 82 | shell: bash 83 | 84 | job-on-container-test: 85 | name: Test on container 86 | runs-on: ubuntu-latest 87 | container: 88 | image: debian:latest 89 | env: 90 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 91 | DEBUG: true 92 | steps: 93 | - name: Check out source code 94 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 95 | 96 | - name: Set up gh-setup 97 | uses: k1LoW/gh-setup@c72de7bc6800094e547b62cc0b690b5998dbe5fb # v1.11.1 98 | with: 99 | repo: cli/cli 100 | bin-match: bin/gh$ 101 | match: tar.gz$ 102 | 103 | - name: Get latest version 104 | id: latest_version 105 | run: | 106 | echo -n 'version=' > $GITHUB_OUTPUT 107 | gh release list --limit 1 | cut -f 1 >> $GITHUB_OUTPUT 108 | cat $GITHUB_OUTPUT 109 | 110 | - name: Run setup as a action (1/2) 111 | uses: ./ 112 | with: 113 | repo: k1LoW/tbls 114 | version: v1.84.0 115 | os: linux 116 | arch: amd64 117 | checksum: 83f35a07fd2a00c2aa360a47edca6d261f5208186911977eff39097151fc57d5 118 | force: true 119 | strict: true 120 | gh-setup-version: ${{ steps.latest_version.outputs.version }} 121 | 122 | - name: Run setup as a action (2/2) 123 | run: tbls version 124 | shell: bash 125 | -------------------------------------------------------------------------------- /.github/workflows/tagpr.yml: -------------------------------------------------------------------------------- 1 | name: tagpr 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | tagpr: 9 | runs-on: ubuntu-latest 10 | outputs: 11 | tagpr-tag: ${{ steps.run-tagpr.outputs.tag }} 12 | env: 13 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 14 | steps: 15 | - name: Check out source code 16 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 17 | 18 | - name: Set up Go 19 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 20 | with: 21 | go-version-file: go.mod 22 | cache: true 23 | 24 | - id: run-tagpr 25 | name: Run tagpr 26 | uses: Songmu/tagpr@812f0c28980cb9a1e5cf427b65c1ac6a1d2b4377 # v1.6.1 27 | 28 | - uses: haya14busa/action-update-semver@22a3666f9309f0d72ab0ea6c49b7a8019c1eab38 # v1.3.0 29 | if: "steps.run-tagpr.outputs.tag != ''" 30 | with: 31 | major_version_tag_only: true 32 | tag: ${{ steps.run-tagpr.outputs.tag }} 33 | 34 | assets: 35 | needs: tagpr 36 | if: needs.tagpr.outputs.tagpr-tag != '' 37 | runs-on: macos-latest 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | steps: 41 | - name: Check out source code 42 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 43 | with: 44 | fetch-depth: 0 45 | 46 | - name: Set up Go 47 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 48 | with: 49 | go-version-file: go.mod 50 | cache: true 51 | 52 | - name: Run GoReleaser 53 | uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 54 | with: 55 | distribution: goreleaser 56 | version: latest 57 | args: --clean 58 | env: 59 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 60 | 61 | dockerimage: 62 | needs: tagpr 63 | if: needs.tagpr.outputs.tagpr-tag != '' 64 | runs-on: ubuntu-latest 65 | env: 66 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 67 | steps: 68 | - name: Check out source code 69 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 70 | with: 71 | fetch-depth: 0 72 | 73 | - name: Get latest version 74 | id: latest_version 75 | run: | 76 | echo -n 'version=' > $GITHUB_OUTPUT 77 | gh release list --limit 1 | cut -f 1 >> $GITHUB_OUTPUT 78 | cat $GITHUB_OUTPUT 79 | 80 | - name: Set up QEMU 81 | uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 82 | 83 | - name: Set up Docker Buildx 84 | uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 85 | 86 | - name: Login to ghcr.io 87 | uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 88 | with: 89 | registry: ghcr.io 90 | username: ${{ github.actor }} 91 | password: ${{ secrets.GITHUB_TOKEN }} 92 | 93 | - name: Build and push 94 | uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0 95 | with: 96 | context: . 97 | file: Dockerfile 98 | platforms: linux/amd64,linux/arm64 99 | push: true 100 | tags: | 101 | ghcr.io/k1low/gh-setup:${{ steps.latest_version.outputs.version }} 102 | ghcr.io/k1low/gh-setup:latest 103 | labels: | 104 | org.opencontainers.image.name=gh-setup 105 | org.opencontainers.image.revision=${{ github.sha }} 106 | org.opencontainers.image.version=${{ steps.latest_version.outputs.version }} 107 | org.opencontainers.image.source=https://github.com/k1LoW/gh-setup 108 | 109 | release: 110 | needs: [tagpr, assets, dockerimage] 111 | runs-on: ubuntu-latest 112 | steps: 113 | - name: Release 114 | run: | 115 | gh api /repos/${{ github.repository }}/releases/generate-notes -f tag_name=${{ needs.tagpr.outputs.tagpr-tag }} --jq .body | gh release edit ${{ needs.tagpr.outputs.tagpr-tag }} --repo ${{ github.repository }} --draft=false --latest --notes-file=- 116 | env: 117 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 118 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | bin/ 3 | coverage.out 4 | ghsetup 5 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | run: 3 | timeout: 2m 4 | linters: 5 | enable: 6 | - godot 7 | - gosec 8 | - misspell 9 | - revive 10 | settings: 11 | errcheck: 12 | check-type-assertions: true 13 | misspell: 14 | locale: US 15 | revive: 16 | rules: 17 | - name: unexported-return 18 | disabled: true 19 | - name: exported 20 | disabled: false 21 | exclusions: 22 | generated: lax 23 | presets: 24 | - comments 25 | - common-false-positives 26 | - legacy 27 | - std-error-handling 28 | paths: 29 | - third_party$ 30 | - builtin$ 31 | - examples$ 32 | formatters: 33 | exclusions: 34 | generated: lax 35 | paths: 36 | - third_party$ 37 | - builtin$ 38 | - examples$ 39 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | before: 3 | hooks: 4 | - go mod download 5 | - go mod tidy 6 | builds: 7 | - 8 | id: gh-setup-linux 9 | env: 10 | - CGO_ENABLED=0 11 | goos: 12 | - linux 13 | goarch: 14 | - amd64 15 | - arm64 16 | main: ./cmd/gh-setup/main.go 17 | ldflags: 18 | - -s -w -X github.com/k1LoW/gh-setup.version={{.Version}} -X github.com/k1LoW/gh-setup.commit={{.FullCommit}} -X github.com/k1LoW/gh-setup.date={{.Date}} -X github.com/k1LoW/gh-setup/version.Version={{.Version}} 19 | - 20 | id: gh-setup-darwin 21 | env: 22 | - CGO_ENABLED=0 23 | goos: 24 | - darwin 25 | goarch: 26 | - amd64 27 | - arm64 28 | main: ./cmd/gh-setup/main.go 29 | ldflags: 30 | - -s -w -X github.com/k1LoW/gh-setup.version={{.Version}} -X github.com/k1LoW/gh-setup.commit={{.FullCommit}} -X github.com/k1LoW/gh-setup.date={{.Date}} -X github.com/k1LoW/gh-setup/version.Version={{.Version}} 31 | - 32 | id: gh-setup-windows 33 | env: 34 | - CGO_ENABLED=0 35 | goos: 36 | - windows 37 | goarch: 38 | - amd64 39 | main: ./cmd/gh-setup/main.go 40 | ldflags: 41 | - -s -w -X github.com/k1LoW/gh-setup.version={{.Version}} -X github.com/k1LoW/gh-setup.commit={{.FullCommit}} -X github.com/k1LoW/gh-setup.date={{.Date}} -X github.com/k1LoW/gh-setup/version.Version={{.Version}} 42 | archives: 43 | - 44 | id: gh-setup-archive 45 | name_template: '{{ .ProjectName }}_v{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' 46 | format_overrides: 47 | - goos: darwin 48 | formats: 49 | - zip 50 | files: 51 | - LICENSE 52 | - CREDITS 53 | - README.md 54 | - CHANGELOG.md 55 | - 56 | id: gh-setup-binary 57 | name_template: '{{ .Binary }}_v{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' 58 | formats: 59 | - binary 60 | checksum: 61 | name_template: 'checksums.txt' 62 | changelog: 63 | nfpms: 64 | - id: gh-setup-nfpms 65 | file_name_template: "{{ .ProjectName }}_{{ .Version }}-1_{{ .Arch }}" 66 | ids: 67 | - gh-setup-linux 68 | homepage: https://github.com/k1LoW/gh-setup 69 | maintainer: Ken'ichiro Oyama 70 | description: Setup asset of Github Releases. 71 | license: MIT 72 | formats: 73 | - apk 74 | - deb 75 | - rpm 76 | bindir: /usr/bin 77 | epoch: 1 78 | release: 79 | draft: true 80 | replace_existing_draft: true 81 | -------------------------------------------------------------------------------- /.octocov.yml: -------------------------------------------------------------------------------- 1 | # generated by octocov init 2 | coverage: 3 | if: true 4 | codeToTestRatio: 5 | code: 6 | - '**/*.go' 7 | - '!**/*_test.go' 8 | test: 9 | - '**/*_test.go' 10 | testExecutionTime: 11 | if: true 12 | diff: 13 | datastores: 14 | - artifact://${GITHUB_REPOSITORY} 15 | comment: 16 | if: is_pull_request 17 | summary: 18 | if: true 19 | report: 20 | if: is_default_branch 21 | datastores: 22 | - artifact://${GITHUB_REPOSITORY} 23 | -------------------------------------------------------------------------------- /.pinact.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/suzuki-shunsuke/pinact/refs/heads/main/json-schema/pinact.json 2 | # pinact - https://github.com/suzuki-shunsuke/pinact 3 | files: 4 | - pattern: "^\\.github/workflows/.*\\.ya?ml$" 5 | - pattern: "^(.*/)?action\\.ya?ml$" 6 | 7 | ignore_actions: 8 | # - name: actions/checkout 9 | # - name: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml 10 | -------------------------------------------------------------------------------- /.tagpr: -------------------------------------------------------------------------------- 1 | # config file for the tagpr in git config format 2 | # The tagpr generates the initial configuration, which you can rewrite to suit your environment. 3 | # CONFIGURATIONS: 4 | # tagpr.releaseBranch 5 | # Generally, it is "main." It is the branch for releases. The pcpr tracks this branch, 6 | # creates or updates a pull request as a release candidate, or tags when they are merged. 7 | # 8 | # tagpr.versionFile 9 | # Versioning file containing the semantic version needed to be updated at release. 10 | # It will be synchronized with the "git tag". 11 | # Often this is a meta-information file such as gemspec, setup.cfg, package.json, etc. 12 | # Sometimes the source code file, such as version.go or Bar.pm, is used. 13 | # If you do not want to use versioning files but only git tags, specify the "-" string here. 14 | # You can specify multiple version files by comma separated strings. 15 | # 16 | # tagpr.vPrefix 17 | # Flag whether or not v-prefix is added to semver when git tagging. (e.g. v1.2.3 if true) 18 | # This is only a tagging convention, not how it is described in the version file. 19 | # 20 | # tagpr.changelog (Optional) 21 | # Flag whether or not changelog is added or changed during the release. 22 | # 23 | # tagpr.command (Optional) 24 | # Command to change files just before release. 25 | # 26 | # tagpr.tmplate (Optional) 27 | # Pull request template in go template format 28 | # 29 | # tagpr.release (Optional) 30 | # GitHub Release creation behavior after tagging [true, draft, false] 31 | # If this value is not set, the release is to be created. 32 | [tagpr] 33 | vPrefix = true 34 | releaseBranch = main 35 | release = draft 36 | versionFile = version/version.go,action.yml 37 | command = "make prerelease_for_tagpr" 38 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v1.11.2](https://github.com/k1LoW/gh-setup/compare/v1.11.1...v1.11.2) - 2025-05-30 4 | - chore(deps): bump the dependencies group across 1 directory with 3 updates by @dependabot in https://github.com/k1LoW/gh-setup/pull/146 5 | - chore(deps): bump the dependencies group with 2 updates by @dependabot in https://github.com/k1LoW/gh-setup/pull/148 6 | - chore(deps): bump github.com/cli/go-gh/v2 from 2.12.0 to 2.12.1 by @dependabot in https://github.com/k1LoW/gh-setup/pull/149 7 | 8 | ## [v1.11.1](https://github.com/k1LoW/gh-setup/compare/v1.11.0...v1.11.1) - 2025-04-21 9 | - chore(deps): bump the dependencies group with 2 updates by @dependabot in https://github.com/k1LoW/gh-setup/pull/143 10 | - chore(deps): bump github.com/k1LoW/go-github-client/v67 from 67.0.16 to 67.0.17 in the dependencies group by @dependabot in https://github.com/k1LoW/gh-setup/pull/142 11 | 12 | ## [v1.11.0](https://github.com/k1LoW/gh-setup/compare/v1.10.2...v1.11.0) - 2025-04-17 13 | - chore(deps): bump the dependencies group with 2 updates by @dependabot in https://github.com/k1LoW/gh-setup/pull/139 14 | - Add attestation verification feature by @haya14busa in https://github.com/k1LoW/gh-setup/pull/141 15 | 16 | ## [v1.10.2](https://github.com/k1LoW/gh-setup/compare/v1.10.1...v1.10.2) - 2025-04-08 17 | - chore(deps): bump github.com/k1LoW/go-github-client/v67 from 67.0.13 to 67.0.16 in the dependencies group by @dependabot in https://github.com/k1LoW/gh-setup/pull/135 18 | - chore(deps): bump the dependencies group across 1 directory with 4 updates by @dependabot in https://github.com/k1LoW/gh-setup/pull/137 19 | - chore(deps): bump github.com/cli/go-gh/v2 from 2.11.2 to 2.12.0 in the dependencies group by @dependabot in https://github.com/k1LoW/gh-setup/pull/138 20 | 21 | ## [v1.10.1](https://github.com/k1LoW/gh-setup/compare/v1.10.0...v1.10.1) - 2025-03-22 22 | - chore(deps): bump github.com/golang-jwt/jwt/v4 from 4.5.1 to 4.5.2 by @dependabot in https://github.com/k1LoW/gh-setup/pull/132 23 | 24 | ## [v1.10.0](https://github.com/k1LoW/gh-setup/compare/v1.9.4...v1.10.0) - 2025-03-19 25 | - ci: update CI workflow to include checksum verification by @k1LoW in https://github.com/k1LoW/gh-setup/pull/130 26 | 27 | ## [v1.9.4](https://github.com/k1LoW/gh-setup/compare/v1.9.3...v1.9.4) - 2025-03-19 28 | - fix: correct checksum flag assignment and add checksum validation by @k1LoW in https://github.com/k1LoW/gh-setup/pull/128 29 | 30 | ## [v1.9.3](https://github.com/k1LoW/gh-setup/compare/v1.9.2...v1.9.3) - 2025-03-19 31 | - feat: add checksum verification for assets by @k1LoW in https://github.com/k1LoW/gh-setup/pull/125 32 | 33 | ## [v1.9.2](https://github.com/k1LoW/gh-setup/compare/v1.9.1...v1.9.2) - 2025-03-19 34 | - chore(deps): bump the dependencies group across 1 directory with 2 updates by @dependabot in https://github.com/k1LoW/gh-setup/pull/122 35 | - ci: pin dependencies by @k1LoW in https://github.com/k1LoW/gh-setup/pull/123 36 | 37 | ## [v1.9.1](https://github.com/k1LoW/gh-setup/compare/v1.9.0...v1.9.1) - 2025-02-13 38 | - chore(deps): bump the dependencies group with 3 updates by @dependabot in https://github.com/k1LoW/gh-setup/pull/119 39 | - chore(deps): bump the dependencies group with 6 updates by @dependabot in https://github.com/k1LoW/gh-setup/pull/120 40 | 41 | ## [v1.9.0](https://github.com/k1LoW/gh-setup/compare/v1.8.4...v1.9.0) - 2024-12-12 42 | - Bump github.com/golang-jwt/jwt/v4 from 4.5.0 to 4.5.1 by @dependabot in https://github.com/k1LoW/gh-setup/pull/112 43 | - Bump golang.org/x/crypto from 0.21.0 to 0.31.0 by @dependabot in https://github.com/k1LoW/gh-setup/pull/115 44 | - Update pkgs by @k1LoW in https://github.com/k1LoW/gh-setup/pull/116 45 | - Fix CI by @k1LoW in https://github.com/k1LoW/gh-setup/pull/117 46 | 47 | ## [v1.8.4](https://github.com/k1LoW/gh-setup/compare/v1.8.3...v1.8.4) - 2024-04-19 48 | - Bump google.golang.org/protobuf from 1.28.1 to 1.33.0 by @dependabot in https://github.com/k1LoW/gh-setup/pull/109 49 | - Bump golang.org/x/net from 0.17.0 to 0.23.0 by @dependabot in https://github.com/k1LoW/gh-setup/pull/111 50 | 51 | ## [v1.8.3](https://github.com/k1LoW/gh-setup/compare/v1.8.2...v1.8.3) - 2024-02-26 52 | - Support linux arm by @k1LoW in https://github.com/k1LoW/gh-setup/pull/108 53 | 54 | ## [v1.8.2](https://github.com/k1LoW/gh-setup/compare/v1.8.1...v1.8.2) - 2024-01-26 55 | - Bump golang.org/x/crypto from 0.14.0 to 0.17.0 by @dependabot in https://github.com/k1LoW/gh-setup/pull/102 56 | - Bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 by @dependabot in https://github.com/k1LoW/gh-setup/pull/104 57 | - Fix CD pipeline by @k1LoW in https://github.com/k1LoW/gh-setup/pull/105 58 | 59 | ## [v1.8.1](https://github.com/k1LoW/gh-setup/compare/v1.8.0...v1.8.1) - 2023-10-11 60 | - docs: add the installation guide with aqua by @suzuki-shunsuke in https://github.com/k1LoW/gh-setup/pull/99 61 | - Bump golang.org/x/net from 0.10.0 to 0.17.0 by @dependabot in https://github.com/k1LoW/gh-setup/pull/101 62 | 63 | ## [v1.8.0](https://github.com/k1LoW/gh-setup/compare/v1.7.0...v1.8.0) - 2023-07-28 64 | - Add `--skip-content-type-check` option for skipping check of content type of assets. by @k1LoW in https://github.com/k1LoW/gh-setup/pull/96 65 | - Support skip-content-type-check for Action by @k1LoW in https://github.com/k1LoW/gh-setup/pull/97 66 | 67 | ## [v1.7.0](https://github.com/k1LoW/gh-setup/compare/v1.6.0...v1.7.0) - 2023-07-11 68 | - Fix extension setup script by @k1LoW in https://github.com/k1LoW/gh-setup/pull/91 69 | - Support linux arm64 by @k1LoW in https://github.com/k1LoW/gh-setup/pull/93 70 | - Update pkgs and actions by @k1LoW in https://github.com/k1LoW/gh-setup/pull/94 71 | 72 | ## [v1.6.0](https://github.com/k1LoW/gh-setup/compare/v1.5.1...v1.6.0) - 2023-05-15 73 | - Freeze host of repo by @k1LoW in https://github.com/k1LoW/gh-setup/pull/87 74 | - Use `git tag` instead of `gh` by @k1LoW in https://github.com/k1LoW/gh-setup/pull/89 75 | - Bump github.com/cloudflare/circl from 1.1.0 to 1.3.3 by @dependabot in https://github.com/k1LoW/gh-setup/pull/90 76 | 77 | ## [v1.5.1](https://github.com/k1LoW/gh-setup/compare/v1.5.0...v1.5.1) - 2023-05-11 78 | - Need to test with authenticated clients. by @k1LoW in https://github.com/k1LoW/gh-setup/pull/85 79 | 80 | ## [v1.5.0](https://github.com/k1LoW/gh-setup/compare/v1.4.2...v1.5.0) - 2023-05-11 81 | - Update pkgs by @k1LoW in https://github.com/k1LoW/gh-setup/pull/83 82 | - Show sources by @k1LoW in https://github.com/k1LoW/gh-setup/pull/84 83 | 84 | ## [v1.4.2](https://github.com/k1LoW/gh-setup/compare/v1.4.1...v1.4.2) - 2023-05-10 85 | - Check response status by @k1LoW in https://github.com/k1LoW/gh-setup/pull/80 86 | 87 | ## [v1.4.1](https://github.com/k1LoW/gh-setup/compare/v1.4.0...v1.4.1) - 2023-05-10 88 | - Support application/x-gtar by @k1LoW in https://github.com/k1LoW/gh-setup/pull/77 89 | - Support env `ACTIONS_STEP_DEBUG` by @k1LoW in https://github.com/k1LoW/gh-setup/pull/79 90 | 91 | ## [v1.4.0](https://github.com/k1LoW/gh-setup/compare/v1.3.0...v1.4.0) - 2023-04-21 92 | - Support bzip2 by @k1LoW in https://github.com/k1LoW/gh-setup/pull/75 93 | 94 | ## [v1.3.0](https://github.com/k1LoW/gh-setup/compare/v1.2.2...v1.3.0) - 2023-03-27 95 | - Fix option handling ( `--match` / `--strict` ) by @k1LoW in https://github.com/k1LoW/gh-setup/pull/72 96 | - Fix `--match` score by @k1LoW in https://github.com/k1LoW/gh-setup/pull/73 97 | 98 | ## [v1.2.2](https://github.com/k1LoW/gh-setup/compare/v1.2.1...v1.2.2) - 2023-03-10 99 | - Update pkgs by @k1LoW in https://github.com/k1LoW/gh-setup/pull/70 100 | 101 | ## [v1.2.1](https://github.com/k1LoW/gh-setup/compare/v1.2.0...v1.2.1) - 2023-02-27 102 | - If curl command is not available, try to install by @k1LoW in https://github.com/k1LoW/gh-setup/pull/67 103 | 104 | ## [v1.2.0](https://github.com/k1LoW/gh-setup/compare/v1.1.4...v1.2.0) - 2023-02-27 105 | - Run gh-setup on container by @k1LoW in https://github.com/k1LoW/gh-setup/pull/65 106 | 107 | ## [v1.1.4](https://github.com/k1LoW/gh-setup/compare/v1.1.3...v1.1.4) - 2023-02-24 108 | - Update pkgs by @k1LoW in https://github.com/k1LoW/gh-setup/pull/63 109 | 110 | ## [v1.1.3](https://github.com/k1LoW/gh-setup/compare/v1.1.2...v1.1.3) - 2023-02-23 111 | - Fix README by @k2tzumi in https://github.com/k1LoW/gh-setup/pull/60 112 | - Add `--verbose` option by @k1LoW in https://github.com/k1LoW/gh-setup/pull/62 113 | 114 | ## [v1.1.2](https://github.com/k1LoW/gh-setup/compare/v1.1.1...v1.1.2) - 2023-02-18 115 | - Fix go.sum by @k1LoW in https://github.com/k1LoW/gh-setup/pull/58 116 | 117 | ## [v1.1.1](https://github.com/k1LoW/gh-setup/compare/v1.1.0...v1.1.1) - 2023-02-18 118 | - Update pkgs by @k1LoW in https://github.com/k1LoW/gh-setup/pull/56 119 | 120 | ## [v1.1.0](https://github.com/k1LoW/gh-setup/compare/v1.0.1...v1.1.0) - 2023-02-18 121 | - bump golang.org/x/net from 0.5.0 to 0.7.0 by @dependabot in https://github.com/k1LoW/gh-setup/pull/55 122 | - Fix GitHub client by @k1LoW in https://github.com/k1LoW/gh-setup/pull/54 123 | 124 | ## [v1.0.1](https://github.com/k1LoW/gh-setup/compare/v1.0.0...v1.0.1) - 2023-02-16 125 | - Fix checking token by @k1LoW in https://github.com/k1LoW/gh-setup/pull/52 126 | 127 | ## [v1.0.0](https://github.com/k1LoW/gh-setup/compare/v0.8.3...v1.0.0) - 2023-02-15 128 | - Bump up version number by @k1LoW in https://github.com/k1LoW/gh-setup/pull/49 129 | 130 | ## [v0.8.3](https://github.com/k1LoW/gh-setup/compare/v0.8.2...v0.8.3) - 2023-02-15 131 | - Support `--strict` in Action by @k1LoW in https://github.com/k1LoW/gh-setup/pull/47 132 | 133 | ## [v0.8.2](https://github.com/k1LoW/gh-setup/compare/v0.8.1...v0.8.2) - 2023-02-15 134 | - Add `--strict` for require strict match. by @k1LoW in https://github.com/k1LoW/gh-setup/pull/46 135 | 136 | ## [v0.8.1](https://github.com/k1LoW/gh-setup/compare/v0.8.0...v0.8.1) - 2023-02-14 137 | - Suppor `bin-match` for action.yml by @k1LoW in https://github.com/k1LoW/gh-setup/pull/43 138 | 139 | ## [v0.8.0](https://github.com/k1LoW/gh-setup/compare/v0.7.4...v0.8.0) - 2023-02-14 140 | - Fix match logic by @k1LoW in https://github.com/k1LoW/gh-setup/pull/41 141 | 142 | ## [v0.7.4](https://github.com/k1LoW/gh-setup/compare/v0.7.3...v0.7.4) - 2023-02-14 143 | 144 | ## [v0.7.3](https://github.com/k1LoW/gh-setup/compare/v0.7.2...v0.7.3) - 2023-02-14 145 | - Fix handling for `--version=latest` by @k1LoW in https://github.com/k1LoW/gh-setup/pull/38 146 | 147 | ## [v0.7.2](https://github.com/k1LoW/gh-setup/compare/v0.7.1...v0.7.2) - 2023-02-14 148 | - Set `${{ github.action_path }}` by @k1LoW in https://github.com/k1LoW/gh-setup/pull/36 149 | 150 | ## [v0.7.1](https://github.com/k1LoW/gh-setup/compare/v0.7.0...v0.7.1) - 2023-02-13 151 | - Fix detecting content-type of asset by @k1LoW in https://github.com/k1LoW/gh-setup/pull/35 152 | - Set log by @k1LoW in https://github.com/k1LoW/gh-setup/pull/34 153 | 154 | ## [v0.7.0](https://github.com/k1LoW/gh-setup/compare/v0.6.0...v0.7.0) - 2023-02-13 155 | - Support setup without credentials by @k1LoW in https://github.com/k1LoW/gh-setup/pull/31 156 | - Fix #31 by @k1LoW in https://github.com/k1LoW/gh-setup/pull/32 157 | 158 | ## [v0.6.0](https://github.com/k1LoW/gh-setup/compare/v0.5.1...v0.6.0) - 2023-02-13 159 | - Fix CI by @k1LoW in https://github.com/k1LoW/gh-setup/pull/28 160 | 161 | ## [v0.5.1](https://github.com/k1LoW/gh-setup/compare/v0.5.0...v0.5.1) - 2023-02-13 162 | - [BREAKING] Change API of version by @k1LoW in https://github.com/k1LoW/gh-setup/pull/26 163 | 164 | ## [v0.5.0](https://github.com/k1LoW/gh-setup/compare/v0.4.0...v0.5.0) - 2023-02-13 165 | - Fix README/CI by @k1LoW in https://github.com/k1LoW/gh-setup/pull/21 166 | - Support custom API host by @k1LoW in https://github.com/k1LoW/gh-setup/pull/23 167 | - Add ignoreBinnameKeywords by @k1LoW in https://github.com/k1LoW/gh-setup/pull/24 168 | - Fix detecting API endpoint by @k1LoW in https://github.com/k1LoW/gh-setup/pull/25 169 | 170 | ## [v0.4.0](https://github.com/k1LoW/gh-setup/compare/v0.3.0...v0.4.0) - 2023-02-12 171 | - Add `gh-setup-version:` by @k1LoW in https://github.com/k1LoW/gh-setup/pull/19 172 | 173 | ## [v0.3.0](https://github.com/k1LoW/gh-setup/compare/v0.2.0...v0.3.0) - 2023-02-12 174 | - Add `--match` option ( Fix repo ) by @k1LoW in https://github.com/k1LoW/gh-setup/pull/14 175 | - Add `match:` section for `--match` by @k1LoW in https://github.com/k1LoW/gh-setup/pull/17 176 | 177 | ## [v0.2.0](https://github.com/k1LoW/gh-setup/compare/v0.1.1...v0.2.0) - 2023-02-12 178 | - Update action.yml by @k1LoW in https://github.com/k1LoW/gh-setup/pull/9 179 | - Update README.md by @k1LoW in https://github.com/k1LoW/gh-setup/pull/10 180 | - Add `--match` option by @k1LoW in https://github.com/k1LoW/gh-setup/pull/12 181 | 182 | ## [v0.1.1](https://github.com/k1LoW/gh-setup/compare/v0.1.0...v0.1.1) - 2023-02-12 183 | 184 | ## [v0.1.0](https://github.com/k1LoW/gh-setup/compare/v0.0.3...v0.1.0) - 2023-02-12 185 | - Add isBinary by @k1LoW in https://github.com/k1LoW/gh-setup/pull/4 186 | - Add action.yml for Action by @k1LoW in https://github.com/k1LoW/gh-setup/pull/6 187 | - Add option `--release-version` `--os` `--arch` by @k1LoW in https://github.com/k1LoW/gh-setup/pull/7 188 | 189 | ## [v0.0.3](https://github.com/k1LoW/gh-setup/compare/v0.0.2...v0.0.3) - 2023-02-12 190 | 191 | ## [v0.0.2](https://github.com/k1LoW/gh-setup/compare/v0.0.1...v0.0.2) - 2023-02-12 192 | - Setup tagpr by @k1LoW in https://github.com/k1LoW/gh-setup/pull/1 193 | 194 | ## [v0.0.1](https://github.com/k1LoW/gh-setup/compare/3ad89381a358...v0.0.1) (2023-02-12) 195 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | Go (the standard library) 2 | https://golang.org/ 3 | ---------------------------------------------------------------- 4 | Copyright (c) 2009 The Go Authors. All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are 8 | met: 9 | 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above 13 | copyright notice, this list of conditions and the following disclaimer 14 | in the documentation and/or other materials provided with the 15 | distribution. 16 | * Neither the name of Google Inc. nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | ================================================================ 33 | 34 | github.com/MakeNowJust/heredoc 35 | https://github.com/MakeNowJust/heredoc 36 | ---------------------------------------------------------------- 37 | The MIT License (MIT) 38 | 39 | Copyright (c) 2014-2019 TSUYUSATO Kitsune 40 | 41 | Permission is hereby granted, free of charge, to any person obtaining a copy 42 | of this software and associated documentation files (the "Software"), to deal 43 | in the Software without restriction, including without limitation the rights 44 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 45 | copies of the Software, and to permit persons to whom the Software is 46 | furnished to do so, subject to the following conditions: 47 | 48 | The above copyright notice and this permission notice shall be included in 49 | all copies or substantial portions of the Software. 50 | 51 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 52 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 53 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 54 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 55 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 56 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 57 | THE SOFTWARE. 58 | 59 | ================================================================ 60 | 61 | github.com/cli/go-gh 62 | https://github.com/cli/go-gh 63 | ---------------------------------------------------------------- 64 | MIT License 65 | 66 | Copyright (c) 2021 GitHub Inc. 67 | 68 | Permission is hereby granted, free of charge, to any person obtaining a copy 69 | of this software and associated documentation files (the "Software"), to deal 70 | in the Software without restriction, including without limitation the rights 71 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 72 | copies of the Software, and to permit persons to whom the Software is 73 | furnished to do so, subject to the following conditions: 74 | 75 | The above copyright notice and this permission notice shall be included in all 76 | copies or substantial portions of the Software. 77 | 78 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 79 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 80 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 81 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 82 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 83 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 84 | SOFTWARE. 85 | 86 | ================================================================ 87 | 88 | github.com/cli/safeexec 89 | https://github.com/cli/safeexec 90 | ---------------------------------------------------------------- 91 | BSD 2-Clause License 92 | 93 | Copyright (c) 2020, GitHub Inc. 94 | All rights reserved. 95 | 96 | Redistribution and use in source and binary forms, with or without 97 | modification, are permitted provided that the following conditions are met: 98 | 99 | 1. Redistributions of source code must retain the above copyright notice, this 100 | list of conditions and the following disclaimer. 101 | 102 | 2. Redistributions in binary form must reproduce the above copyright notice, 103 | this list of conditions and the following disclaimer in the documentation 104 | and/or other materials provided with the distribution. 105 | 106 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 107 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 108 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 109 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 110 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 111 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 112 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 113 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 114 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 115 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 116 | 117 | ================================================================ 118 | 119 | github.com/cli/shurcooL-graphql 120 | https://github.com/cli/shurcooL-graphql 121 | ---------------------------------------------------------------- 122 | MIT License 123 | 124 | Copyright (c) 2017 Dmitri Shuralyov 125 | 126 | Permission is hereby granted, free of charge, to any person obtaining a copy 127 | of this software and associated documentation files (the "Software"), to deal 128 | in the Software without restriction, including without limitation the rights 129 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 130 | copies of the Software, and to permit persons to whom the Software is 131 | furnished to do so, subject to the following conditions: 132 | 133 | The above copyright notice and this permission notice shall be included in all 134 | copies or substantial portions of the Software. 135 | 136 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 137 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 138 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 139 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 140 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 141 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 142 | SOFTWARE. 143 | 144 | ================================================================ 145 | 146 | github.com/davecgh/go-spew 147 | https://github.com/davecgh/go-spew 148 | ---------------------------------------------------------------- 149 | ISC License 150 | 151 | Copyright (c) 2012-2016 Dave Collins 152 | 153 | Permission to use, copy, modify, and/or distribute this software for any 154 | purpose with or without fee is hereby granted, provided that the above 155 | copyright notice and this permission notice appear in all copies. 156 | 157 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 158 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 159 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 160 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 161 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 162 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 163 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 164 | 165 | ================================================================ 166 | 167 | github.com/golang/protobuf 168 | https://github.com/golang/protobuf 169 | ---------------------------------------------------------------- 170 | Copyright 2010 The Go Authors. All rights reserved. 171 | 172 | Redistribution and use in source and binary forms, with or without 173 | modification, are permitted provided that the following conditions are 174 | met: 175 | 176 | * Redistributions of source code must retain the above copyright 177 | notice, this list of conditions and the following disclaimer. 178 | * Redistributions in binary form must reproduce the above 179 | copyright notice, this list of conditions and the following disclaimer 180 | in the documentation and/or other materials provided with the 181 | distribution. 182 | * Neither the name of Google Inc. nor the names of its 183 | contributors may be used to endorse or promote products derived from 184 | this software without specific prior written permission. 185 | 186 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 187 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 189 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 190 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 191 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 192 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 193 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 194 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 195 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 196 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 197 | 198 | 199 | ================================================================ 200 | 201 | github.com/google/go-cmp 202 | https://github.com/google/go-cmp 203 | ---------------------------------------------------------------- 204 | Copyright (c) 2017 The Go Authors. All rights reserved. 205 | 206 | Redistribution and use in source and binary forms, with or without 207 | modification, are permitted provided that the following conditions are 208 | met: 209 | 210 | * Redistributions of source code must retain the above copyright 211 | notice, this list of conditions and the following disclaimer. 212 | * Redistributions in binary form must reproduce the above 213 | copyright notice, this list of conditions and the following disclaimer 214 | in the documentation and/or other materials provided with the 215 | distribution. 216 | * Neither the name of Google Inc. nor the names of its 217 | contributors may be used to endorse or promote products derived from 218 | this software without specific prior written permission. 219 | 220 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 221 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 222 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 223 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 224 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 225 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 227 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 228 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 229 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 230 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 231 | 232 | ================================================================ 233 | 234 | github.com/google/go-github/v50 235 | https://github.com/google/go-github/v50 236 | ---------------------------------------------------------------- 237 | Copyright (c) 2013 The go-github AUTHORS. All rights reserved. 238 | 239 | Redistribution and use in source and binary forms, with or without 240 | modification, are permitted provided that the following conditions are 241 | met: 242 | 243 | * Redistributions of source code must retain the above copyright 244 | notice, this list of conditions and the following disclaimer. 245 | * Redistributions in binary form must reproduce the above 246 | copyright notice, this list of conditions and the following disclaimer 247 | in the documentation and/or other materials provided with the 248 | distribution. 249 | * Neither the name of Google Inc. nor the names of its 250 | contributors may be used to endorse or promote products derived from 251 | this software without specific prior written permission. 252 | 253 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 254 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 255 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 256 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 257 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 258 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 259 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 260 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 261 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 264 | 265 | ================================================================ 266 | 267 | github.com/google/go-querystring 268 | https://github.com/google/go-querystring 269 | ---------------------------------------------------------------- 270 | Copyright (c) 2013 Google. All rights reserved. 271 | 272 | Redistribution and use in source and binary forms, with or without 273 | modification, are permitted provided that the following conditions are 274 | met: 275 | 276 | * Redistributions of source code must retain the above copyright 277 | notice, this list of conditions and the following disclaimer. 278 | * Redistributions in binary form must reproduce the above 279 | copyright notice, this list of conditions and the following disclaimer 280 | in the documentation and/or other materials provided with the 281 | distribution. 282 | * Neither the name of Google Inc. nor the names of its 283 | contributors may be used to endorse or promote products derived from 284 | this software without specific prior written permission. 285 | 286 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 287 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 288 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 289 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 290 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 291 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 292 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 293 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 294 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 295 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 296 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 297 | 298 | ================================================================ 299 | 300 | github.com/gorilla/mux 301 | https://github.com/gorilla/mux 302 | ---------------------------------------------------------------- 303 | Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved. 304 | 305 | Redistribution and use in source and binary forms, with or without 306 | modification, are permitted provided that the following conditions are 307 | met: 308 | 309 | * Redistributions of source code must retain the above copyright 310 | notice, this list of conditions and the following disclaimer. 311 | * Redistributions in binary form must reproduce the above 312 | copyright notice, this list of conditions and the following disclaimer 313 | in the documentation and/or other materials provided with the 314 | distribution. 315 | * Neither the name of Google Inc. nor the names of its 316 | contributors may be used to endorse or promote products derived from 317 | this software without specific prior written permission. 318 | 319 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 320 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 321 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 323 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 324 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 325 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 327 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 328 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 329 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 330 | 331 | ================================================================ 332 | 333 | github.com/h2non/parth 334 | https://github.com/h2non/parth 335 | ---------------------------------------------------------------- 336 | The MIT License (MIT) 337 | 338 | Copyright (c) 2018 codemodus 339 | 340 | Permission is hereby granted, free of charge, to any person obtaining a copy 341 | of this software and associated documentation files (the "Software"), to deal 342 | in the Software without restriction, including without limitation the rights 343 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 344 | copies of the Software, and to permit persons to whom the Software is 345 | furnished to do so, subject to the following conditions: 346 | 347 | The above copyright notice and this permission notice shall be included in all 348 | copies or substantial portions of the Software. 349 | 350 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 351 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 352 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 353 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 354 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 355 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 356 | SOFTWARE. 357 | 358 | 359 | ================================================================ 360 | 361 | github.com/henvic/httpretty 362 | https://github.com/henvic/httpretty 363 | ---------------------------------------------------------------- 364 | MIT License 365 | 366 | Copyright (c) 2020 Henrique Vicente 367 | 368 | Permission is hereby granted, free of charge, to any person obtaining a copy 369 | of this software and associated documentation files (the "Software"), to deal 370 | in the Software without restriction, including without limitation the rights 371 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 372 | copies of the Software, and to permit persons to whom the Software is 373 | furnished to do so, subject to the following conditions: 374 | 375 | The above copyright notice and this permission notice shall be included in all 376 | copies or substantial portions of the Software. 377 | 378 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 379 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 380 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 381 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 382 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 383 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 384 | SOFTWARE. 385 | 386 | ================================================================ 387 | 388 | github.com/inconshreveable/mousetrap 389 | https://github.com/inconshreveable/mousetrap 390 | ---------------------------------------------------------------- 391 | Apache License 392 | Version 2.0, January 2004 393 | http://www.apache.org/licenses/ 394 | 395 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 396 | 397 | 1. Definitions. 398 | 399 | "License" shall mean the terms and conditions for use, reproduction, 400 | and distribution as defined by Sections 1 through 9 of this document. 401 | 402 | "Licensor" shall mean the copyright owner or entity authorized by 403 | the copyright owner that is granting the License. 404 | 405 | "Legal Entity" shall mean the union of the acting entity and all 406 | other entities that control, are controlled by, or are under common 407 | control with that entity. For the purposes of this definition, 408 | "control" means (i) the power, direct or indirect, to cause the 409 | direction or management of such entity, whether by contract or 410 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 411 | outstanding shares, or (iii) beneficial ownership of such entity. 412 | 413 | "You" (or "Your") shall mean an individual or Legal Entity 414 | exercising permissions granted by this License. 415 | 416 | "Source" form shall mean the preferred form for making modifications, 417 | including but not limited to software source code, documentation 418 | source, and configuration files. 419 | 420 | "Object" form shall mean any form resulting from mechanical 421 | transformation or translation of a Source form, including but 422 | not limited to compiled object code, generated documentation, 423 | and conversions to other media types. 424 | 425 | "Work" shall mean the work of authorship, whether in Source or 426 | Object form, made available under the License, as indicated by a 427 | copyright notice that is included in or attached to the work 428 | (an example is provided in the Appendix below). 429 | 430 | "Derivative Works" shall mean any work, whether in Source or Object 431 | form, that is based on (or derived from) the Work and for which the 432 | editorial revisions, annotations, elaborations, or other modifications 433 | represent, as a whole, an original work of authorship. For the purposes 434 | of this License, Derivative Works shall not include works that remain 435 | separable from, or merely link (or bind by name) to the interfaces of, 436 | the Work and Derivative Works thereof. 437 | 438 | "Contribution" shall mean any work of authorship, including 439 | the original version of the Work and any modifications or additions 440 | to that Work or Derivative Works thereof, that is intentionally 441 | submitted to Licensor for inclusion in the Work by the copyright owner 442 | or by an individual or Legal Entity authorized to submit on behalf of 443 | the copyright owner. For the purposes of this definition, "submitted" 444 | means any form of electronic, verbal, or written communication sent 445 | to the Licensor or its representatives, including but not limited to 446 | communication on electronic mailing lists, source code control systems, 447 | and issue tracking systems that are managed by, or on behalf of, the 448 | Licensor for the purpose of discussing and improving the Work, but 449 | excluding communication that is conspicuously marked or otherwise 450 | designated in writing by the copyright owner as "Not a Contribution." 451 | 452 | "Contributor" shall mean Licensor and any individual or Legal Entity 453 | on behalf of whom a Contribution has been received by Licensor and 454 | subsequently incorporated within the Work. 455 | 456 | 2. Grant of Copyright License. Subject to the terms and conditions of 457 | this License, each Contributor hereby grants to You a perpetual, 458 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 459 | copyright license to reproduce, prepare Derivative Works of, 460 | publicly display, publicly perform, sublicense, and distribute the 461 | Work and such Derivative Works in Source or Object form. 462 | 463 | 3. Grant of Patent License. Subject to the terms and conditions of 464 | this License, each Contributor hereby grants to You a perpetual, 465 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 466 | (except as stated in this section) patent license to make, have made, 467 | use, offer to sell, sell, import, and otherwise transfer the Work, 468 | where such license applies only to those patent claims licensable 469 | by such Contributor that are necessarily infringed by their 470 | Contribution(s) alone or by combination of their Contribution(s) 471 | with the Work to which such Contribution(s) was submitted. If You 472 | institute patent litigation against any entity (including a 473 | cross-claim or counterclaim in a lawsuit) alleging that the Work 474 | or a Contribution incorporated within the Work constitutes direct 475 | or contributory patent infringement, then any patent licenses 476 | granted to You under this License for that Work shall terminate 477 | as of the date such litigation is filed. 478 | 479 | 4. Redistribution. You may reproduce and distribute copies of the 480 | Work or Derivative Works thereof in any medium, with or without 481 | modifications, and in Source or Object form, provided that You 482 | meet the following conditions: 483 | 484 | (a) You must give any other recipients of the Work or 485 | Derivative Works a copy of this License; and 486 | 487 | (b) You must cause any modified files to carry prominent notices 488 | stating that You changed the files; and 489 | 490 | (c) You must retain, in the Source form of any Derivative Works 491 | that You distribute, all copyright, patent, trademark, and 492 | attribution notices from the Source form of the Work, 493 | excluding those notices that do not pertain to any part of 494 | the Derivative Works; and 495 | 496 | (d) If the Work includes a "NOTICE" text file as part of its 497 | distribution, then any Derivative Works that You distribute must 498 | include a readable copy of the attribution notices contained 499 | within such NOTICE file, excluding those notices that do not 500 | pertain to any part of the Derivative Works, in at least one 501 | of the following places: within a NOTICE text file distributed 502 | as part of the Derivative Works; within the Source form or 503 | documentation, if provided along with the Derivative Works; or, 504 | within a display generated by the Derivative Works, if and 505 | wherever such third-party notices normally appear. The contents 506 | of the NOTICE file are for informational purposes only and 507 | do not modify the License. You may add Your own attribution 508 | notices within Derivative Works that You distribute, alongside 509 | or as an addendum to the NOTICE text from the Work, provided 510 | that such additional attribution notices cannot be construed 511 | as modifying the License. 512 | 513 | You may add Your own copyright statement to Your modifications and 514 | may provide additional or different license terms and conditions 515 | for use, reproduction, or distribution of Your modifications, or 516 | for any such Derivative Works as a whole, provided Your use, 517 | reproduction, and distribution of the Work otherwise complies with 518 | the conditions stated in this License. 519 | 520 | 5. Submission of Contributions. Unless You explicitly state otherwise, 521 | any Contribution intentionally submitted for inclusion in the Work 522 | by You to the Licensor shall be under the terms and conditions of 523 | this License, without any additional terms or conditions. 524 | Notwithstanding the above, nothing herein shall supersede or modify 525 | the terms of any separate license agreement you may have executed 526 | with Licensor regarding such Contributions. 527 | 528 | 6. Trademarks. This License does not grant permission to use the trade 529 | names, trademarks, service marks, or product names of the Licensor, 530 | except as required for reasonable and customary use in describing the 531 | origin of the Work and reproducing the content of the NOTICE file. 532 | 533 | 7. Disclaimer of Warranty. Unless required by applicable law or 534 | agreed to in writing, Licensor provides the Work (and each 535 | Contributor provides its Contributions) on an "AS IS" BASIS, 536 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 537 | implied, including, without limitation, any warranties or conditions 538 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 539 | PARTICULAR PURPOSE. You are solely responsible for determining the 540 | appropriateness of using or redistributing the Work and assume any 541 | risks associated with Your exercise of permissions under this License. 542 | 543 | 8. Limitation of Liability. In no event and under no legal theory, 544 | whether in tort (including negligence), contract, or otherwise, 545 | unless required by applicable law (such as deliberate and grossly 546 | negligent acts) or agreed to in writing, shall any Contributor be 547 | liable to You for damages, including any direct, indirect, special, 548 | incidental, or consequential damages of any character arising as a 549 | result of this License or out of the use or inability to use the 550 | Work (including but not limited to damages for loss of goodwill, 551 | work stoppage, computer failure or malfunction, or any and all 552 | other commercial damages or losses), even if such Contributor 553 | has been advised of the possibility of such damages. 554 | 555 | 9. Accepting Warranty or Additional Liability. While redistributing 556 | the Work or Derivative Works thereof, You may choose to offer, 557 | and charge a fee for, acceptance of support, warranty, indemnity, 558 | or other liability obligations and/or rights consistent with this 559 | License. However, in accepting such obligations, You may act only 560 | on Your own behalf and on Your sole responsibility, not on behalf 561 | of any other Contributor, and only if You agree to indemnify, 562 | defend, and hold each Contributor harmless for any liability 563 | incurred by, or claims asserted against, such Contributor by reason 564 | of your accepting any such warranty or additional liability. 565 | 566 | END OF TERMS AND CONDITIONS 567 | 568 | APPENDIX: How to apply the Apache License to your work. 569 | 570 | To apply the Apache License to your work, attach the following 571 | boilerplate notice, with the fields enclosed by brackets "[]" 572 | replaced with your own identifying information. (Don't include 573 | the brackets!) The text should be enclosed in the appropriate 574 | comment syntax for the file format. We also recommend that a 575 | file or class name and description of purpose be included on the 576 | same "printed page" as the copyright notice for easier 577 | identification within third-party archives. 578 | 579 | Copyright 2022 Alan Shreve (@inconshreveable) 580 | 581 | Licensed under the Apache License, Version 2.0 (the "License"); 582 | you may not use this file except in compliance with the License. 583 | You may obtain a copy of the License at 584 | 585 | http://www.apache.org/licenses/LICENSE-2.0 586 | 587 | Unless required by applicable law or agreed to in writing, software 588 | distributed under the License is distributed on an "AS IS" BASIS, 589 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 590 | See the License for the specific language governing permissions and 591 | limitations under the License. 592 | 593 | ================================================================ 594 | 595 | github.com/k1LoW/go-github-client/v50 596 | https://github.com/k1LoW/go-github-client/v50 597 | ---------------------------------------------------------------- 598 | The MIT License (MIT) 599 | 600 | Copyright © 2021 Ken'ichiro Oyama 601 | 602 | Permission is hereby granted, free of charge, to any person obtaining a copy 603 | of this software and associated documentation files (the "Software"), to deal 604 | in the Software without restriction, including without limitation the rights 605 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 606 | copies of the Software, and to permit persons to whom the Software is 607 | furnished to do so, subject to the following conditions: 608 | 609 | The above copyright notice and this permission notice shall be included in 610 | all copies or substantial portions of the Software. 611 | 612 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 613 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 614 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 615 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 616 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 617 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 618 | THE SOFTWARE. 619 | 620 | ================================================================ 621 | 622 | github.com/kr/pretty 623 | https://github.com/kr/pretty 624 | ---------------------------------------------------------------- 625 | The MIT License (MIT) 626 | 627 | Copyright 2012 Keith Rarick 628 | 629 | Permission is hereby granted, free of charge, to any person obtaining a copy 630 | of this software and associated documentation files (the "Software"), to deal 631 | in the Software without restriction, including without limitation the rights 632 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 633 | copies of the Software, and to permit persons to whom the Software is 634 | furnished to do so, subject to the following conditions: 635 | 636 | The above copyright notice and this permission notice shall be included in 637 | all copies or substantial portions of the Software. 638 | 639 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 640 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 641 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 642 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 643 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 644 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 645 | THE SOFTWARE. 646 | 647 | ================================================================ 648 | 649 | github.com/kr/text 650 | https://github.com/kr/text 651 | ---------------------------------------------------------------- 652 | Copyright 2012 Keith Rarick 653 | 654 | Permission is hereby granted, free of charge, to any person obtaining a copy 655 | of this software and associated documentation files (the "Software"), to deal 656 | in the Software without restriction, including without limitation the rights 657 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 658 | copies of the Software, and to permit persons to whom the Software is 659 | furnished to do so, subject to the following conditions: 660 | 661 | The above copyright notice and this permission notice shall be included in 662 | all copies or substantial portions of the Software. 663 | 664 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 665 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 666 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 667 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 668 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 669 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 670 | THE SOFTWARE. 671 | 672 | ================================================================ 673 | 674 | github.com/lucasb-eyer/go-colorful 675 | https://github.com/lucasb-eyer/go-colorful 676 | ---------------------------------------------------------------- 677 | Copyright (c) 2013 Lucas Beyer 678 | 679 | 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: 680 | 681 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 682 | 683 | 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. 684 | 685 | ================================================================ 686 | 687 | github.com/mattn/go-isatty 688 | https://github.com/mattn/go-isatty 689 | ---------------------------------------------------------------- 690 | Copyright (c) Yasuhiro MATSUMOTO 691 | 692 | MIT License (Expat) 693 | 694 | 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: 695 | 696 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 697 | 698 | 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. 699 | 700 | ================================================================ 701 | 702 | github.com/mattn/go-runewidth 703 | https://github.com/mattn/go-runewidth 704 | ---------------------------------------------------------------- 705 | The MIT License (MIT) 706 | 707 | Copyright (c) 2016 Yasuhiro Matsumoto 708 | 709 | Permission is hereby granted, free of charge, to any person obtaining a copy 710 | of this software and associated documentation files (the "Software"), to deal 711 | in the Software without restriction, including without limitation the rights 712 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 713 | copies of the Software, and to permit persons to whom the Software is 714 | furnished to do so, subject to the following conditions: 715 | 716 | The above copyright notice and this permission notice shall be included in all 717 | copies or substantial portions of the Software. 718 | 719 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 720 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 721 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 722 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 723 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 724 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 725 | SOFTWARE. 726 | 727 | ================================================================ 728 | 729 | github.com/migueleliasweb/go-github-mock 730 | https://github.com/migueleliasweb/go-github-mock 731 | ---------------------------------------------------------------- 732 | MIT License 733 | 734 | Copyright (c) 2021 Miguel Elias dos Santos 735 | 736 | Permission is hereby granted, free of charge, to any person obtaining a copy 737 | of this software and associated documentation files (the "Software"), to deal 738 | in the Software without restriction, including without limitation the rights 739 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 740 | copies of the Software, and to permit persons to whom the Software is 741 | furnished to do so, subject to the following conditions: 742 | 743 | The above copyright notice and this permission notice shall be included in all 744 | copies or substantial portions of the Software. 745 | 746 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 747 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 748 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 749 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 750 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 751 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 752 | SOFTWARE. 753 | 754 | ================================================================ 755 | 756 | github.com/muesli/reflow 757 | https://github.com/muesli/reflow 758 | ---------------------------------------------------------------- 759 | MIT License 760 | 761 | Copyright (c) 2019 Christian Muehlhaeuser 762 | 763 | Permission is hereby granted, free of charge, to any person obtaining a copy 764 | of this software and associated documentation files (the "Software"), to deal 765 | in the Software without restriction, including without limitation the rights 766 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 767 | copies of the Software, and to permit persons to whom the Software is 768 | furnished to do so, subject to the following conditions: 769 | 770 | The above copyright notice and this permission notice shall be included in all 771 | copies or substantial portions of the Software. 772 | 773 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 774 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 775 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 776 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 777 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 778 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 779 | SOFTWARE. 780 | 781 | ================================================================ 782 | 783 | github.com/muesli/termenv 784 | https://github.com/muesli/termenv 785 | ---------------------------------------------------------------- 786 | MIT License 787 | 788 | Copyright (c) 2019 Christian Muehlhaeuser 789 | 790 | Permission is hereby granted, free of charge, to any person obtaining a copy 791 | of this software and associated documentation files (the "Software"), to deal 792 | in the Software without restriction, including without limitation the rights 793 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 794 | copies of the Software, and to permit persons to whom the Software is 795 | furnished to do so, subject to the following conditions: 796 | 797 | The above copyright notice and this permission notice shall be included in all 798 | copies or substantial portions of the Software. 799 | 800 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 801 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 802 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 803 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 804 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 805 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 806 | SOFTWARE. 807 | 808 | ================================================================ 809 | 810 | github.com/nlepage/go-tarfs 811 | https://github.com/nlepage/go-tarfs 812 | ---------------------------------------------------------------- 813 | This is free and unencumbered software released into the public domain. 814 | 815 | Anyone is free to copy, modify, publish, use, compile, sell, or 816 | distribute this software, either in source code form or as a compiled 817 | binary, for any purpose, commercial or non-commercial, and by any 818 | means. 819 | 820 | In jurisdictions that recognize copyright laws, the author or authors 821 | of this software dedicate any and all copyright interest in the 822 | software to the public domain. We make this dedication for the benefit 823 | of the public at large and to the detriment of our heirs and 824 | successors. We intend this dedication to be an overt act of 825 | relinquishment in perpetuity of all present and future rights to this 826 | software under copyright law. 827 | 828 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 829 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 830 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 831 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 832 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 833 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 834 | OTHER DEALINGS IN THE SOFTWARE. 835 | 836 | For more information, please refer to 837 | 838 | ================================================================ 839 | 840 | github.com/pmezard/go-difflib 841 | https://github.com/pmezard/go-difflib 842 | ---------------------------------------------------------------- 843 | Copyright (c) 2013, Patrick Mezard 844 | All rights reserved. 845 | 846 | Redistribution and use in source and binary forms, with or without 847 | modification, are permitted provided that the following conditions are 848 | met: 849 | 850 | Redistributions of source code must retain the above copyright 851 | notice, this list of conditions and the following disclaimer. 852 | Redistributions in binary form must reproduce the above copyright 853 | notice, this list of conditions and the following disclaimer in the 854 | documentation and/or other materials provided with the distribution. 855 | The names of its contributors may not be used to endorse or promote 856 | products derived from this software without specific prior written 857 | permission. 858 | 859 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 860 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 861 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 862 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 863 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 864 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 865 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 866 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 867 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 868 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 869 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 870 | 871 | ================================================================ 872 | 873 | github.com/rivo/uniseg 874 | https://github.com/rivo/uniseg 875 | ---------------------------------------------------------------- 876 | MIT License 877 | 878 | Copyright (c) 2019 Oliver Kuederle 879 | 880 | Permission is hereby granted, free of charge, to any person obtaining a copy 881 | of this software and associated documentation files (the "Software"), to deal 882 | in the Software without restriction, including without limitation the rights 883 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 884 | copies of the Software, and to permit persons to whom the Software is 885 | furnished to do so, subject to the following conditions: 886 | 887 | The above copyright notice and this permission notice shall be included in all 888 | copies or substantial portions of the Software. 889 | 890 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 891 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 892 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 893 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 894 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 895 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 896 | SOFTWARE. 897 | 898 | ================================================================ 899 | 900 | github.com/shurcooL/githubv4 901 | https://github.com/shurcooL/githubv4 902 | ---------------------------------------------------------------- 903 | MIT License 904 | 905 | Copyright (c) 2017 Dmitri Shuralyov 906 | 907 | Permission is hereby granted, free of charge, to any person obtaining a copy 908 | of this software and associated documentation files (the "Software"), to deal 909 | in the Software without restriction, including without limitation the rights 910 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 911 | copies of the Software, and to permit persons to whom the Software is 912 | furnished to do so, subject to the following conditions: 913 | 914 | The above copyright notice and this permission notice shall be included in all 915 | copies or substantial portions of the Software. 916 | 917 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 918 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 919 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 920 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 921 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 922 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 923 | SOFTWARE. 924 | 925 | ================================================================ 926 | 927 | github.com/shurcooL/graphql 928 | https://github.com/shurcooL/graphql 929 | ---------------------------------------------------------------- 930 | MIT License 931 | 932 | Copyright (c) 2017 Dmitri Shuralyov 933 | 934 | Permission is hereby granted, free of charge, to any person obtaining a copy 935 | of this software and associated documentation files (the "Software"), to deal 936 | in the Software without restriction, including without limitation the rights 937 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 938 | copies of the Software, and to permit persons to whom the Software is 939 | furnished to do so, subject to the following conditions: 940 | 941 | The above copyright notice and this permission notice shall be included in all 942 | copies or substantial portions of the Software. 943 | 944 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 945 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 946 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 947 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 948 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 949 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 950 | SOFTWARE. 951 | 952 | ================================================================ 953 | 954 | github.com/spf13/cobra 955 | https://github.com/spf13/cobra 956 | ---------------------------------------------------------------- 957 | Apache License 958 | Version 2.0, January 2004 959 | http://www.apache.org/licenses/ 960 | 961 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 962 | 963 | 1. Definitions. 964 | 965 | "License" shall mean the terms and conditions for use, reproduction, 966 | and distribution as defined by Sections 1 through 9 of this document. 967 | 968 | "Licensor" shall mean the copyright owner or entity authorized by 969 | the copyright owner that is granting the License. 970 | 971 | "Legal Entity" shall mean the union of the acting entity and all 972 | other entities that control, are controlled by, or are under common 973 | control with that entity. For the purposes of this definition, 974 | "control" means (i) the power, direct or indirect, to cause the 975 | direction or management of such entity, whether by contract or 976 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 977 | outstanding shares, or (iii) beneficial ownership of such entity. 978 | 979 | "You" (or "Your") shall mean an individual or Legal Entity 980 | exercising permissions granted by this License. 981 | 982 | "Source" form shall mean the preferred form for making modifications, 983 | including but not limited to software source code, documentation 984 | source, and configuration files. 985 | 986 | "Object" form shall mean any form resulting from mechanical 987 | transformation or translation of a Source form, including but 988 | not limited to compiled object code, generated documentation, 989 | and conversions to other media types. 990 | 991 | "Work" shall mean the work of authorship, whether in Source or 992 | Object form, made available under the License, as indicated by a 993 | copyright notice that is included in or attached to the work 994 | (an example is provided in the Appendix below). 995 | 996 | "Derivative Works" shall mean any work, whether in Source or Object 997 | form, that is based on (or derived from) the Work and for which the 998 | editorial revisions, annotations, elaborations, or other modifications 999 | represent, as a whole, an original work of authorship. For the purposes 1000 | of this License, Derivative Works shall not include works that remain 1001 | separable from, or merely link (or bind by name) to the interfaces of, 1002 | the Work and Derivative Works thereof. 1003 | 1004 | "Contribution" shall mean any work of authorship, including 1005 | the original version of the Work and any modifications or additions 1006 | to that Work or Derivative Works thereof, that is intentionally 1007 | submitted to Licensor for inclusion in the Work by the copyright owner 1008 | or by an individual or Legal Entity authorized to submit on behalf of 1009 | the copyright owner. For the purposes of this definition, "submitted" 1010 | means any form of electronic, verbal, or written communication sent 1011 | to the Licensor or its representatives, including but not limited to 1012 | communication on electronic mailing lists, source code control systems, 1013 | and issue tracking systems that are managed by, or on behalf of, the 1014 | Licensor for the purpose of discussing and improving the Work, but 1015 | excluding communication that is conspicuously marked or otherwise 1016 | designated in writing by the copyright owner as "Not a Contribution." 1017 | 1018 | "Contributor" shall mean Licensor and any individual or Legal Entity 1019 | on behalf of whom a Contribution has been received by Licensor and 1020 | subsequently incorporated within the Work. 1021 | 1022 | 2. Grant of Copyright License. Subject to the terms and conditions of 1023 | this License, each Contributor hereby grants to You a perpetual, 1024 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 1025 | copyright license to reproduce, prepare Derivative Works of, 1026 | publicly display, publicly perform, sublicense, and distribute the 1027 | Work and such Derivative Works in Source or Object form. 1028 | 1029 | 3. Grant of Patent License. Subject to the terms and conditions of 1030 | this License, each Contributor hereby grants to You a perpetual, 1031 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 1032 | (except as stated in this section) patent license to make, have made, 1033 | use, offer to sell, sell, import, and otherwise transfer the Work, 1034 | where such license applies only to those patent claims licensable 1035 | by such Contributor that are necessarily infringed by their 1036 | Contribution(s) alone or by combination of their Contribution(s) 1037 | with the Work to which such Contribution(s) was submitted. If You 1038 | institute patent litigation against any entity (including a 1039 | cross-claim or counterclaim in a lawsuit) alleging that the Work 1040 | or a Contribution incorporated within the Work constitutes direct 1041 | or contributory patent infringement, then any patent licenses 1042 | granted to You under this License for that Work shall terminate 1043 | as of the date such litigation is filed. 1044 | 1045 | 4. Redistribution. You may reproduce and distribute copies of the 1046 | Work or Derivative Works thereof in any medium, with or without 1047 | modifications, and in Source or Object form, provided that You 1048 | meet the following conditions: 1049 | 1050 | (a) You must give any other recipients of the Work or 1051 | Derivative Works a copy of this License; and 1052 | 1053 | (b) You must cause any modified files to carry prominent notices 1054 | stating that You changed the files; and 1055 | 1056 | (c) You must retain, in the Source form of any Derivative Works 1057 | that You distribute, all copyright, patent, trademark, and 1058 | attribution notices from the Source form of the Work, 1059 | excluding those notices that do not pertain to any part of 1060 | the Derivative Works; and 1061 | 1062 | (d) If the Work includes a "NOTICE" text file as part of its 1063 | distribution, then any Derivative Works that You distribute must 1064 | include a readable copy of the attribution notices contained 1065 | within such NOTICE file, excluding those notices that do not 1066 | pertain to any part of the Derivative Works, in at least one 1067 | of the following places: within a NOTICE text file distributed 1068 | as part of the Derivative Works; within the Source form or 1069 | documentation, if provided along with the Derivative Works; or, 1070 | within a display generated by the Derivative Works, if and 1071 | wherever such third-party notices normally appear. The contents 1072 | of the NOTICE file are for informational purposes only and 1073 | do not modify the License. You may add Your own attribution 1074 | notices within Derivative Works that You distribute, alongside 1075 | or as an addendum to the NOTICE text from the Work, provided 1076 | that such additional attribution notices cannot be construed 1077 | as modifying the License. 1078 | 1079 | You may add Your own copyright statement to Your modifications and 1080 | may provide additional or different license terms and conditions 1081 | for use, reproduction, or distribution of Your modifications, or 1082 | for any such Derivative Works as a whole, provided Your use, 1083 | reproduction, and distribution of the Work otherwise complies with 1084 | the conditions stated in this License. 1085 | 1086 | 5. Submission of Contributions. Unless You explicitly state otherwise, 1087 | any Contribution intentionally submitted for inclusion in the Work 1088 | by You to the Licensor shall be under the terms and conditions of 1089 | this License, without any additional terms or conditions. 1090 | Notwithstanding the above, nothing herein shall supersede or modify 1091 | the terms of any separate license agreement you may have executed 1092 | with Licensor regarding such Contributions. 1093 | 1094 | 6. Trademarks. This License does not grant permission to use the trade 1095 | names, trademarks, service marks, or product names of the Licensor, 1096 | except as required for reasonable and customary use in describing the 1097 | origin of the Work and reproducing the content of the NOTICE file. 1098 | 1099 | 7. Disclaimer of Warranty. Unless required by applicable law or 1100 | agreed to in writing, Licensor provides the Work (and each 1101 | Contributor provides its Contributions) on an "AS IS" BASIS, 1102 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1103 | implied, including, without limitation, any warranties or conditions 1104 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 1105 | PARTICULAR PURPOSE. You are solely responsible for determining the 1106 | appropriateness of using or redistributing the Work and assume any 1107 | risks associated with Your exercise of permissions under this License. 1108 | 1109 | 8. Limitation of Liability. In no event and under no legal theory, 1110 | whether in tort (including negligence), contract, or otherwise, 1111 | unless required by applicable law (such as deliberate and grossly 1112 | negligent acts) or agreed to in writing, shall any Contributor be 1113 | liable to You for damages, including any direct, indirect, special, 1114 | incidental, or consequential damages of any character arising as a 1115 | result of this License or out of the use or inability to use the 1116 | Work (including but not limited to damages for loss of goodwill, 1117 | work stoppage, computer failure or malfunction, or any and all 1118 | other commercial damages or losses), even if such Contributor 1119 | has been advised of the possibility of such damages. 1120 | 1121 | 9. Accepting Warranty or Additional Liability. While redistributing 1122 | the Work or Derivative Works thereof, You may choose to offer, 1123 | and charge a fee for, acceptance of support, warranty, indemnity, 1124 | or other liability obligations and/or rights consistent with this 1125 | License. However, in accepting such obligations, You may act only 1126 | on Your own behalf and on Your sole responsibility, not on behalf 1127 | of any other Contributor, and only if You agree to indemnify, 1128 | defend, and hold each Contributor harmless for any liability 1129 | incurred by, or claims asserted against, such Contributor by reason 1130 | of your accepting any such warranty or additional liability. 1131 | 1132 | ================================================================ 1133 | 1134 | github.com/spf13/pflag 1135 | https://github.com/spf13/pflag 1136 | ---------------------------------------------------------------- 1137 | Copyright (c) 2012 Alex Ogier. All rights reserved. 1138 | Copyright (c) 2012 The Go Authors. All rights reserved. 1139 | 1140 | Redistribution and use in source and binary forms, with or without 1141 | modification, are permitted provided that the following conditions are 1142 | met: 1143 | 1144 | * Redistributions of source code must retain the above copyright 1145 | notice, this list of conditions and the following disclaimer. 1146 | * Redistributions in binary form must reproduce the above 1147 | copyright notice, this list of conditions and the following disclaimer 1148 | in the documentation and/or other materials provided with the 1149 | distribution. 1150 | * Neither the name of Google Inc. nor the names of its 1151 | contributors may be used to endorse or promote products derived from 1152 | this software without specific prior written permission. 1153 | 1154 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1155 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1156 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1157 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1158 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1159 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1160 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1161 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1162 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1163 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1164 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1165 | 1166 | ================================================================ 1167 | 1168 | github.com/stretchr/testify 1169 | https://github.com/stretchr/testify 1170 | ---------------------------------------------------------------- 1171 | MIT License 1172 | 1173 | Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors. 1174 | 1175 | Permission is hereby granted, free of charge, to any person obtaining a copy 1176 | of this software and associated documentation files (the "Software"), to deal 1177 | in the Software without restriction, including without limitation the rights 1178 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1179 | copies of the Software, and to permit persons to whom the Software is 1180 | furnished to do so, subject to the following conditions: 1181 | 1182 | The above copyright notice and this permission notice shall be included in all 1183 | copies or substantial portions of the Software. 1184 | 1185 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1186 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1187 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1188 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1189 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1190 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1191 | SOFTWARE. 1192 | 1193 | ================================================================ 1194 | 1195 | github.com/thlib/go-timezone-local 1196 | https://github.com/thlib/go-timezone-local 1197 | ---------------------------------------------------------------- 1198 | This is free and unencumbered software released into the public domain. 1199 | 1200 | Anyone is free to copy, modify, publish, use, compile, sell, or 1201 | distribute this software, either in source code form or as a compiled 1202 | binary, for any purpose, commercial or non-commercial, and by any 1203 | means. 1204 | 1205 | In jurisdictions that recognize copyright laws, the author or authors 1206 | of this software dedicate any and all copyright interest in the 1207 | software to the public domain. We make this dedication for the benefit 1208 | of the public at large and to the detriment of our heirs and 1209 | successors. We intend this dedication to be an overt act of 1210 | relinquishment in perpetuity of all present and future rights to this 1211 | software under copyright law. 1212 | 1213 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1214 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1215 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1216 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 1217 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1218 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 1219 | OTHER DEALINGS IN THE SOFTWARE. 1220 | 1221 | For more information, please refer to 1222 | 1223 | ================================================================ 1224 | 1225 | golang.org/x/crypto 1226 | https://golang.org/x/crypto 1227 | ---------------------------------------------------------------- 1228 | Copyright (c) 2009 The Go Authors. All rights reserved. 1229 | 1230 | Redistribution and use in source and binary forms, with or without 1231 | modification, are permitted provided that the following conditions are 1232 | met: 1233 | 1234 | * Redistributions of source code must retain the above copyright 1235 | notice, this list of conditions and the following disclaimer. 1236 | * Redistributions in binary form must reproduce the above 1237 | copyright notice, this list of conditions and the following disclaimer 1238 | in the documentation and/or other materials provided with the 1239 | distribution. 1240 | * Neither the name of Google Inc. nor the names of its 1241 | contributors may be used to endorse or promote products derived from 1242 | this software without specific prior written permission. 1243 | 1244 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1245 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1246 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1247 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1248 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1249 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1250 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1251 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1252 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1253 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1254 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1255 | 1256 | ================================================================ 1257 | 1258 | golang.org/x/net 1259 | https://golang.org/x/net 1260 | ---------------------------------------------------------------- 1261 | Copyright (c) 2009 The Go Authors. All rights reserved. 1262 | 1263 | Redistribution and use in source and binary forms, with or without 1264 | modification, are permitted provided that the following conditions are 1265 | met: 1266 | 1267 | * Redistributions of source code must retain the above copyright 1268 | notice, this list of conditions and the following disclaimer. 1269 | * Redistributions in binary form must reproduce the above 1270 | copyright notice, this list of conditions and the following disclaimer 1271 | in the documentation and/or other materials provided with the 1272 | distribution. 1273 | * Neither the name of Google Inc. nor the names of its 1274 | contributors may be used to endorse or promote products derived from 1275 | this software without specific prior written permission. 1276 | 1277 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1278 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1279 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1280 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1281 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1282 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1283 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1284 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1285 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1286 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1287 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1288 | 1289 | ================================================================ 1290 | 1291 | golang.org/x/oauth2 1292 | https://golang.org/x/oauth2 1293 | ---------------------------------------------------------------- 1294 | Copyright (c) 2009 The Go Authors. All rights reserved. 1295 | 1296 | Redistribution and use in source and binary forms, with or without 1297 | modification, are permitted provided that the following conditions are 1298 | met: 1299 | 1300 | * Redistributions of source code must retain the above copyright 1301 | notice, this list of conditions and the following disclaimer. 1302 | * Redistributions in binary form must reproduce the above 1303 | copyright notice, this list of conditions and the following disclaimer 1304 | in the documentation and/or other materials provided with the 1305 | distribution. 1306 | * Neither the name of Google Inc. nor the names of its 1307 | contributors may be used to endorse or promote products derived from 1308 | this software without specific prior written permission. 1309 | 1310 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1311 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1312 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1313 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1314 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1315 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1316 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1317 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1318 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1319 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1320 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1321 | 1322 | ================================================================ 1323 | 1324 | golang.org/x/sys 1325 | https://golang.org/x/sys 1326 | ---------------------------------------------------------------- 1327 | Copyright (c) 2009 The Go Authors. All rights reserved. 1328 | 1329 | Redistribution and use in source and binary forms, with or without 1330 | modification, are permitted provided that the following conditions are 1331 | met: 1332 | 1333 | * Redistributions of source code must retain the above copyright 1334 | notice, this list of conditions and the following disclaimer. 1335 | * Redistributions in binary form must reproduce the above 1336 | copyright notice, this list of conditions and the following disclaimer 1337 | in the documentation and/or other materials provided with the 1338 | distribution. 1339 | * Neither the name of Google Inc. nor the names of its 1340 | contributors may be used to endorse or promote products derived from 1341 | this software without specific prior written permission. 1342 | 1343 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1344 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1345 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1346 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1347 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1348 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1349 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1350 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1351 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1352 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1353 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1354 | 1355 | ================================================================ 1356 | 1357 | golang.org/x/term 1358 | https://golang.org/x/term 1359 | ---------------------------------------------------------------- 1360 | Copyright (c) 2009 The Go Authors. All rights reserved. 1361 | 1362 | Redistribution and use in source and binary forms, with or without 1363 | modification, are permitted provided that the following conditions are 1364 | met: 1365 | 1366 | * Redistributions of source code must retain the above copyright 1367 | notice, this list of conditions and the following disclaimer. 1368 | * Redistributions in binary form must reproduce the above 1369 | copyright notice, this list of conditions and the following disclaimer 1370 | in the documentation and/or other materials provided with the 1371 | distribution. 1372 | * Neither the name of Google Inc. nor the names of its 1373 | contributors may be used to endorse or promote products derived from 1374 | this software without specific prior written permission. 1375 | 1376 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1377 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1378 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1379 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1380 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1381 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1382 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1383 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1384 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1385 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1386 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1387 | 1388 | ================================================================ 1389 | 1390 | google.golang.org/appengine 1391 | https://google.golang.org/appengine 1392 | ---------------------------------------------------------------- 1393 | 1394 | Apache License 1395 | Version 2.0, January 2004 1396 | http://www.apache.org/licenses/ 1397 | 1398 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1399 | 1400 | 1. Definitions. 1401 | 1402 | "License" shall mean the terms and conditions for use, reproduction, 1403 | and distribution as defined by Sections 1 through 9 of this document. 1404 | 1405 | "Licensor" shall mean the copyright owner or entity authorized by 1406 | the copyright owner that is granting the License. 1407 | 1408 | "Legal Entity" shall mean the union of the acting entity and all 1409 | other entities that control, are controlled by, or are under common 1410 | control with that entity. For the purposes of this definition, 1411 | "control" means (i) the power, direct or indirect, to cause the 1412 | direction or management of such entity, whether by contract or 1413 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 1414 | outstanding shares, or (iii) beneficial ownership of such entity. 1415 | 1416 | "You" (or "Your") shall mean an individual or Legal Entity 1417 | exercising permissions granted by this License. 1418 | 1419 | "Source" form shall mean the preferred form for making modifications, 1420 | including but not limited to software source code, documentation 1421 | source, and configuration files. 1422 | 1423 | "Object" form shall mean any form resulting from mechanical 1424 | transformation or translation of a Source form, including but 1425 | not limited to compiled object code, generated documentation, 1426 | and conversions to other media types. 1427 | 1428 | "Work" shall mean the work of authorship, whether in Source or 1429 | Object form, made available under the License, as indicated by a 1430 | copyright notice that is included in or attached to the work 1431 | (an example is provided in the Appendix below). 1432 | 1433 | "Derivative Works" shall mean any work, whether in Source or Object 1434 | form, that is based on (or derived from) the Work and for which the 1435 | editorial revisions, annotations, elaborations, or other modifications 1436 | represent, as a whole, an original work of authorship. For the purposes 1437 | of this License, Derivative Works shall not include works that remain 1438 | separable from, or merely link (or bind by name) to the interfaces of, 1439 | the Work and Derivative Works thereof. 1440 | 1441 | "Contribution" shall mean any work of authorship, including 1442 | the original version of the Work and any modifications or additions 1443 | to that Work or Derivative Works thereof, that is intentionally 1444 | submitted to Licensor for inclusion in the Work by the copyright owner 1445 | or by an individual or Legal Entity authorized to submit on behalf of 1446 | the copyright owner. For the purposes of this definition, "submitted" 1447 | means any form of electronic, verbal, or written communication sent 1448 | to the Licensor or its representatives, including but not limited to 1449 | communication on electronic mailing lists, source code control systems, 1450 | and issue tracking systems that are managed by, or on behalf of, the 1451 | Licensor for the purpose of discussing and improving the Work, but 1452 | excluding communication that is conspicuously marked or otherwise 1453 | designated in writing by the copyright owner as "Not a Contribution." 1454 | 1455 | "Contributor" shall mean Licensor and any individual or Legal Entity 1456 | on behalf of whom a Contribution has been received by Licensor and 1457 | subsequently incorporated within the Work. 1458 | 1459 | 2. Grant of Copyright License. Subject to the terms and conditions of 1460 | this License, each Contributor hereby grants to You a perpetual, 1461 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 1462 | copyright license to reproduce, prepare Derivative Works of, 1463 | publicly display, publicly perform, sublicense, and distribute the 1464 | Work and such Derivative Works in Source or Object form. 1465 | 1466 | 3. Grant of Patent License. Subject to the terms and conditions of 1467 | this License, each Contributor hereby grants to You a perpetual, 1468 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 1469 | (except as stated in this section) patent license to make, have made, 1470 | use, offer to sell, sell, import, and otherwise transfer the Work, 1471 | where such license applies only to those patent claims licensable 1472 | by such Contributor that are necessarily infringed by their 1473 | Contribution(s) alone or by combination of their Contribution(s) 1474 | with the Work to which such Contribution(s) was submitted. If You 1475 | institute patent litigation against any entity (including a 1476 | cross-claim or counterclaim in a lawsuit) alleging that the Work 1477 | or a Contribution incorporated within the Work constitutes direct 1478 | or contributory patent infringement, then any patent licenses 1479 | granted to You under this License for that Work shall terminate 1480 | as of the date such litigation is filed. 1481 | 1482 | 4. Redistribution. You may reproduce and distribute copies of the 1483 | Work or Derivative Works thereof in any medium, with or without 1484 | modifications, and in Source or Object form, provided that You 1485 | meet the following conditions: 1486 | 1487 | (a) You must give any other recipients of the Work or 1488 | Derivative Works a copy of this License; and 1489 | 1490 | (b) You must cause any modified files to carry prominent notices 1491 | stating that You changed the files; and 1492 | 1493 | (c) You must retain, in the Source form of any Derivative Works 1494 | that You distribute, all copyright, patent, trademark, and 1495 | attribution notices from the Source form of the Work, 1496 | excluding those notices that do not pertain to any part of 1497 | the Derivative Works; and 1498 | 1499 | (d) If the Work includes a "NOTICE" text file as part of its 1500 | distribution, then any Derivative Works that You distribute must 1501 | include a readable copy of the attribution notices contained 1502 | within such NOTICE file, excluding those notices that do not 1503 | pertain to any part of the Derivative Works, in at least one 1504 | of the following places: within a NOTICE text file distributed 1505 | as part of the Derivative Works; within the Source form or 1506 | documentation, if provided along with the Derivative Works; or, 1507 | within a display generated by the Derivative Works, if and 1508 | wherever such third-party notices normally appear. The contents 1509 | of the NOTICE file are for informational purposes only and 1510 | do not modify the License. You may add Your own attribution 1511 | notices within Derivative Works that You distribute, alongside 1512 | or as an addendum to the NOTICE text from the Work, provided 1513 | that such additional attribution notices cannot be construed 1514 | as modifying the License. 1515 | 1516 | You may add Your own copyright statement to Your modifications and 1517 | may provide additional or different license terms and conditions 1518 | for use, reproduction, or distribution of Your modifications, or 1519 | for any such Derivative Works as a whole, provided Your use, 1520 | reproduction, and distribution of the Work otherwise complies with 1521 | the conditions stated in this License. 1522 | 1523 | 5. Submission of Contributions. Unless You explicitly state otherwise, 1524 | any Contribution intentionally submitted for inclusion in the Work 1525 | by You to the Licensor shall be under the terms and conditions of 1526 | this License, without any additional terms or conditions. 1527 | Notwithstanding the above, nothing herein shall supersede or modify 1528 | the terms of any separate license agreement you may have executed 1529 | with Licensor regarding such Contributions. 1530 | 1531 | 6. Trademarks. This License does not grant permission to use the trade 1532 | names, trademarks, service marks, or product names of the Licensor, 1533 | except as required for reasonable and customary use in describing the 1534 | origin of the Work and reproducing the content of the NOTICE file. 1535 | 1536 | 7. Disclaimer of Warranty. Unless required by applicable law or 1537 | agreed to in writing, Licensor provides the Work (and each 1538 | Contributor provides its Contributions) on an "AS IS" BASIS, 1539 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1540 | implied, including, without limitation, any warranties or conditions 1541 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 1542 | PARTICULAR PURPOSE. You are solely responsible for determining the 1543 | appropriateness of using or redistributing the Work and assume any 1544 | risks associated with Your exercise of permissions under this License. 1545 | 1546 | 8. Limitation of Liability. In no event and under no legal theory, 1547 | whether in tort (including negligence), contract, or otherwise, 1548 | unless required by applicable law (such as deliberate and grossly 1549 | negligent acts) or agreed to in writing, shall any Contributor be 1550 | liable to You for damages, including any direct, indirect, special, 1551 | incidental, or consequential damages of any character arising as a 1552 | result of this License or out of the use or inability to use the 1553 | Work (including but not limited to damages for loss of goodwill, 1554 | work stoppage, computer failure or malfunction, or any and all 1555 | other commercial damages or losses), even if such Contributor 1556 | has been advised of the possibility of such damages. 1557 | 1558 | 9. Accepting Warranty or Additional Liability. While redistributing 1559 | the Work or Derivative Works thereof, You may choose to offer, 1560 | and charge a fee for, acceptance of support, warranty, indemnity, 1561 | or other liability obligations and/or rights consistent with this 1562 | License. However, in accepting such obligations, You may act only 1563 | on Your own behalf and on Your sole responsibility, not on behalf 1564 | of any other Contributor, and only if You agree to indemnify, 1565 | defend, and hold each Contributor harmless for any liability 1566 | incurred by, or claims asserted against, such Contributor by reason 1567 | of your accepting any such warranty or additional liability. 1568 | 1569 | END OF TERMS AND CONDITIONS 1570 | 1571 | APPENDIX: How to apply the Apache License to your work. 1572 | 1573 | To apply the Apache License to your work, attach the following 1574 | boilerplate notice, with the fields enclosed by brackets "[]" 1575 | replaced with your own identifying information. (Don't include 1576 | the brackets!) The text should be enclosed in the appropriate 1577 | comment syntax for the file format. We also recommend that a 1578 | file or class name and description of purpose be included on the 1579 | same "printed page" as the copyright notice for easier 1580 | identification within third-party archives. 1581 | 1582 | Copyright [yyyy] [name of copyright owner] 1583 | 1584 | Licensed under the Apache License, Version 2.0 (the "License"); 1585 | you may not use this file except in compliance with the License. 1586 | You may obtain a copy of the License at 1587 | 1588 | http://www.apache.org/licenses/LICENSE-2.0 1589 | 1590 | Unless required by applicable law or agreed to in writing, software 1591 | distributed under the License is distributed on an "AS IS" BASIS, 1592 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1593 | See the License for the specific language governing permissions and 1594 | limitations under the License. 1595 | 1596 | ================================================================ 1597 | 1598 | google.golang.org/protobuf 1599 | https://google.golang.org/protobuf 1600 | ---------------------------------------------------------------- 1601 | Copyright (c) 2018 The Go Authors. All rights reserved. 1602 | 1603 | Redistribution and use in source and binary forms, with or without 1604 | modification, are permitted provided that the following conditions are 1605 | met: 1606 | 1607 | * Redistributions of source code must retain the above copyright 1608 | notice, this list of conditions and the following disclaimer. 1609 | * Redistributions in binary form must reproduce the above 1610 | copyright notice, this list of conditions and the following disclaimer 1611 | in the documentation and/or other materials provided with the 1612 | distribution. 1613 | * Neither the name of Google Inc. nor the names of its 1614 | contributors may be used to endorse or promote products derived from 1615 | this software without specific prior written permission. 1616 | 1617 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1618 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1619 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1620 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1621 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1622 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1623 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1624 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1625 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1626 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1627 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1628 | 1629 | ================================================================ 1630 | 1631 | gopkg.in/check.v1 1632 | https://gopkg.in/check.v1 1633 | ---------------------------------------------------------------- 1634 | Gocheck - A rich testing framework for Go 1635 | 1636 | Copyright (c) 2010-2013 Gustavo Niemeyer 1637 | 1638 | All rights reserved. 1639 | 1640 | Redistribution and use in source and binary forms, with or without 1641 | modification, are permitted provided that the following conditions are met: 1642 | 1643 | 1. Redistributions of source code must retain the above copyright notice, this 1644 | list of conditions and the following disclaimer. 1645 | 2. Redistributions in binary form must reproduce the above copyright notice, 1646 | this list of conditions and the following disclaimer in the documentation 1647 | and/or other materials provided with the distribution. 1648 | 1649 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 1650 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1651 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 1652 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 1653 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 1654 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 1655 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 1656 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1657 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 1658 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1659 | 1660 | ================================================================ 1661 | 1662 | gopkg.in/h2non/gock.v1 1663 | https://gopkg.in/h2non/gock.v1 1664 | ---------------------------------------------------------------- 1665 | The MIT License 1666 | 1667 | Copyright (c) 2016-2019 Tomas Aparicio 1668 | 1669 | Permission is hereby granted, free of charge, to any person 1670 | obtaining a copy of this software and associated documentation 1671 | files (the "Software"), to deal in the Software without 1672 | restriction, including without limitation the rights to use, 1673 | copy, modify, merge, publish, distribute, sublicense, and/or sell 1674 | copies of the Software, and to permit persons to whom the 1675 | Software is furnished to do so, subject to the following 1676 | conditions: 1677 | 1678 | The above copyright notice and this permission notice shall be 1679 | included in all copies or substantial portions of the Software. 1680 | 1681 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1682 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 1683 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1684 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 1685 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 1686 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 1687 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 1688 | OTHER DEALINGS IN THE SOFTWARE. 1689 | 1690 | ================================================================ 1691 | 1692 | gopkg.in/yaml.v3 1693 | https://gopkg.in/yaml.v3 1694 | ---------------------------------------------------------------- 1695 | 1696 | This project is covered by two different licenses: MIT and Apache. 1697 | 1698 | #### MIT License #### 1699 | 1700 | The following files were ported to Go from C files of libyaml, and thus 1701 | are still covered by their original MIT license, with the additional 1702 | copyright staring in 2011 when the project was ported over: 1703 | 1704 | apic.go emitterc.go parserc.go readerc.go scannerc.go 1705 | writerc.go yamlh.go yamlprivateh.go 1706 | 1707 | Copyright (c) 2006-2010 Kirill Simonov 1708 | Copyright (c) 2006-2011 Kirill Simonov 1709 | 1710 | Permission is hereby granted, free of charge, to any person obtaining a copy of 1711 | this software and associated documentation files (the "Software"), to deal in 1712 | the Software without restriction, including without limitation the rights to 1713 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1714 | of the Software, and to permit persons to whom the Software is furnished to do 1715 | so, subject to the following conditions: 1716 | 1717 | The above copyright notice and this permission notice shall be included in all 1718 | copies or substantial portions of the Software. 1719 | 1720 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1721 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1722 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1723 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1724 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1725 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1726 | SOFTWARE. 1727 | 1728 | ### Apache License ### 1729 | 1730 | All the remaining project files are covered by the Apache license: 1731 | 1732 | Copyright (c) 2011-2019 Canonical Ltd 1733 | 1734 | Licensed under the Apache License, Version 2.0 (the "License"); 1735 | you may not use this file except in compliance with the License. 1736 | You may obtain a copy of the License at 1737 | 1738 | http://www.apache.org/licenses/LICENSE-2.0 1739 | 1740 | Unless required by applicable law or agreed to in writing, software 1741 | distributed under the License is distributed on an "AS IS" BASIS, 1742 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1743 | See the License for the specific language governing permissions and 1744 | limitations under the License. 1745 | 1746 | ================================================================ 1747 | 1748 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1-bullseye AS builder 2 | 3 | WORKDIR /workdir/ 4 | COPY . /workdir/ 5 | 6 | RUN apt-get update 7 | 8 | RUN update-ca-certificates 9 | 10 | RUN make build 11 | 12 | FROM debian:bullseye-slim 13 | 14 | RUN apt-get update \ 15 | && apt-get clean \ 16 | && rm -rf /var/lib/apt/lists/* 17 | 18 | COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 19 | COPY --from=builder /workdir/ghsetup ./usr/bin/gh-setup 20 | 21 | ENTRYPOINT ["/entrypoint.sh"] 22 | 23 | COPY scripts/entrypoint.sh /entrypoint.sh 24 | RUN chmod +x /entrypoint.sh 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2023 Ken'ichiro Oyama 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PKG = github.com/k1LoW/gh-setup 2 | COMMIT = $$(git describe --tags --always) 3 | OSNAME=${shell uname -s} 4 | ifeq ($(OSNAME),Darwin) 5 | DATE = $$(gdate --utc '+%Y-%m-%d_%H:%M:%S') 6 | else 7 | DATE = $$(date --utc '+%Y-%m-%d_%H:%M:%S') 8 | endif 9 | 10 | export GO111MODULE=on 11 | 12 | BUILD_LDFLAGS = -X $(PKG).commit=$(COMMIT) -X $(PKG).date=$(DATE) 13 | 14 | default: test 15 | 16 | ci: depsdev test 17 | 18 | test: 19 | go test ./... -coverprofile=coverage.out -covermode=count 20 | 21 | lint: 22 | golangci-lint run ./... 23 | 24 | build: 25 | go build -ldflags="$(BUILD_LDFLAGS)" -o ghsetup cmd/gh-setup/main.go 26 | 27 | depsdev: 28 | go install github.com/Songmu/ghch/cmd/ghch@latest 29 | go install github.com/Songmu/gocredits/cmd/gocredits@latest 30 | go install github.com/securego/gosec/v2/cmd/gosec@latest 31 | 32 | prerelease: 33 | git pull origin main --tag 34 | go mod tidy 35 | ghch -w -N ${VER} 36 | gocredits -skip-missing -w . 37 | git add CHANGELOG.md CREDITS go.mod go.sum 38 | git commit -m'Bump up version number' 39 | git tag ${VER} 40 | 41 | prerelease_for_tagpr: 42 | gocredits -skip-missing -w . 43 | git add CHANGELOG.md CREDITS go.mod go.sum 44 | 45 | release: 46 | git push origin main --tag 47 | goreleaser --clean 48 | 49 | .PHONY: default test 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gh-setup 2 | 3 | :octocat: Setup asset of Github Releases. 4 | 5 | [![build](https://github.com/k1LoW/gh-setup/actions/workflows/ci.yml/badge.svg)](https://github.com/k1LoW/gh-setup/actions/workflows/ci.yml) ![Coverage](https://raw.githubusercontent.com/k1LoW/octocovs/main/badges/k1LoW/gh-setup/coverage.svg) ![Code to Test Ratio](https://raw.githubusercontent.com/k1LoW/octocovs/main/badges/k1LoW/gh-setup/ratio.svg) 6 | 7 | Key features of `gh-setup` are: 8 | 9 | - **For setup, detect the version, the appropriate GitHub Releases asset, the asset's compressed format, and the executable path where the binary will be installed.** 10 | - **Works as a GitHub CLI extension (or a standalone CLI) as well as a GitHub Action.** 11 | - **Could be used as a part to create a GitHub Action like `setup-*`.** 12 | 13 | ## As a GitHub CLI extension 14 | 15 | ### Usage 16 | 17 | ``` console 18 | $ gh setup --repo k1LoW/tbls 19 | Use tbls_v1.62.0_darwin_arm64.zip 20 | Setup binaries to executable path (PATH): 21 | tbls -> /Users/k1low/local/bin/tbls 22 | $ tbls version 23 | 1.62.0 24 | ``` 25 | 26 | ### Install 27 | 28 | ``` console 29 | $ gh extension install k1LoW/gh-setup 30 | ``` 31 | 32 | ## As a GitHub Action 33 | 34 | ### Usage 35 | 36 | ``` yaml 37 | # .github/workflows/doc.yml 38 | [...] 39 | steps: 40 | - 41 | name: Setup k1LoW/tbls 42 | uses: k1LoW/gh-setup@v1 43 | with: 44 | github-token: ${{ secrets.GITHUB_TOKEN }} 45 | repo: k1LoW/tbls 46 | # version: v1.60.0 47 | # os: linux 48 | # arch: amd64 49 | # bin-match: tbls 50 | # checksum: f1ee97bbf22d5324ec2b468d83f43088d9e5c61deb77fafc220b297e03d47574 51 | # force: true 52 | # strict: true 53 | # verify-attestation: true 54 | # attestation-flags: "--owner=k1LoW" 55 | # gh-setup-version: latest 56 | - 57 | name: Run tbls 58 | run: tbls doc 59 | ``` 60 | 61 | ## As a part to create a GitHub Action like `setup-*` 62 | 63 | See https://github.com/k1LoW/setup-tbls 64 | 65 | ``` yaml 66 | # action.yml 67 | name: 'Setup tbls' 68 | description: 'GitHub Action for tbls, a CI-Friendly tool for document a database, written in Go.' 69 | branding: 70 | icon: 'box' 71 | color: 'blue' 72 | inputs: 73 | github-token: 74 | description: The GitHub token 75 | default: ${{ github.token }} 76 | required: false 77 | version: 78 | description: Version of tbls 79 | default: latest 80 | required: false 81 | force: 82 | description: Enable force setup 83 | default: '' 84 | required: false 85 | checksum: 86 | description: Checksum of tbls 87 | default: '' 88 | required: false 89 | runs: 90 | using: 'composite' 91 | steps: 92 | - 93 | uses: k1LoW/gh-setup@v1 94 | with: 95 | repo: github.com/k1LoW/tbls 96 | github-token: ${{ inputs.github-token }} 97 | version: ${{ inputs.version }} 98 | bin-match: tbls 99 | checksum: ${{ inputs.checksum }} 100 | force: ${{ inputs.force }} 101 | ``` 102 | 103 | ## As a Standalone CLI 104 | 105 | ### Usage 106 | 107 | Run `gh-setup` instead of `gh setup`. 108 | 109 | ``` console 110 | $ gh-setup --repo k1LoW/tbls 111 | Use tbls_v1.62.0_darwin_arm64.zip 112 | Setup binaries to executable path (PATH): 113 | tbls -> /Users/k1low/local/bin/tbls 114 | $ tbls version 115 | 1.62.0 116 | ``` 117 | 118 | ### Install 119 | 120 | **deb:** 121 | 122 | ``` console 123 | $ export GH_SETUP_VERSION=X.X.X 124 | $ curl -o gh-setup.deb -L https://github.com/k1LoW/gh-setup/releases/download/v$GH_SETUP_VERSION/gh-setup_$GH_SETUP_VERSION-1_amd64.deb 125 | $ dpkg -i gh-setup.deb 126 | ``` 127 | 128 | **RPM:** 129 | 130 | ``` console 131 | $ export GH_SETUP_VERSION=X.X.X 132 | $ yum install https://github.com/k1LoW/gh-setup/releases/download/v$GH_SETUP_VERSION/gh-setup_$GH_SETUP_VERSION-1_amd64.rpm 133 | ``` 134 | 135 | **apk:** 136 | 137 | ``` console 138 | $ export GH_SETUP_VERSION=X.X.X 139 | $ curl -o gh-setup.apk -L https://github.com/k1LoW/gh-setup/releases/download/v$GH_SETUP_VERSION/gh-setup_$GH_SETUP_VERSION-1_amd64.apk 140 | $ apk add gh-setup.apk 141 | ``` 142 | 143 | **homebrew tap:** 144 | 145 | ```console 146 | $ brew install k1LoW/tap/gh-setup 147 | ``` 148 | 149 | **[aqua](https://aquaproj.github.io/):** 150 | 151 | ```console 152 | $ aqua g -i k1LoW/gh-setup 153 | ``` 154 | 155 | **manually:** 156 | 157 | Download binary from [releases page](https://github.com/k1LoW/gh-setup/releases) 158 | 159 | **go install:** 160 | 161 | ```console 162 | $ go install github.com/k1LoW/gh-setup/cmd/gh-setup@latest 163 | ``` 164 | 165 | **docker:** 166 | 167 | ```console 168 | $ docker pull ghcr.io/k1low/gh-setup:latest 169 | ``` 170 | 171 | ## Attestation Verification 172 | 173 | gh-setup supports verifying attestations using the `gh attestation verify` command. To enable attestation verification, use the `--verify-attestation` flag. You can also pass additional flags to the `gh attestation verify` command using the `--attestation-flags` flag. 174 | 175 | Example: 176 | 177 | ```console 178 | $ gh setup --repo k1LoW/tbls --verify-attestation --attestation-flags "--owner=k1LoW" 179 | ``` 180 | 181 | In GitHub Actions: 182 | 183 | ```yaml 184 | - name: Setup k1LoW/tbls 185 | uses: k1LoW/gh-setup@v1 186 | with: 187 | github-token: ${{ secrets.GITHUB_TOKEN }} 188 | repo: k1LoW/tbls 189 | verify-attestation: true 190 | attestation-flags: "--owner=k1LoW" 191 | ``` 192 | 193 | This feature requires the `gh` CLI with the attestation extension to be installed. 194 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Setup asset of Github Releases' 2 | description: 'GitHub Action for gh-setup' 3 | branding: 4 | icon: 'zap' 5 | color: 'gray-dark' 6 | inputs: 7 | github-token: 8 | description: The GitHub token 9 | default: ${{ github.token }} 10 | required: false 11 | repo: 12 | description: "Target repository ([HOST/]OWNER/REPO)" 13 | required: true 14 | version: 15 | description: "Release version" 16 | default: "" 17 | required: false 18 | os: 19 | description: "Specify OS of asset" 20 | default: "" 21 | required: false 22 | arch: 23 | description: "Specify arch of asset" 24 | default: "" 25 | required: false 26 | match: 27 | description: "Regexp to match asset name" 28 | default: "" 29 | required: false 30 | bin-dir: 31 | description: "Executable path" 32 | default: "" 33 | required: false 34 | bin-match: 35 | description: "Regexp to match bin path in asset" 36 | default: "" 37 | required: false 38 | checksum: 39 | description: "Checksum of asset" 40 | default: "" 41 | required: false 42 | force: 43 | description: "Enable force setup" 44 | default: "" 45 | required: false 46 | strict: 47 | description: "Require strict match" 48 | default: "" 49 | required: false 50 | skip-content-type-check: 51 | description: "Skip check content-type of assets" 52 | default: "" 53 | required: false 54 | verify-attestation: 55 | description: "Enable attestation verification using 'gh attestation verify'" 56 | default: "" 57 | required: false 58 | attestation-flags: 59 | description: "Additional flags to pass to 'gh attestation verify'" 60 | default: "" 61 | required: false 62 | gh-setup-version: 63 | description: "Version of gh-setup" 64 | default: "v1.11.2" 65 | required: false 66 | runs: 67 | using: "composite" 68 | steps: 69 | - 70 | id: install-gh-setup 71 | run: ${GITHUB_ACTION_PATH}/scripts/install-gh-setup.sh 72 | shell: bash 73 | env: 74 | GH_SETUP_GITHUB_TOKEN: ${{ inputs.github-token }} 75 | GH_SETUP_GH_SETUP_VERSION: ${{ inputs.gh-setup-version }} 76 | - 77 | run: ${GITHUB_ACTION_PATH}/scripts/run-gh-setup.sh 78 | shell: bash 79 | env: 80 | GH_SETUP_GITHUB_TOKEN: ${{ inputs.github-token }} 81 | GH_SETUP_REPO: ${{ inputs.repo }} 82 | GH_SETUP_VERSION: ${{ inputs.version }} 83 | GH_SETUP_OS: ${{ inputs.os }} 84 | GH_SETUP_ARCH: ${{ inputs.arch }} 85 | GH_SETUP_MATCH: ${{ inputs.match }} 86 | GH_SETUP_BIN_DIR: ${{ inputs.bin-dir }} 87 | GH_SETUP_BIN_MATCH: ${{ inputs.bin-match }} 88 | GH_SETUP_CHECKSUM: ${{ inputs.checksum }} 89 | GH_SETUP_FORCE: ${{ inputs.force }} 90 | GH_SETUP_STRICT: ${{ inputs.strict }} 91 | GH_SETUP_SKIP_CONTENT_TYPE_CHECK: ${{ inputs.skip-content-type-check }} 92 | GH_SETUP_VERIFY_ATTESTATION: ${{ inputs.verify-attestation }} 93 | GH_SETUP_ATTESTATION_FLAGS: ${{ inputs.attestation-flags }} 94 | GH_SETUP_BIN: ${{ steps.install-gh-setup.outputs.bin }} 95 | -------------------------------------------------------------------------------- /cmd/gh-setup/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2023 Ken'ichiro Oyama 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | package main 23 | 24 | import "github.com/k1LoW/gh-setup/cmd" 25 | 26 | func main() { 27 | cmd.Execute() 28 | } 29 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2023 Ken'ichiro Oyama 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | package cmd 23 | 24 | import ( 25 | "context" 26 | "fmt" 27 | "io" 28 | "os" 29 | 30 | "github.com/k1LoW/gh-setup/gh" 31 | "github.com/k1LoW/gh-setup/setup" 32 | "github.com/k1LoW/gh-setup/version" 33 | "github.com/spf13/cobra" 34 | "golang.org/x/exp/slog" 35 | ) 36 | 37 | var ownerrepo string 38 | 39 | var ( 40 | opt = &gh.AssetOption{} 41 | sOpt = &setup.Option{} 42 | verbose bool 43 | ) 44 | 45 | var rootCmd = &cobra.Command{ 46 | Use: "gh-setup", 47 | Short: "Setup asset of Github Releases", 48 | Long: `Setup asset of Github Releases.`, 49 | Args: cobra.OnlyValidArgs, 50 | ValidArgs: []string{"version"}, 51 | SilenceUsage: true, 52 | RunE: func(cmd *cobra.Command, args []string) error { 53 | if len(args) > 0 { 54 | cmd.Printf("gh-setup version %s\n", version.Version) 55 | return nil 56 | } 57 | ctx := context.Background() 58 | setLogger(verbose) 59 | host, owner, repo, err := gh.DetectHostOwnerRepo(ownerrepo) 60 | if err != nil { 61 | return err 62 | } 63 | // override env 64 | os.Setenv("GH_HOST", host) 65 | os.Unsetenv("GITHUB_API_URL") 66 | 67 | a, fsys, err := gh.GetReleaseAsset(ctx, owner, repo, opt) 68 | if err != nil { 69 | return err 70 | } 71 | cmd.Printf("Use %s\n", a.Name) 72 | m, err := setup.Bin(fsys, sOpt) 73 | if err != nil { 74 | return err 75 | } 76 | if len(m) == 0 { 77 | return fmt.Errorf("setup failed: %s", a.Name) 78 | } 79 | cmd.Println("Setup binaries to executable path (PATH):") 80 | for b, bp := range m { 81 | cmd.Println(" ", b, "->", bp) 82 | } 83 | return nil 84 | }, 85 | } 86 | 87 | func Execute() { 88 | rootCmd.SetOut(os.Stdout) 89 | rootCmd.SetErr(os.Stderr) 90 | if err := rootCmd.Execute(); err != nil { 91 | os.Exit(1) 92 | } 93 | } 94 | 95 | func setLogger(verbose bool) { 96 | logger := slog.New(slog.NewTextHandler(io.Discard, nil)) 97 | switch { 98 | case os.Getenv("DEBUG") != "" || os.Getenv("ACTIONS_STEP_DEBUG") != "": 99 | logger = slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ 100 | AddSource: true, 101 | Level: slog.LevelDebug, 102 | })) 103 | case verbose: 104 | logger = slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ 105 | AddSource: false, 106 | Level: slog.LevelInfo, 107 | })) 108 | } 109 | slog.SetDefault(logger) 110 | } 111 | 112 | func init() { 113 | rootCmd.Flags().StringVarP(&ownerrepo, "repo", "R", "", "repository using the [HOST/]OWNER/REPO format") 114 | rootCmd.Flags().StringVarP(&opt.Version, "version", "v", "", "release version") 115 | rootCmd.Flags().StringVarP(&opt.OS, "os", "O", "", "specify OS of asset") 116 | rootCmd.Flags().StringVarP(&opt.Arch, "arch", "A", "", "specify arch of asset") 117 | rootCmd.Flags().StringVarP(&opt.Match, "match", "", "", "regexp to match asset name") 118 | rootCmd.Flags().StringVarP(&sOpt.BinDir, "bin-dir", "", "", "bin directory for setup") 119 | rootCmd.Flags().StringVarP(&sOpt.BinMatch, "bin-match", "", "", "regexp to match bin path in asset") 120 | rootCmd.Flags().StringVarP(&opt.Checksum, "checksum", "", "", "checksum of asset") 121 | rootCmd.Flags().BoolVarP(&sOpt.Force, "force", "f", false, "enable force setup") 122 | rootCmd.Flags().BoolVarP(&opt.Strict, "strict", "", false, "require strict match") 123 | rootCmd.Flags().BoolVarP(&opt.SkipContentTypeCheck, "skip-content-type-check", "", false, "skip check content-type of assets") 124 | rootCmd.Flags().BoolVarP(&verbose, "verbose", "", false, "show verbose log") 125 | rootCmd.Flags().BoolVarP(&opt.VerifyAttestation, "verify-attestation", "", false, "enable attestation verification using 'gh attestation verify'") 126 | rootCmd.Flags().StringVarP(&opt.AttestationFlags, "attestation-flags", "", "", "additional flags to pass to 'gh attestation verify' (e.g. \"--owner=k1LoW\")") 127 | } 128 | -------------------------------------------------------------------------------- /gh-setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Get extension repository path 5 | extPath="$(dirname "$0")" 6 | 7 | # Get latest version 8 | cd "${extPath}" > /dev/null 9 | ver="$(git tag | grep ^v | sort --version-sort | tail -1)" 10 | if [ "${ver}" = "" ]; then 11 | git fetch --tags > /dev/null 2>&1 12 | ver="$(git tag | grep ^v | sort --version-sort | tail -1)" 13 | fi 14 | cd - > /dev/null 15 | 16 | # Get arch 17 | arch="$(uname -m)" 18 | 19 | # Get binary file name 20 | exe="gh-setup" # default 21 | if uname -a | grep Msys > /dev/null; then 22 | if [ "${arch}" = "x86_64" ]; then 23 | exe="gh-setup_${ver}_windows_amd64.exe" 24 | fi 25 | elif uname -a | grep Darwin > /dev/null; then 26 | if [ "${arch}" = "x86_64" ]; then 27 | exe="gh-setup_${ver}_darwin_amd64" 28 | elif [ "${arch}" = "arm64" ]; then 29 | exe="gh-setup_${ver}_darwin_arm64" 30 | fi 31 | elif uname -a | grep Linux > /dev/null; then 32 | if [ "${arch}" = "x86_64" ]; then 33 | exe="gh-setup_${ver}_linux_amd64" 34 | elif [ "${arch}" = "arm64" ] || [ "${arch}" = "aarch64" ]; then 35 | exe="gh-setup_${ver}_linux_arm64" 36 | fi 37 | fi 38 | 39 | # Cleanup bin/ dir 40 | rm -f "${extPath}/bin/*" 41 | mkdir -p "${extPath}/bin" 42 | 43 | binPath="${extPath}/bin/${exe}" 44 | 45 | if [ "${exe}" == "gh-setup" ]; then 46 | # Build binary 47 | if [ "$(which go)" = "" ]; then 48 | echo "go must be installed to use this gh extension on this platform" 49 | exit 1 50 | fi 51 | 52 | exe="cmd.out" 53 | 54 | cd "${extPath}" > /dev/null 55 | go build -o "${binPath}" 56 | cd - > /dev/null 57 | else 58 | # Download release binary 59 | if [[ ! -x "${binPath}" ]]; then 60 | if [ "$(which curl)" = "" ]; then 61 | echo "curl must be installed to use this gh extension on this platform" 62 | exit 1 63 | fi 64 | curl -sL -o "${binPath}" "https://github.com/k1LoW/gh-setup/releases/download/${ver}/${exe}" 65 | fi 66 | fi 67 | chmod +x "${binPath}" 68 | 69 | exec "${binPath}" "$@" 70 | -------------------------------------------------------------------------------- /gh/client.go: -------------------------------------------------------------------------------- 1 | package gh 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "context" 7 | "errors" 8 | "fmt" 9 | "io" 10 | "net/http" 11 | "strings" 12 | "time" 13 | 14 | "github.com/cli/go-gh/v2/pkg/api" 15 | "github.com/cli/go-gh/v2/pkg/auth" 16 | "github.com/google/go-github/v67/github" 17 | "github.com/k1LoW/go-github-client/v67/factory" 18 | "golang.org/x/exp/slog" 19 | ) 20 | 21 | type releaseAsset struct { 22 | ID int64 23 | Name string 24 | ContentType string 25 | DownloadURL string 26 | } 27 | 28 | type client struct { 29 | gc *github.Client 30 | hc *http.Client 31 | owner string 32 | repo string 33 | token string 34 | v3ep string 35 | } 36 | 37 | const ( 38 | defaultV3Endpoint = "https://api.github.com" 39 | acceptHeader = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" 40 | ) 41 | 42 | func newClient(ctx context.Context, owner, repo string) (*client, error) { 43 | host, hostSource := auth.DefaultHost() 44 | _, tokenSource := auth.TokenForHost(host) 45 | token, v3ep, _, _ := factory.GetTokenAndEndpoints() 46 | if token == "" { 47 | slog.Info("No credentials found, access without credentials", slog.String("endpoint", v3ep), slog.String("owner", owner), slog.String("repo", repo), slog.String("host_source", hostSource)) 48 | return newNoAuthClient(ctx, owner, repo, v3ep) 49 | } 50 | slog.Info("Access with credentials", slog.String("endpoint", v3ep), slog.String("owner", owner), slog.String("repo", repo), slog.String("host_source", hostSource), slog.String("token_source", tokenSource)) 51 | gc, err := factory.NewGithubClient() 52 | if err != nil { 53 | return nil, err 54 | } 55 | if _, _, err := gc.Repositories.Get(ctx, owner, repo); err != nil { 56 | slog.Info("Authentication failed, access without credentials", slog.String("error", err.Error()), slog.String("endpoint", v3ep), slog.String("owner", owner), slog.String("repo", repo), slog.String("host_source", hostSource), slog.String("token_source", tokenSource)) 57 | return newNoAuthClient(ctx, owner, repo, v3ep) 58 | } 59 | hc, err := api.DefaultHTTPClient() 60 | if err != nil { 61 | return nil, err 62 | } 63 | c := &client{ 64 | owner: owner, 65 | repo: repo, 66 | token: token, 67 | v3ep: v3ep, 68 | gc: gc, 69 | hc: hc, 70 | } 71 | return c, nil 72 | } 73 | 74 | func newNoAuthClient(ctx context.Context, owner, repo, v3ep string) (*client, error) { 75 | gc, err := factory.NewGithubClient(factory.SkipAuth(true)) 76 | if err != nil { 77 | return nil, err 78 | } 79 | tp, ok := http.DefaultTransport.(*http.Transport) 80 | if !ok { 81 | return nil, errors.New("failed to get http.Transport") 82 | } 83 | hc := &http.Client{ 84 | Timeout: 30 * time.Second, 85 | Transport: tp.Clone(), 86 | } 87 | c := &client{ 88 | owner: owner, 89 | repo: repo, 90 | v3ep: v3ep, 91 | gc: gc, 92 | hc: hc, 93 | } 94 | return c, nil 95 | } 96 | 97 | func (c *client) getReleaseAssets(ctx context.Context, opt *AssetOption) ([]*releaseAsset, error) { 98 | if c.token != "" { 99 | assets, err := c.getReleaseAssetsWithAPI(ctx, opt) 100 | if err == nil { 101 | return assets, nil 102 | } 103 | } 104 | return c.getReleaseAssetsWithoutAPI(ctx, opt) 105 | } 106 | 107 | func (c *client) getReleaseAssetsWithoutAPI(ctx context.Context, opt *AssetOption) ([]*releaseAsset, error) { 108 | slog.Info("Get assets directly from the GitHub WebUI") 109 | if c.v3ep != defaultV3Endpoint { 110 | return nil, fmt.Errorf("not support for non-API access: %s", c.v3ep) 111 | } 112 | page := 1 113 | for { 114 | urls, err := c.getReleaseAssetsURLs(ctx, page) 115 | if err != nil { 116 | return nil, err 117 | } 118 | if len(urls) == 0 { 119 | break 120 | } 121 | if opt == nil || (opt.Version == "" || opt.Version == versionLatest) { 122 | return c.getReleaseAssetsViaURL(ctx, urls[0]) 123 | } else { 124 | for _, url := range urls { 125 | if strings.HasSuffix(url, opt.Version) { 126 | return c.getReleaseAssetsViaURL(ctx, url) 127 | } 128 | } 129 | } 130 | page++ 131 | } 132 | return nil, errors.New("no assets found") 133 | } 134 | 135 | func (c *client) getReleaseAssetsURLs(ctx context.Context, page int) ([]string, error) { 136 | u := fmt.Sprintf("https://github.com/%s/%s/releases?page=%d", c.owner, c.repo, page) 137 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) 138 | if err != nil { 139 | return nil, err 140 | } 141 | req.Header.Add("Accept", acceptHeader) 142 | resp, err := c.hc.Do(req) 143 | if err != nil { 144 | return nil, err 145 | } 146 | defer resp.Body.Close() 147 | b, err := io.ReadAll(resp.Body) 148 | if err != nil { 149 | return nil, err 150 | } 151 | scanner := bufio.NewScanner(bytes.NewReader(b)) 152 | scanner.Split(bufio.ScanLines) 153 | urls := []string{} 154 | for scanner.Scan() { 155 | line := scanner.Text() 156 | if strings.Contains(line, fmt.Sprintf("https://github.com/%s/%s/releases/expanded_assets/", c.owner, c.repo)) { 157 | splitted := strings.Split(line, `src="`) 158 | if len(splitted) == 2 { 159 | splitted2 := strings.Split(splitted[1], `"`) 160 | urls = append(urls, splitted2[0]) 161 | } 162 | } 163 | } 164 | if err := scanner.Err(); err != nil { 165 | return nil, err 166 | } 167 | return urls, nil 168 | } 169 | 170 | func (c *client) getReleaseAssetsViaURL(ctx context.Context, url string) ([]*releaseAsset, error) { 171 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) 172 | if err != nil { 173 | return nil, err 174 | } 175 | req.Header.Add("Accept", acceptHeader) 176 | resp, err := c.hc.Do(req) 177 | if err != nil { 178 | return nil, err 179 | } 180 | defer resp.Body.Close() 181 | b, err := io.ReadAll(resp.Body) 182 | if err != nil { 183 | return nil, err 184 | } 185 | scanner := bufio.NewScanner(bytes.NewReader(b)) 186 | scanner.Split(bufio.ScanLines) 187 | assets := []*releaseAsset{} 188 | for scanner.Scan() { 189 | line := scanner.Text() 190 | if strings.Contains(line, "/download/") { 191 | splitted := strings.Split(line, `href="`) 192 | if len(splitted) == 2 { 193 | splitted2 := strings.Split(splitted[1], `"`) 194 | u := fmt.Sprintf("https://github.com%s", splitted2[0]) 195 | splitted3 := strings.Split(splitted2[0], "/") 196 | name := splitted3[len(splitted3)-1] 197 | assets = append(assets, &releaseAsset{ 198 | Name: name, 199 | DownloadURL: u, 200 | }) 201 | } 202 | } 203 | } 204 | if err := scanner.Err(); err != nil { 205 | return nil, err 206 | } 207 | return assets, nil 208 | } 209 | 210 | func (c *client) getReleaseAssetsWithAPI(ctx context.Context, opt *AssetOption) ([]*releaseAsset, error) { 211 | slog.Info("Get assets using the GitHub API") 212 | var ( 213 | r *github.RepositoryRelease 214 | err error 215 | ) 216 | if opt == nil || (opt.Version == "" || opt.Version == versionLatest) { 217 | r, _, err = c.gc.Repositories.GetLatestRelease(ctx, c.owner, c.repo) 218 | if err != nil { 219 | return nil, err 220 | } 221 | } else { 222 | r, _, err = c.gc.Repositories.GetReleaseByTag(ctx, c.owner, c.repo, opt.Version) 223 | if err != nil { 224 | return nil, err 225 | } 226 | } 227 | assets := []*releaseAsset{} 228 | for _, a := range r.Assets { 229 | assets = append(assets, &releaseAsset{ 230 | ID: a.GetID(), 231 | Name: a.GetName(), 232 | ContentType: a.GetContentType(), 233 | DownloadURL: a.GetBrowserDownloadURL(), 234 | }) 235 | } 236 | return assets, nil 237 | } 238 | 239 | func (c *client) downloadAsset(ctx context.Context, a *releaseAsset) ([]byte, error) { 240 | if c.token != "" { 241 | b, err := c.downloadAssetWithAPI(ctx, a) 242 | if err == nil { 243 | return b, nil 244 | } 245 | } 246 | return c.downloadAssetWithoutAPI(ctx, a) 247 | } 248 | 249 | func (c *client) downloadAssetWithoutAPI(ctx context.Context, a *releaseAsset) ([]byte, error) { 250 | slog.Info("Download asset directly from the GitHub WebUI") 251 | if a.DownloadURL == "" { 252 | return nil, errors.New("empty download URL") 253 | } 254 | u := a.DownloadURL 255 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) 256 | if err != nil { 257 | return nil, err 258 | } 259 | req.Header.Add("Accept", "application/octet-stream") 260 | resp, err := c.hc.Do(req) 261 | if err != nil { 262 | return nil, err 263 | } 264 | defer resp.Body.Close() 265 | b, err := io.ReadAll(resp.Body) 266 | if err != nil { 267 | return nil, err 268 | } 269 | if resp.StatusCode != http.StatusOK { 270 | return nil, fmt.Errorf("failed to download: %d %s", resp.StatusCode, string(b)) 271 | } 272 | return b, nil 273 | } 274 | 275 | func (c *client) downloadAssetWithAPI(ctx context.Context, a *releaseAsset) ([]byte, error) { 276 | slog.Info("Download asset using the GitHub API") 277 | u := fmt.Sprintf("%s/repos/%s/%s/releases/assets/%d", c.v3ep, c.owner, c.repo, a.ID) 278 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) 279 | if err != nil { 280 | return nil, err 281 | } 282 | req.Header.Add("Accept", "application/octet-stream") 283 | resp, err := c.hc.Do(req) 284 | if err != nil { 285 | return nil, err 286 | } 287 | defer resp.Body.Close() 288 | b, err := io.ReadAll(resp.Body) 289 | if err != nil { 290 | return nil, err 291 | } 292 | if resp.StatusCode != http.StatusOK { 293 | return nil, fmt.Errorf("failed to download: %d %s", resp.StatusCode, string(b)) 294 | } 295 | return b, nil 296 | } 297 | -------------------------------------------------------------------------------- /gh/client_test.go: -------------------------------------------------------------------------------- 1 | package gh 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | ) 7 | 8 | func TestGetReleaseAssetsWithoutAPI(t *testing.T) { 9 | tests := []struct { 10 | owner string 11 | repo string 12 | opt *AssetOption 13 | }{ 14 | {"k1LoW", "tbls", nil}, 15 | } 16 | ctx := context.Background() 17 | for _, tt := range tests { 18 | c, err := newClient(ctx, tt.owner, tt.repo) 19 | if err != nil { 20 | t.Error(err) 21 | continue 22 | } 23 | assets, err := c.getReleaseAssetsWithoutAPI(ctx, tt.opt) 24 | if err != nil { 25 | t.Error(err) 26 | continue 27 | } 28 | if len(assets) == 0 { 29 | t.Error("want assets") 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gh/gh.go: -------------------------------------------------------------------------------- 1 | package gh 2 | 3 | import ( 4 | "archive/zip" 5 | "bytes" 6 | "compress/bzip2" 7 | "compress/gzip" 8 | "context" 9 | "crypto/md5" //nolint:gosec 10 | "crypto/sha1" //nolint:gosec 11 | "crypto/sha256" 12 | "crypto/sha512" 13 | "encoding/hex" 14 | "errors" 15 | "fmt" 16 | "hash/crc32" 17 | "io" 18 | "io/fs" 19 | "net/http" 20 | "os" 21 | "os/exec" 22 | "regexp" 23 | "runtime" 24 | "sort" 25 | "strings" 26 | "testing/fstest" 27 | "time" 28 | 29 | "github.com/cli/go-gh/v2/pkg/repository" 30 | "github.com/nlepage/go-tarfs" 31 | "golang.org/x/exp/slog" 32 | ) 33 | 34 | var osDict = map[string][]string{ 35 | "darwin": {"darwin", "macos"}, 36 | "windows": {"windows"}, 37 | "linux": {"linux"}, 38 | } 39 | 40 | var archDict = map[string][]string{ 41 | "amd64": {"amd64", "x86_64", "x64"}, 42 | "arm64": {"arm64", "aarch64"}, 43 | } 44 | 45 | var supportContentType = []string{ 46 | // zip 47 | "application/zip", 48 | "application/x-zip-compressed", 49 | // tar.gz 50 | "application/gzip", 51 | "application/x-gtar", 52 | "application/x-gzip", 53 | // tar.bz2 54 | "application/x-bzip2", 55 | // binary 56 | "application/octet-stream", 57 | } 58 | 59 | const versionLatest = "latest" 60 | 61 | type AssetOption struct { 62 | Match string 63 | Version string 64 | OS string 65 | Arch string 66 | Strict bool 67 | SkipContentTypeCheck bool 68 | Checksum string 69 | VerifyAttestation bool // Enable attestation verification 70 | AttestationFlags string // Additional flags for gh attestation verify 71 | } 72 | 73 | func GetReleaseAsset(ctx context.Context, owner, repo string, opt *AssetOption) (*releaseAsset, fs.FS, error) { 74 | c, err := newClient(ctx, owner, repo) 75 | if err != nil { 76 | return nil, nil, err 77 | } 78 | assets, err := c.getReleaseAssets(ctx, opt) 79 | if err != nil { 80 | return nil, nil, err 81 | } 82 | a, err := detectAsset(assets, opt) 83 | if err != nil { 84 | return nil, nil, err 85 | } 86 | b, err := c.downloadAsset(ctx, a) 87 | if err != nil { 88 | return nil, nil, err 89 | } 90 | 91 | if opt != nil { 92 | if err := checksum(b, opt.Checksum); err != nil { 93 | return nil, nil, err 94 | } 95 | 96 | // Add attestation verification 97 | if opt.VerifyAttestation { 98 | // Create a temporary file for the downloaded asset 99 | tmpFile, err := os.CreateTemp("", fmt.Sprintf("%s-%s-*", repo, a.Name)) 100 | if err != nil { 101 | return nil, nil, fmt.Errorf("failed to create temp file for attestation verification: %w", err) 102 | } 103 | defer os.Remove(tmpFile.Name()) 104 | defer tmpFile.Close() 105 | 106 | if _, err := tmpFile.Write(b); err != nil { 107 | return nil, nil, fmt.Errorf("failed to write to temp file: %w", err) 108 | } 109 | 110 | // Verify attestation 111 | if err := verifyAttestation(ctx, tmpFile.Name(), opt.AttestationFlags); err != nil { 112 | return nil, nil, err 113 | } 114 | } 115 | } 116 | 117 | fsys, err := makeFS(ctx, b, repo, a.Name, []string{a.ContentType, http.DetectContentType(b)}) 118 | if err != nil { 119 | return nil, nil, err 120 | } 121 | return a, fsys, nil 122 | } 123 | 124 | // verifyAttestation verifies the attestation of an artifact using gh attestation verify. 125 | func verifyAttestation(ctx context.Context, artifactPath string, additionalFlags string) error { 126 | // Check if gh CLI is installed 127 | if _, err := exec.LookPath("gh"); err != nil { 128 | return fmt.Errorf("gh CLI not found: %w", err) 129 | } 130 | 131 | // Build the base command 132 | baseCmd := fmt.Sprintf("gh attestation verify %s", artifactPath) 133 | 134 | // Add any additional flags 135 | fullCmd := baseCmd 136 | if additionalFlags != "" { 137 | fullCmd = fmt.Sprintf("%s %s", baseCmd, additionalFlags) 138 | } 139 | 140 | slog.Info("Running attestation verification", slog.String("command", fullCmd)) 141 | 142 | // Split the command into parts for exec.Command 143 | cmdParts := strings.Fields(fullCmd) 144 | cmd := exec.CommandContext(ctx, cmdParts[0], cmdParts[1:]...) //nolint:gosec 145 | 146 | // Force TTY output for gh attestation verify command 147 | cmd.Env = append(os.Environ(), "GH_FORCE_TTY=1") 148 | 149 | output, err := cmd.CombinedOutput() 150 | if err != nil { 151 | return fmt.Errorf("attestation verification failed: %s: %s", err, string(output)) 152 | } 153 | 154 | slog.Info("Attestation verification successful", 155 | slog.String("artifact", artifactPath), 156 | slog.String("output", string(output))) 157 | 158 | return nil 159 | } 160 | 161 | func DetectHostOwnerRepo(ownerrepo string) (string, string, string, error) { 162 | var host, owner, repo string 163 | if ownerrepo == "" { 164 | r, err := repository.Current() 165 | if err != nil { 166 | return "", "", "", err 167 | } 168 | host = r.Host 169 | owner = r.Owner 170 | repo = r.Name 171 | } else { 172 | r, err := repository.Parse(ownerrepo) 173 | if err != nil { 174 | return "", "", "", err 175 | } 176 | host = r.Host 177 | owner = r.Owner 178 | repo = r.Name 179 | } 180 | return host, owner, repo, nil 181 | } 182 | 183 | func detectAsset(assets []*releaseAsset, opt *AssetOption) (*releaseAsset, error) { 184 | slog.Info("Detect the most appropriate asset from all assets") 185 | var ( 186 | od, ad, om *regexp.Regexp 187 | err error 188 | ) 189 | if opt != nil && opt.Match != "" { 190 | om, err = regexp.Compile(opt.Match) 191 | if err != nil { 192 | return nil, err 193 | } 194 | } 195 | if opt != nil && opt.OS != "" { 196 | od = getDictRegexp(opt.OS, osDict) 197 | } else { 198 | od = getDictRegexp(runtime.GOOS, osDict) 199 | } 200 | if opt != nil && opt.Arch != "" { 201 | ad = getDictRegexp(opt.Arch, archDict) 202 | } else { 203 | ad = getDictRegexp(runtime.GOARCH, archDict) 204 | } 205 | 206 | type assetScore struct { 207 | asset *releaseAsset 208 | score int 209 | } 210 | assetScores := []*assetScore{} 211 | for _, a := range assets { 212 | if (opt == nil || !opt.SkipContentTypeCheck) && a.ContentType != "" && !contains(supportContentType, a.ContentType) { 213 | slog.Info("Skip", 214 | slog.String("name", a.Name), 215 | slog.String("reason", "Unsupported content type"), 216 | slog.String("content type", a.ContentType), 217 | slog.String("support content type", fmt.Sprintf("%v", supportContentType))) 218 | continue 219 | } 220 | as := &assetScore{ 221 | asset: a, 222 | score: 0, 223 | } 224 | if om != nil && om.MatchString(a.Name) { 225 | slog.Info("it matched --match", slog.String("name", a.Name), slog.String("match", om.String())) 226 | as.score += 13 227 | } 228 | assetScores = append(assetScores, as) 229 | // os 230 | if od.MatchString(a.Name) { 231 | as.score += 7 232 | } 233 | // arch 234 | if ad.MatchString(a.Name) { 235 | as.score += 3 236 | } 237 | // content type 238 | if a.ContentType == "application/octet-stream" { 239 | as.score += 1 240 | } 241 | if opt != nil && opt.Strict && om != nil { 242 | slog.Info("Set score", slog.String("name", a.Name), slog.Int("score", as.score)) 243 | } 244 | } 245 | if opt != nil && opt.Strict && om != nil { 246 | return nil, fmt.Errorf("no matching assets found: %s", opt.Match) 247 | } 248 | if len(assetScores) == 0 { 249 | return nil, errors.New("no matching assets found") 250 | } 251 | 252 | sort.Slice(assetScores, func(i, j int) bool { 253 | return assetScores[i].score > assetScores[j].score 254 | }) 255 | 256 | if opt != nil && opt.Strict && assetScores[0].score < 10 { 257 | return nil, fmt.Errorf("no matching assets found for OS/Arch: %s/%s", opt.OS, opt.Arch) 258 | } 259 | slog.Info("Select the one with the highest score", slog.String("name", assetScores[0].asset.Name), slog.Int("score", assetScores[0].score)) 260 | return assetScores[0].asset, nil 261 | } 262 | 263 | func getDictRegexp(key string, dict map[string][]string) *regexp.Regexp { 264 | for k, d := range dict { 265 | if strings.ToLower(key) == k { 266 | return regexp.MustCompile(fmt.Sprintf("(?i)(%s)", strings.Join(d, "|"))) 267 | } 268 | } 269 | return regexp.MustCompile(fmt.Sprintf("(?i)(%s)", strings.ToLower(key))) 270 | } 271 | 272 | func contains(s []string, e string) bool { 273 | for _, v := range s { 274 | if e == v { 275 | return true 276 | } 277 | } 278 | return false 279 | } 280 | 281 | func makeFS(ctx context.Context, b []byte, repo, name string, contentTypes []string) (fs.FS, error) { 282 | switch { 283 | case matchContentTypes([]string{"application/zip", "application/x-zip-compressed"}, contentTypes): 284 | return zip.NewReader(bytes.NewReader(b), int64(len(b))) 285 | case matchContentTypes([]string{"application/gzip", "application/x-gzip"}, contentTypes): 286 | gr, err := gzip.NewReader(bytes.NewReader(b)) 287 | if err != nil { 288 | return nil, err 289 | } 290 | defer gr.Close() 291 | if strings.HasSuffix(name, ".tar.gz") { 292 | fsys, err := tarfs.New(gr) 293 | if err != nil { 294 | return nil, err 295 | } 296 | return fsys, nil 297 | } 298 | b, err := io.ReadAll(gr) 299 | if err != nil { 300 | return nil, err 301 | } 302 | fsys := fstest.MapFS{} 303 | fsys[repo] = &fstest.MapFile{ 304 | Data: b, 305 | Mode: fs.ModePerm, 306 | ModTime: time.Now(), 307 | } 308 | return fsys, nil 309 | case matchContentTypes([]string{"application/x-bzip2"}, contentTypes): 310 | br := bzip2.NewReader(bytes.NewReader(b)) 311 | if strings.HasSuffix(name, ".tar.bz2") { 312 | fsys, err := tarfs.New(br) 313 | if err != nil { 314 | return nil, err 315 | } 316 | return fsys, nil 317 | } 318 | b, err := io.ReadAll(br) 319 | if err != nil { 320 | return nil, err 321 | } 322 | fsys := fstest.MapFS{} 323 | fsys[repo] = &fstest.MapFile{ 324 | Data: b, 325 | Mode: fs.ModePerm, 326 | ModTime: time.Now(), 327 | } 328 | return fsys, nil 329 | case matchContentTypes([]string{"application/octet-stream"}, contentTypes): 330 | fsys := fstest.MapFS{} 331 | fsys[repo] = &fstest.MapFile{ 332 | Data: b, 333 | Mode: fs.ModePerm, 334 | ModTime: time.Now(), 335 | } 336 | return fsys, nil 337 | default: 338 | return nil, fmt.Errorf("unsupport content types: %s", contentTypes) 339 | } 340 | } 341 | 342 | func matchContentTypes(m, ct []string) bool { 343 | for _, v := range m { 344 | for _, vv := range ct { 345 | if v == vv { 346 | return true 347 | } 348 | } 349 | } 350 | return false 351 | } 352 | 353 | func checksum(b []byte, c string) error { 354 | if c == "" { 355 | return nil // No checksum verification needed 356 | } 357 | 358 | var ( 359 | alg string 360 | want string 361 | ) 362 | 363 | // Check if the format is "algorithm:hash" 364 | parts := strings.SplitN(c, ":", 2) 365 | if len(parts) == 2 { 366 | alg = strings.ToLower(parts[0]) 367 | want = strings.ToLower(parts[1]) 368 | } else { 369 | // If no alg is specified, try to determine it based on the length of the checksum 370 | want = strings.ToLower(c) 371 | // Try to match based on length and value 372 | switch len(want) { 373 | case 8: // CRC32 374 | alg = "crc32" 375 | case 32: // MD5 376 | alg = "md5" 377 | case 40: // SHA-1 378 | alg = "sha1" 379 | case 64: // SHA-256 380 | alg = "sha256" 381 | case 128: // SHA-512 382 | alg = "sha512" 383 | } 384 | } 385 | 386 | var got string 387 | switch alg { 388 | case "crc32": 389 | got = fmt.Sprintf("%08x", crc32.ChecksumIEEE(b)) 390 | case "md5": 391 | sum := md5.Sum(b) //nolint:gosec 392 | got = hex.EncodeToString(sum[:]) 393 | case "sha1": 394 | sum := sha1.Sum(b) //nolint:gosec 395 | got = hex.EncodeToString(sum[:]) 396 | case "sha256": 397 | sum := sha256.Sum256(b) 398 | got = hex.EncodeToString(sum[:]) 399 | case "sha512": 400 | sum := sha512.Sum512(b) 401 | got = hex.EncodeToString(sum[:]) 402 | default: 403 | return fmt.Errorf("unsupported alg: %s", alg) 404 | } 405 | 406 | if got != want { 407 | return fmt.Errorf("checksum mismatch: expected=%s, calculated=%s", want, got) 408 | } 409 | return nil 410 | } 411 | -------------------------------------------------------------------------------- /gh/gh_test.go: -------------------------------------------------------------------------------- 1 | package gh 2 | 3 | import ( 4 | "context" 5 | "io/fs" 6 | "os" 7 | "testing" 8 | 9 | "github.com/k1LoW/go-github-client/v67/factory" 10 | ) 11 | 12 | func TestMain(m *testing.M) { 13 | os.Setenv("GH_CONFIG_DIR", "/tmp") // Disable reading credentials from config 14 | m.Run() 15 | } 16 | 17 | func TestGetReleaseAsset(t *testing.T) { 18 | tests := []struct { 19 | owner string 20 | repo string 21 | opt *AssetOption 22 | wantFile string 23 | useToken bool 24 | }{ 25 | {"k1LoW", "tbls", &AssetOption{}, "tbls", true}, 26 | {"k1LoW", "tbls", &AssetOption{}, "tbls", false}, 27 | {"k1LoW", "tbls", &AssetOption{Version: "v1.60.0"}, "tbls", true}, 28 | {"k1LoW", "tbls", &AssetOption{Version: "v1.60.0"}, "tbls", false}, 29 | {"k1LoW", "tbls", &AssetOption{Version: "v1.84.0", OS: "linux", Arch: "amd64", Checksum: "83f35a07fd2a00c2aa360a47edca6d261f5208186911977eff39097151fc57d5"}, "tbls", false}, 30 | } 31 | ctx := context.Background() 32 | token, _, _, _ := factory.GetTokenAndEndpoints() 33 | for _, tt := range tests { 34 | if tt.useToken { 35 | t.Setenv("GITHUB_TOKEN", token) 36 | } else { 37 | t.Setenv("GITHUB_TOKEN", "") 38 | t.Setenv("GH_TOKEN", "") 39 | } 40 | _, fsys, err := GetReleaseAsset(ctx, tt.owner, tt.repo, tt.opt) 41 | if err != nil { 42 | t.Error(err) 43 | continue 44 | } 45 | if _, err := fs.ReadFile(fsys, tt.wantFile); err != nil { 46 | t.Error(err) 47 | } 48 | } 49 | } 50 | 51 | func TestChecksum(t *testing.T) { 52 | // Test data 53 | testData := []byte("hello world") 54 | 55 | tests := []struct { 56 | name string 57 | data []byte 58 | checksumStr string 59 | wantErr bool 60 | }{ 61 | // Empty checksum string (should return nil) 62 | { 63 | name: "Empty checksum", 64 | data: testData, 65 | checksumStr: "", 66 | wantErr: false, 67 | }, 68 | 69 | // Explicit algorithm specification (algorithm:hash format) 70 | // SHA-256 tests 71 | { 72 | name: "SHA-256 explicit - correct", 73 | data: testData, 74 | checksumStr: "sha256:b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", 75 | wantErr: false, 76 | }, 77 | { 78 | name: "SHA-256 explicit - incorrect", 79 | data: testData, 80 | checksumStr: "sha256:incorrect_hash", 81 | wantErr: true, 82 | }, 83 | 84 | // SHA-512 tests 85 | { 86 | name: "SHA-512 explicit - correct", 87 | data: testData, 88 | checksumStr: "sha512:309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f", 89 | wantErr: false, 90 | }, 91 | { 92 | name: "SHA-512 explicit - incorrect", 93 | data: testData, 94 | checksumStr: "sha512:incorrect_hash", 95 | wantErr: true, 96 | }, 97 | 98 | // SHA-1 tests 99 | { 100 | name: "SHA-1 explicit - correct", 101 | data: testData, 102 | checksumStr: "sha1:2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", 103 | wantErr: false, 104 | }, 105 | { 106 | name: "SHA-1 explicit - incorrect", 107 | data: testData, 108 | checksumStr: "sha1:incorrect_hash", 109 | wantErr: true, 110 | }, 111 | 112 | // MD5 tests 113 | { 114 | name: "MD5 explicit - correct", 115 | data: testData, 116 | checksumStr: "md5:5eb63bbbe01eeed093cb22bb8f5acdc3", 117 | wantErr: false, 118 | }, 119 | { 120 | name: "MD5 explicit - incorrect", 121 | data: testData, 122 | checksumStr: "md5:incorrect_hash", 123 | wantErr: true, 124 | }, 125 | 126 | // CRC32 tests 127 | { 128 | name: "CRC32 explicit - correct", 129 | data: testData, 130 | checksumStr: "crc32:0d4a1185", 131 | wantErr: false, 132 | }, 133 | { 134 | name: "CRC32 explicit - incorrect", 135 | data: testData, 136 | checksumStr: "crc32:incorrect", 137 | wantErr: true, 138 | }, 139 | 140 | // Invalid algorithm 141 | { 142 | name: "Invalid algorithm", 143 | data: testData, 144 | checksumStr: "invalid:hash", 145 | wantErr: true, 146 | }, 147 | 148 | // Automatic algorithm detection 149 | // SHA-256 auto-detection 150 | { 151 | name: "SHA-256 auto-detection - correct", 152 | data: testData, 153 | checksumStr: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", 154 | wantErr: false, 155 | }, 156 | { 157 | name: "SHA-256 auto-detection - incorrect", 158 | data: testData, 159 | checksumStr: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde8", // Changed last digit 160 | wantErr: true, 161 | }, 162 | 163 | // SHA-512 auto-detection 164 | { 165 | name: "SHA-512 auto-detection - correct", 166 | data: testData, 167 | checksumStr: "309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f", 168 | wantErr: false, 169 | }, 170 | { 171 | name: "SHA-512 auto-detection - incorrect", 172 | data: testData, 173 | checksumStr: "309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76e", // Changed last digit 174 | wantErr: true, 175 | }, 176 | 177 | // SHA-1 auto-detection 178 | { 179 | name: "SHA-1 auto-detection - correct", 180 | data: testData, 181 | checksumStr: "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", 182 | wantErr: false, 183 | }, 184 | { 185 | name: "SHA-1 auto-detection - incorrect", 186 | data: testData, 187 | checksumStr: "2aae6c35c94fcfb415dbe95f408b9ce91ee846ec", // Changed last digit 188 | wantErr: true, 189 | }, 190 | 191 | // MD5 auto-detection 192 | { 193 | name: "MD5 auto-detection - correct", 194 | data: testData, 195 | checksumStr: "5eb63bbbe01eeed093cb22bb8f5acdc3", 196 | wantErr: false, 197 | }, 198 | { 199 | name: "MD5 auto-detection - incorrect", 200 | data: testData, 201 | checksumStr: "5eb63bbbe01eeed093cb22bb8f5acdc2", // Changed last digit 202 | wantErr: true, 203 | }, 204 | 205 | // CRC32 auto-detection 206 | { 207 | name: "CRC32 auto-detection - correct", 208 | data: testData, 209 | checksumStr: "0d4a1185", 210 | wantErr: false, 211 | }, 212 | { 213 | name: "CRC32 auto-detection - incorrect", 214 | data: testData, 215 | checksumStr: "0d4a1184", // Changed last digit 216 | wantErr: true, 217 | }, 218 | 219 | // Invalid length for auto-detection 220 | { 221 | name: "Invalid length for auto-detection", 222 | data: testData, 223 | checksumStr: "invalid_length_hash", 224 | wantErr: true, 225 | }, 226 | } 227 | 228 | for _, tt := range tests { 229 | t.Run(tt.name, func(t *testing.T) { 230 | err := checksum(tt.data, tt.checksumStr) 231 | if (err != nil) != tt.wantErr { 232 | t.Errorf("checksum() error = %v, wantErr %v", err, tt.wantErr) 233 | } 234 | }) 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/k1LoW/gh-setup 2 | 3 | go 1.23.8 4 | 5 | require ( 6 | github.com/cli/go-gh/v2 v2.12.1 7 | github.com/google/go-cmp v0.7.0 8 | github.com/google/go-github/v67 v67.0.0 9 | github.com/h2non/filetype v1.1.3 10 | github.com/k1LoW/go-github-client/v67 v67.0.17 11 | github.com/nlepage/go-tarfs v1.2.1 12 | github.com/spf13/cobra v1.9.1 13 | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df 14 | ) 15 | 16 | require ( 17 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect 18 | github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 // indirect 19 | github.com/cli/safeexec v1.0.0 // indirect 20 | github.com/cli/shurcooL-graphql v0.0.4 // indirect 21 | github.com/golang-jwt/jwt/v4 v4.5.2 // indirect 22 | github.com/google/go-github/v71 v71.0.0 // indirect 23 | github.com/google/go-querystring v1.1.0 // indirect 24 | github.com/henvic/httpretty v0.0.6 // indirect 25 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 26 | github.com/kr/pretty v0.3.1 // indirect 27 | github.com/lucasb-eyer/go-colorful v1.2.0 // indirect 28 | github.com/mattn/go-isatty v0.0.20 // indirect 29 | github.com/muesli/termenv v0.16.0 // indirect 30 | github.com/rivo/uniseg v0.4.7 // indirect 31 | github.com/spf13/pflag v1.0.6 // indirect 32 | github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect 33 | golang.org/x/sys v0.32.0 // indirect 34 | golang.org/x/term v0.30.0 // indirect 35 | golang.org/x/text v0.24.0 // indirect 36 | gopkg.in/yaml.v3 v3.0.1 // indirect 37 | ) 38 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= 2 | github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= 3 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= 4 | github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= 5 | github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 h1:7r2rPUM04rgszMP0U1UZ1M5VoVVIlsaBSnpABfYxcQY= 6 | github.com/bradleyfalzon/ghinstallation/v2 v2.15.0/go.mod h1:PoH9Vhy82OeRFZfxsVrk3mfQhVkEzou9OOwPOsEhiXE= 7 | github.com/cli/go-gh/v2 v2.12.1 h1:SVt1/afj5FRAythyMV3WJKaUfDNsxXTIe7arZbwTWKA= 8 | github.com/cli/go-gh/v2 v2.12.1/go.mod h1:+5aXmEOJsH9fc9mBHfincDwnS02j2AIA/DsTH0Bk5uw= 9 | github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI= 10 | github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= 11 | github.com/cli/shurcooL-graphql v0.0.4 h1:6MogPnQJLjKkaXPyGqPRXOI2qCsQdqNfUY1QSJu2GuY= 12 | github.com/cli/shurcooL-graphql v0.0.4/go.mod h1:3waN4u02FiZivIV+p1y4d0Jo1jc6BViMA73C+sZo2fk= 13 | github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= 14 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 15 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 16 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 17 | github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= 18 | github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= 19 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 20 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 21 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 22 | github.com/google/go-github/v64 v64.0.0 h1:4G61sozmY3eiPAjjoOHponXDBONm+utovTKbyUb2Qdg= 23 | github.com/google/go-github/v64 v64.0.0/go.mod h1:xB3vqMQNdHzilXBiO2I+M7iEFtHf+DP/omBOv6tQzVo= 24 | github.com/google/go-github/v67 v67.0.0 h1:g11NDAmfaBaCO8qYdI9fsmbaRipHNWRIU/2YGvlh4rg= 25 | github.com/google/go-github/v67 v67.0.0/go.mod h1:zH3K7BxjFndr9QSeFibx4lTKkYS3K9nDanoI1NjaOtY= 26 | github.com/google/go-github/v71 v71.0.0 h1:Zi16OymGKZZMm8ZliffVVJ/Q9YZreDKONCr+WUd0Z30= 27 | github.com/google/go-github/v71 v71.0.0/go.mod h1:URZXObp2BLlMjwu0O8g4y6VBneUj2bCHgnI8FfgZ51M= 28 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 29 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 30 | github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= 31 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 32 | github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= 33 | github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= 34 | github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= 35 | github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= 36 | github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTxs= 37 | github.com/henvic/httpretty v0.0.6/go.mod h1:X38wLjWXHkXT7r2+uK8LjCMne9rsuNaBLJ+5cU2/Pmo= 38 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 39 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 40 | github.com/k1LoW/go-github-client/v67 v67.0.17 h1:sZfwnhVL19X3YQek6lqV9sB2DDMYHVAS0tjTmyDf0WQ= 41 | github.com/k1LoW/go-github-client/v67 v67.0.17/go.mod h1:+W9kQmf/4pX1NEB/E4p2rsT56cgijV+GpsbRNR0llfI= 42 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 43 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 44 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 45 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 46 | github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= 47 | github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= 48 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 49 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 50 | github.com/migueleliasweb/go-github-mock v1.1.0 h1:GKaOBPsrPGkAKgtfuWY8MclS1xR6MInkx1SexJucMwE= 51 | github.com/migueleliasweb/go-github-mock v1.1.0/go.mod h1:pYe/XlGs4BGMfRY4vmeixVsODHnVDDhJ9zoi0qzSMHc= 52 | github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= 53 | github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= 54 | github.com/nlepage/go-tarfs v1.2.1 h1:o37+JPA+ajllGKSPfy5+YpsNHDjZnAoyfvf5GsUa+Ks= 55 | github.com/nlepage/go-tarfs v1.2.1/go.mod h1:rno18mpMy9aEH1IiJVftFsqPyIpwqSUiAOpJYjlV2NA= 56 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 57 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 58 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 59 | github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= 60 | github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 61 | github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= 62 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 63 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 64 | github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= 65 | github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= 66 | github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= 67 | github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 68 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= 69 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 70 | github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8= 71 | github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI= 72 | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= 73 | golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= 74 | golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 75 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 76 | golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= 77 | golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 78 | golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= 79 | golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= 80 | golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= 81 | golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 82 | golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= 83 | golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 84 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 85 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 86 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 87 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 88 | gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= 89 | gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= 90 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 91 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 92 | -------------------------------------------------------------------------------- /scripts/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -l 2 | 3 | gh-setup $@ 4 | -------------------------------------------------------------------------------- /scripts/install-gh-setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | token=${GH_SETUP_GITHUB_TOKEN} 5 | if [ -z "${token}" ]; then 6 | token=${GITHUB_TOKEN} 7 | fi 8 | repo="k1LoW/gh-setup" 9 | tag=${GH_SETUP_GH_SETUP_VERSION} 10 | if [ -z "${tag}" ]; then 11 | tag="$(curl -sL -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${token}" https://api.github.com/repos/${repo}/releases/latest | grep tag_name | awk -F':' '{print $2}' | awk -F'\"' '{print $2}')" 12 | fi 13 | if [[ "${tag}" == "latest" ]]; then 14 | tag="$(curl -sL -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${token}" https://api.github.com/repos/${repo}/releases/latest | grep tag_name | awk -F':' '{print $2}' | awk -F'\"' '{print $2}')" 15 | fi 16 | arch="$(uname -m)" 17 | 18 | if uname -a | grep Msys > /dev/null; then 19 | if [ $arch = "x86_64" ]; then 20 | exe="gh-setup_${tag}_windows_amd64.exe" 21 | fi 22 | bin="${TEMP}/gh-setup" 23 | elif uname -a | grep Darwin > /dev/null; then 24 | if [ $arch = "x86_64" ]; then 25 | exe="gh-setup_${tag}_darwin_amd64" 26 | elif [ $arch = "arm64" ]; then 27 | exe="gh-setup_${tag}_darwin_arm64" 28 | fi 29 | bin="${TMPDIR}gh-setup" 30 | elif uname -a | grep Linux > /dev/null; then 31 | if [ $arch = "x86_64" ]; then 32 | exe="gh-setup_${tag}_linux_amd64" 33 | elif [ $arch = "arm64" ] || [ $arch = "aarch64" ]; then 34 | exe="gh-setup_${tag}_linux_arm64" 35 | fi 36 | bin="/tmp/gh-setup" 37 | 38 | # If on a container or a self-hosted runner, install curl 39 | if !(type "curl" > /dev/null 2>&1); then 40 | if (type "apt-get" > /dev/null 2>&1); then 41 | apt-get update || true 42 | apt-get -y install curl || true 43 | elif (type "yum" > /dev/null 2>&1); then 44 | yum install -y curl || true 45 | elif (type "apk" > /dev/null 2>&1); then 46 | apk add --no-cache curl || true 47 | fi 48 | fi 49 | fi 50 | 51 | # download 52 | curl -sL -o ${bin} https://github.com/k1LoW/gh-setup/releases/download/${tag}/${exe} 53 | chmod +x ${bin} 54 | ${bin} version 55 | echo "bin=${bin}" >> ${GITHUB_OUTPUT} 56 | -------------------------------------------------------------------------------- /scripts/run-gh-setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | bin="${GH_SETUP_BIN}" 5 | token=${GH_SETUP_GITHUB_TOKEN} 6 | if [ -z "${token}" ]; then 7 | token=${GITHUB_TOKEN} 8 | fi 9 | export GITHUB_TOKEN=${token} 10 | 11 | repo=${GH_SETUP_REPO} 12 | version=${GH_SETUP_VERSION} 13 | os=${GH_SETUP_OS} 14 | arch=${GH_SETUP_ARCH} 15 | match=${GH_SETUP_MATCH} 16 | bin_dir=${GH_SETUP_BIN_DIR} 17 | bin_match=${GH_SETUP_BIN_MATCH} 18 | checksum=${GH_SETUP_CHECKSUM} 19 | force=${GH_SETUP_FORCE} 20 | strict=${GH_SETUP_STRICT} 21 | skip_content_type_check=${GH_SETUP_SKIP_CONTENT_TYPE_CHECK} 22 | verify_attestation=${GH_SETUP_VERIFY_ATTESTATION} 23 | attestation_flags=${GH_SETUP_ATTESTATION_FLAGS} 24 | 25 | boolopts="" 26 | 27 | if [ ! -z "${force}" ]; then 28 | boolopts+=" --force" 29 | fi 30 | 31 | if [ ! -z "${strict}" ]; then 32 | boolopts+=" --strict" 33 | fi 34 | 35 | if [ ! -z "${skip_content_type_check}" ]; then 36 | boolopts+=" --skip-content-type-check" 37 | fi 38 | 39 | if [ ! -z "${verify_attestation}" ]; then 40 | boolopts+=" --verify-attestation" 41 | fi 42 | 43 | attestation_flags_opt="" 44 | if [ ! -z "${attestation_flags}" ]; then 45 | attestation_flags_opt=" --attestation-flags=\"${attestation_flags}\"" 46 | fi 47 | 48 | ${bin} --repo ${repo} --version=${version} --os=${os} --arch=${arch} --match=${match} --bin-dir=${bin_dir} --bin-match=${bin_match} --checksum=${checksum}${boolopts}${attestation_flags_opt} 49 | -------------------------------------------------------------------------------- /setup/setup.go: -------------------------------------------------------------------------------- 1 | package setup 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/fs" 7 | "net/http" 8 | "os" 9 | "path/filepath" 10 | "regexp" 11 | "sort" 12 | "strconv" 13 | "strings" 14 | 15 | "github.com/h2non/filetype" 16 | "golang.org/x/exp/slog" 17 | ) 18 | 19 | type Option struct { 20 | BinDir string 21 | BinMatch string 22 | Force bool 23 | } 24 | 25 | func Bin(fsys fs.FS, opt *Option) (map[string]string, error) { 26 | var ( 27 | bd string 28 | bm *regexp.Regexp 29 | force bool 30 | err error 31 | ) 32 | m := map[string]string{} 33 | if opt != nil { 34 | force = opt.Force 35 | bd = opt.BinDir 36 | if opt.BinMatch != "" { 37 | bm, err = regexp.Compile(opt.BinMatch) 38 | if err != nil { 39 | return nil, err 40 | } 41 | } 42 | } 43 | if bd == "" { 44 | bd, err = binDir() 45 | if err != nil { 46 | return nil, err 47 | } 48 | } 49 | if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { 50 | slog.Info("Extract target", slog.String("path", path)) 51 | if err != nil { 52 | return err 53 | } 54 | if d.IsDir() { 55 | return nil 56 | } 57 | if bm != nil { 58 | if !bm.MatchString(path) { 59 | slog.Info("Skip", slog.String("Reason", "No match for --bin-match"), slog.String("path", path), slog.String("match", bm.String())) 60 | return nil 61 | } 62 | } else { 63 | for _, i := range ignoreBinnameKeywords { 64 | if strings.Contains(filepath.ToSlash(strings.ToLower(path)), filepath.ToSlash(strings.ToLower(i))) { 65 | slog.Info("Skip", slog.String("Reason", "Matched the ignore filename keywords"), slog.String("path", path), slog.String("list", fmt.Sprintf("%v", ignoreBinnameKeywords))) 66 | return nil 67 | } 68 | } 69 | } 70 | 71 | b, err := fs.ReadFile(fsys, path) 72 | if err != nil { 73 | return err 74 | } 75 | 76 | if !isBinary(b) { 77 | slog.Info("Skip", slog.String("Reason", "Not determined to be a binary file"), slog.String("path", path)) 78 | return nil 79 | } 80 | 81 | slog.Info("Determine as a binary file", slog.String("path", path)) 82 | perm := "0755" 83 | perm32, err := strconv.ParseUint(perm, 8, 32) 84 | if err != nil { 85 | return err 86 | } 87 | bp := filepath.Join(bd, filepath.Base(path)) 88 | slog.Info("Write file", slog.String("bin path", bp)) 89 | if _, err := os.Stat(bp); err == nil && !force { 90 | return fmt.Errorf("%s already exist", bp) 91 | } 92 | if err := os.WriteFile(bp, b, os.FileMode(perm32)); err != nil { 93 | return err 94 | } 95 | m[path] = bp 96 | return nil 97 | }); err != nil { 98 | return nil, err 99 | } 100 | return m, nil 101 | } 102 | 103 | var priorityPaths = []string{"/usr/local/bin", "/usr/bin"} 104 | var ignorePathKeywords = []string{ 105 | "homebrew", 106 | "X11", 107 | "/usr/local/opt", 108 | "sbin", 109 | "perl", 110 | "git", 111 | "/go/", 112 | ".asdf", 113 | ".cargo", 114 | ".dotnet", 115 | ".ghcup", 116 | ".yarn", 117 | "/Library/", 118 | "hostedtoolcache", 119 | } 120 | var ignoreBinnameKeywords = []string{ 121 | "CHANGELOG", 122 | "README", 123 | "CREDIT", 124 | "LICENSE", 125 | } 126 | 127 | func binDir() (string, error) { 128 | if os.Getenv("PATH") == "" { 129 | return "", errors.New("env PATH not set") 130 | } 131 | paths, err := sortPaths(filepath.SplitList(os.Getenv("PATH"))) 132 | if err != nil { 133 | return "", err 134 | } 135 | for _, p := range paths { 136 | f := filepath.Join(p, "gh-setup-tmp") 137 | if err := os.WriteFile(f, []byte("test"), os.ModePerm); err == nil { //nolint:gosec 138 | if err := os.Remove(f); err != nil { 139 | return "", err 140 | } 141 | return p, nil 142 | } 143 | } 144 | return "", fmt.Errorf("could not find a writable bin path: %s", strings.Join(paths, string(filepath.ListSeparator))) 145 | } 146 | 147 | func sortPaths(paths []string) ([]string, error) { 148 | home, err := os.UserHomeDir() 149 | if err != nil { 150 | return nil, err 151 | } 152 | filtered := []string{} 153 | L: 154 | for _, p := range paths { 155 | for _, i := range ignorePathKeywords { 156 | if strings.Contains(filepath.ToSlash(strings.ToLower(p)), filepath.ToSlash(strings.ToLower(i))) { 157 | continue L 158 | } 159 | } 160 | filtered = append(filtered, p) 161 | } 162 | sort.Slice(filtered, func(i, j int) bool { 163 | pi := filtered[i] 164 | pj := filtered[j] 165 | switch { 166 | case strings.HasPrefix(pi, home) && !strings.HasPrefix(pj, home): 167 | return true 168 | case !strings.HasPrefix(pi, home) && strings.HasPrefix(pj, home): 169 | return false 170 | case strings.HasPrefix(pi, home) && strings.HasPrefix(pj, home): 171 | return pi < pj 172 | case hasPrefixes(pi, priorityPaths) >= 0 && hasPrefixes(pj, priorityPaths) < 0: 173 | return true 174 | case hasPrefixes(pi, priorityPaths) < 0 && hasPrefixes(pj, priorityPaths) >= 0: 175 | return false 176 | case hasPrefixes(pi, priorityPaths) >= 0 && hasPrefixes(pj, priorityPaths) >= 0: 177 | return hasPrefixes(pi, priorityPaths) < hasPrefixes(pj, priorityPaths) 178 | } 179 | return false 180 | }) 181 | 182 | return filtered, nil 183 | } 184 | 185 | func hasPrefixes(in string, ps []string) int { 186 | for i, p := range ps { 187 | if strings.HasPrefix(in, p) { 188 | return i 189 | } 190 | } 191 | return -1 192 | } 193 | 194 | func isBinary(b []byte) bool { 195 | // FIXME: On Windows, it can't be detected at all. 196 | const binaryContentType = "application/octet-stream" 197 | contentType := http.DetectContentType(b) 198 | slog.Info("Detect content type", slog.String("content type", contentType)) 199 | if contentType == binaryContentType { 200 | return true 201 | } 202 | typ, err := filetype.Match(b) 203 | if err != nil { 204 | return false 205 | } 206 | slog.Info("Detect file type", slog.String("file type", fmt.Sprintf("%v", typ))) 207 | return typ == filetype.Unknown 208 | } 209 | -------------------------------------------------------------------------------- /setup/setup_test.go: -------------------------------------------------------------------------------- 1 | package setup 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/google/go-cmp/cmp" 8 | ) 9 | 10 | func TestSortPaths(t *testing.T) { 11 | t.Setenv("HOME", "/Users/k1low") 12 | 13 | tests := []struct { 14 | paths []string 15 | want []string 16 | }{ 17 | { 18 | []string{"/opt/homebrew/bin", "/usr/local/bin", "/usr/local/sbin", "/usr/bin", "/usr/sbin", "/Users/k1low/.local/bin"}, 19 | []string{"/Users/k1low/.local/bin", "/usr/local/bin", "/usr/bin"}, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(fmt.Sprintf("%s", tt.paths), func(t *testing.T) { 24 | got, err := sortPaths(tt.paths) 25 | if err != nil { 26 | t.Error(err) 27 | } 28 | if diff := cmp.Diff(got, tt.want, nil); diff != "" { 29 | t.Errorf("%s", diff) 30 | } 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | // Name for this. 4 | const Name string = "gh-setup" 5 | 6 | // Version for this. 7 | var Version = "1.11.2" 8 | --------------------------------------------------------------------------------