diff --git a/.badges/main/coverage.svg b/.badges/main/coverage.svg new file mode 100644 index 0000000..3f369c4 --- /dev/null +++ b/.badges/main/coverage.svg @@ -0,0 +1 @@ +coveragecoverage48%48% \ No newline at end of file diff --git a/.github/commitlint.config.mjs b/.github/commitlint.config.mjs deleted file mode 100644 index 51b1c33..0000000 --- a/.github/commitlint.config.mjs +++ /dev/null @@ -1,29 +0,0 @@ -/* Taken from: https://github.com/wagoid/commitlint-github-action/blob/7f0a61df502599e1f1f50880aaa7ec1e2c0592f2/commitlint.config.mjs */ -/* eslint-disable import/no-extraneous-dependencies */ -import { maxLineLength } from '@commitlint/ensure' - -const bodyMaxLineLength = 100 - -const validateBodyMaxLengthIgnoringDeps = (parsedCommit) => { - const { type, scope, body } = parsedCommit - const isDepsCommit = - type === 'chore' && (scope === 'deps' || scope === 'deps-dev') - - return [ - isDepsCommit || !body || maxLineLength(body, bodyMaxLineLength), - `body's lines must not be longer than ${bodyMaxLineLength}`, - ] -} - -export default { - extends: ['@commitlint/config-conventional'], - plugins: ['commitlint-plugin-function-rules'], - rules: { - 'body-max-line-length': [0], - 'function-rules/body-max-line-length': [ - 2, - 'always', - validateBodyMaxLengthIgnoringDeps, - ], - }, -} diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml deleted file mode 100644 index c344a50..0000000 --- a/.github/dependabot.yaml +++ /dev/null @@ -1,44 +0,0 @@ -version: 2 -updates: -- package-ecosystem: github-actions - commit-message: - prefix: chore - include: scope - directory: / - schedule: - interval: monthly - groups: - github-actions: - patterns: - - "*" - update-types: - - "minor" - - "patch" -- package-ecosystem: docker - commit-message: - prefix: chore - include: scope - directory: / - schedule: - interval: monthly - groups: - docker: - patterns: - - "*" - update-types: - - "minor" - - "patch" -- package-ecosystem: gomod - commit-message: - prefix: chore - include: scope - directory: / - schedule: - interval: monthly - groups: - gomod: - patterns: - - "*" - update-types: - - "minor" - - "patch" diff --git a/.github/dependency-review-config.yaml b/.github/dependency-review-config.yaml deleted file mode 100644 index 08389a1..0000000 --- a/.github/dependency-review-config.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# https://github.com/cncf/foundation/blob/main/allowed-third-party-license-policy.md -allow-licenses: -- 'Apache-2.0' -- 'BSD-2-Clause' -- 'BSD-2-Clause-FreeBSD' -- 'BSD-3-Clause' -- 'ISC' -- 'MIT' -- 'PostgreSQL' -- 'Python-2.0' -- 'X11' -- 'Zlib' - -allow-dependencies-licenses: -# this action is GPL-3 but it is only used in CI -# https://github.com/actions/dependency-review-action/issues/530#issuecomment-1638291806 -- pkg:githubactions/vladopajic/go-test-coverage@bcd064e5ceef1ccec5441519eb054263b6a44787 -# this package is MPL-2.0 and has a CNCF exception -# https://github.com/cncf/foundation/blob/9b8c9173c2101c1b4aedad3caf2c0128715133f6/license-exceptions/cncf-exceptions-2022-04-12.json#L43C17-L43C47 -- pkg:golang/github.com/go-sql-driver/mysql diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml deleted file mode 100644 index 95a4c4f..0000000 --- a/.github/workflows/build.yaml +++ /dev/null @@ -1,87 +0,0 @@ -name: build -on: - pull_request: - branches: - - main -permissions: {} -jobs: - build-snapshot: - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 - with: - go-version: stable - - uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0 - id: goreleaser - with: - version: latest - args: build --clean --verbose --single-target --snapshot - - name: tar up binaries - run: tar -cvf dist.tar dist - - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - with: - path: dist.tar - build-image: - permissions: - contents: read - packages: write - runs-on: ubuntu-latest - needs: build-snapshot - strategy: - matrix: - binary: - - go-cli-github - - another-binary - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - - name: untar binaries - run: tar -xvf dist.tar - - name: Login to GHCR - if: github.actor != 'dependabot[bot]' - uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Get Docker metadata - if: github.actor != 'dependabot[bot]' - id: docker_metadata - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0 - with: - images: ghcr.io/${{ github.repository }}/${{ matrix.binary }} - - name: Build and push ${{ matrix.binary }} container image - if: github.actor != 'dependabot[bot]' - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - push: true - tags: ${{ steps.docker_metadata.outputs.tags }} - labels: ${{ steps.docker_metadata.outputs.labels }} - file: Dockerfile - build-args: BINARY=${{ matrix.binary }} - context: dist/${{ matrix.binary }}_linux_amd64_v1 - check-tag: - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - fetch-depth: 0 - - id: ccv - uses: smlx/ccv@7318e2f25a52dcd550e75384b84983973251a1f8 # v0.10.0 - with: - write-tag: false - - run: | - echo "new-tag=$NEW_TAG" - echo "new-tag-version=$NEW_TAG_VERSION" - env: - NEW_TAG: ${{steps.ccv.outputs.new-tag}} - NEW_TAG_VERSION: ${{steps.ccv.outputs.new-tag-version}} diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml deleted file mode 100644 index eb236e9..0000000 --- a/.github/workflows/coverage.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: coverage -on: - push: - branches: - - main -permissions: {} -jobs: - coverage: - permissions: - contents: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 - with: - go-version: stable - - name: Calculate coverage - run: | - go test -v -covermode=atomic -coverprofile=cover.out -coverpkg=./... ./... - - name: Generage coverage badge - uses: vladopajic/go-test-coverage@cc5012c2cfa84542e02b079141958a885861d326 # v2.17.0 - with: - profile: cover.out - local-prefix: github.com/${{ github.repository }} - git-token: ${{ secrets.GITHUB_TOKEN }} - # orphan branch for storing badges - git-branch: badges diff --git a/.github/workflows/dependency-review.yaml b/.github/workflows/dependency-review.yaml deleted file mode 100644 index d9102c1..0000000 --- a/.github/workflows/dependency-review.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: dependency review -on: - pull_request: - branches: - - main - merge_group: - types: - - checks_requested -permissions: {} -jobs: - dependency-review: - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/dependency-review-action@40c09b7dc99638e5ddb0bfd91c1673effc064d8a # v4.8.1 - with: - config-file: .github/dependency-review-config.yaml diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml deleted file mode 100644 index 148fb55..0000000 --- a/.github/workflows/lint.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: lint -on: - pull_request: - branches: - - main - merge_group: - types: - - checks_requested -permissions: {} -jobs: - lint-go: - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 - with: - go-version: stable - - uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 - with: - args: --timeout=180s --enable gocritic - lint-commits: - permissions: - contents: read - pull-requests: read - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - fetch-depth: 0 - - uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6.2.1 - with: - configFile: .github/commitlint.config.mjs - lint-actions: - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: docker://rhysd/actionlint:1.7.0@sha256:601d6faeefa07683a4a79f756f430a1850b34d575d734b1d1324692202bf312e # v1.7.0 - with: - args: -color diff --git a/.github/workflows/ossf-analysis.yaml b/.github/workflows/ossf-analysis.yaml deleted file mode 100644 index eeba1d8..0000000 --- a/.github/workflows/ossf-analysis.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: OSSF scorecard -on: - push: - branches: - - main -permissions: {} -jobs: - ossf-scorecard-analysis: - runs-on: ubuntu-latest - permissions: - contents: read - # Needed if using Code scanning alerts - security-events: write - # Needed for GitHub OIDC token if publish_results is true - id-token: write - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Run analysis - uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 - with: - results_file: results.sarif - results_format: sarif - # Publish the results for public repositories to enable scorecard badges. For more details, see - # https://github.com/ossf/scorecard-action#publishing-results. - # For private repositories, `publish_results` will automatically be set to `false`, regardless - # of the value entered here. - publish_results: true - - name: Upload SARIF results to code scanning - uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v3.29.5 - with: - sarif_file: results.sarif diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 94cf9de..0000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,92 +0,0 @@ -name: release -on: - push: - branches: - - main -permissions: {} -jobs: - release-tag: - permissions: - # create tag - contents: write - runs-on: ubuntu-latest - outputs: - new-tag: ${{ steps.ccv.outputs.new-tag }} - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - fetch-depth: 0 - - name: Bump tag if necessary - id: ccv - uses: smlx/ccv@7318e2f25a52dcd550e75384b84983973251a1f8 # v0.10.0 - release-build: - permissions: - # create release - contents: write - # push docker images to registry - packages: write - # required by attest-build-provenance - id-token: write - attestations: write - needs: release-tag - if: needs.release-tag.outputs.new-tag == 'true' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - fetch-depth: 0 - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 - with: - go-version: stable - - name: Login to GHCR - uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Export SBOM in SPDX JSON format - # https://docs.github.com/en/rest/dependency-graph/sboms?apiVersion=2022-11-28 - run: | - gh api \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/${{ github.repository }}/dependency-graph/sbom > sbom.spdx.json - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0 - id: goreleaser - with: - version: latest - args: release --clean - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # attest artefacts - - uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0 - with: - subject-path: | - dist/*.tar.gz - sbom.spdx.json - # parse artifacts to the format required for image attestation - - run: | - echo "digest=$(echo "$ARTIFACTS" | jq -r '.[]|select(.type=="Docker Manifest")|select(.name|test("go-cli-github:v"))|.extra.Digest')" >> "$GITHUB_OUTPUT" - echo "name=$(echo "$ARTIFACTS" | jq -r '.[]|select(.type=="Docker Manifest")|select(.name|test("go-cli-github:v"))|.name|split(":")[0]')" >> "$GITHUB_OUTPUT" - id: image_metadata_go_cli_github - env: - ARTIFACTS: ${{steps.goreleaser.outputs.artifacts}} - - run: | - echo "digest=$(echo "$ARTIFACTS" | jq -r '.[]|select(.type=="Docker Manifest")|select(.name|test("another-binary:v"))|.extra.Digest')" >> "$GITHUB_OUTPUT" - echo "name=$(echo "$ARTIFACTS" | jq -r '.[]|select(.type=="Docker Manifest")|select(.name|test("another-binary:v"))|.name|split(":")[0]')" >> "$GITHUB_OUTPUT" - id: image_metadata_another_binary - env: - ARTIFACTS: ${{steps.goreleaser.outputs.artifacts}} - # attest images - - uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0 - with: - subject-digest: ${{steps.image_metadata_go_cli_github.outputs.digest}} - subject-name: ${{steps.image_metadata_go_cli_github.outputs.name}} - push-to-registry: true - - uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0 - with: - subject-digest: ${{steps.image_metadata_another_binary.outputs.digest}} - subject-name: ${{steps.image_metadata_another_binary.outputs.name}} - push-to-registry: true diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml deleted file mode 100644 index 9238c25..0000000 --- a/.github/workflows/test.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: test -on: - pull_request: - branches: - - main - merge_group: - types: - - checks_requested -permissions: {} -jobs: - test-go: - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 - with: - go-version: stable - - run: go test -v ./... diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 6ee2014..0000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/dist -/cover.out -/sbom.spdx.json diff --git a/.golangci.yaml b/.golangci.yaml deleted file mode 100644 index 3506354..0000000 --- a/.golangci.yaml +++ /dev/null @@ -1,5 +0,0 @@ -version: "2" -linters: - exclusions: - presets: - - std-error-handling diff --git a/.goreleaser.yaml b/.goreleaser.yaml deleted file mode 100644 index 3d51e6f..0000000 --- a/.goreleaser.yaml +++ /dev/null @@ -1,87 +0,0 @@ -version: 2 -builds: -- &buildDefinition - id: go-cli-github - binary: go-cli-github - main: ./cmd/go-cli-github - ldflags: - - > - -s -w - -X "main.commit={{.Commit}}" - -X "main.date={{.Date}}" - -X "main.projectName={{.ProjectName}}" - -X "main.version=v{{.Version}}" - env: - - CGO_ENABLED=0 - goos: - - linux - - darwin - goarch: - - amd64 - - arm64 -- <<: *buildDefinition - id: another-binary - binary: another-binary - main: ./cmd/another-binary - -changelog: - use: github-native - -dockers: -- ids: - - go-cli-github - image_templates: - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/go-cli-github:v{{ .Version }}-amd64" - use: buildx - build_flag_templates: - - "--build-arg=BINARY=go-cli-github" - - "--platform=linux/amd64" -- ids: - - go-cli-github - image_templates: - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/go-cli-github:v{{ .Version }}-arm64v8" - use: buildx - goarch: arm64 - build_flag_templates: - - "--build-arg=BINARY=go-cli-github" - - "--platform=linux/arm64/v8" -- ids: - - another-binary - image_templates: - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/another-binary:v{{ .Version }}-amd64" - use: buildx - build_flag_templates: - - "--build-arg=BINARY=another-binary" - - "--platform=linux/amd64" -- ids: - - another-binary - image_templates: - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/another-binary:v{{ .Version }}-arm64v8" - use: buildx - goarch: arm64 - build_flag_templates: - - "--build-arg=BINARY=another-binary" - - "--platform=linux/arm64/v8" - -docker_manifests: -- name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/go-cli-github:v{{ .Version }}" - image_templates: - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/go-cli-github:v{{ .Version }}-amd64" - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/go-cli-github:v{{ .Version }}-arm64v8" -- name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/go-cli-github:latest" - image_templates: - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/go-cli-github:v{{ .Version }}-amd64" - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/go-cli-github:v{{ .Version }}-arm64v8" -- name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/another-binary:v{{ .Version }}" - image_templates: - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/another-binary:v{{ .Version }}-amd64" - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/another-binary:v{{ .Version }}-arm64v8" -- name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/another-binary:latest" - image_templates: - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/another-binary:v{{ .Version }}-amd64" - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}/another-binary:v{{ .Version }}-arm64v8" - -release: - extra_files: - - glob: ./sbom.spdx.json - name_template: "{{ .ProjectName }}.v{{ .Version }}.sbom.spdx.json" diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 2c872ae..0000000 --- a/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM alpine:3.22@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412 -ARG BINARY=binary-build-arg-not-defined -ENV BINARY=${BINARY} -ENTRYPOINT ["sh", "-c"] -CMD ["exec /${BINARY}"] -COPY ${BINARY} / diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Makefile b/Makefile deleted file mode 100644 index 3e2502a..0000000 --- a/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# local development targets - -.PHONY: test -test: mod-tidy generate - go test -v ./... - -.PHONY: mod-tidy -mod-tidy: - go mod tidy - -.PHONY: generate -generate: mod-tidy - go generate ./... - -.PHONY: build -build: - goreleaser build --verbose --clean --single-target --snapshot - -.PHONY: lint -lint: - golangci-lint run --enable gocritic - -.PHONY: fuzz -fuzz: mod-tidy generate - go test -fuzz='^Fuzz' -fuzztime=10s -v ./internal/server - -.PHONY: cover -cover: mod-tidy generate - go test -v -covermode=atomic -coverprofile=cover.out -coverpkg=./... ./... - go tool cover -html=cover.out diff --git a/README.md b/README.md index 5dc533e..d092e97 100644 --- a/README.md +++ b/README.md @@ -1,131 +1,3 @@ -# Go CLI GitHub +# Badges -[![Go Reference](https://pkg.go.dev/badge/github.com/smlx/go-cli-github.svg)](https://pkg.go.dev/github.com/smlx/go-cli-github) -[![Release](https://github.com/smlx/go-cli-github/actions/workflows/release.yaml/badge.svg)](https://github.com/smlx/go-cli-github/actions/workflows/release.yaml) -[![coverage](https://raw.githubusercontent.com/smlx/go-cli-github/badges/.badges/main/coverage.svg)](https://github.com/smlx/go-cli-github/actions/workflows/coverage.yaml) -[![Go Report Card](https://goreportcard.com/badge/github.com/smlx/go-cli-github)](https://goreportcard.com/report/github.com/smlx/go-cli-github) -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/smlx/go-cli-github/badge)](https://securityscorecards.dev/viewer/?uri=github.com/smlx/go-cli-github) -[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8168/badge)](https://www.bestpractices.dev/projects/8168) - -This repository is a template for a Go CLI tool or service. -It is quite opinionated about security and release engineering, but hopefully in a good way. - -It comes pre-configured for integration with GitHub-specific features such as [Dependabot security tooling](https://docs.github.com/en/code-security/dependabot), [CodeQL](https://codeql.github.com/), and [branch protection](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches). -It also automatically builds and tests your code using [GitHub Actions](https://docs.github.com/en/actions). - -## Features - -* Use [GoReleaser](https://goreleaser.com/) to automatically build and create GitHub Releases and Docker images on merge to `main`. - - * This uses the [Conventional Commits Versioner](https://github.com/smlx/ccv) to automatically version each release. - -* Lint your commit messages, and your Go, GitHub Action, and Dockerfile code. -* Test Pull Requests using `go test`. -* Build Docker images from Pull Requests for manual testing and review. -* Static code analysis using [CodeQL](https://codeql.github.com/) and [Go Report Card](https://goreportcard.com/). -* Coverage analysis using the [go-test-coverage action](https://github.com/vladopajic/go-test-coverage). -* Security analysis using [OpenSSF](https://securityscorecards.dev). -* Signed binary artifacts using [artifact attestations](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds). - -## How to use - -First set up the GitHub repo - -1. Create a new empty GitHub repository. - -Then push some code to main: - -1. Install [gonew](https://go.dev/blog/gonew) and run this command, replacing the last argument with the name of your new module: - - ```bash - gonew github.com/smlx/go-cli-github@main github.com/smlx/newproject - ``` - -1. Create the git repo and push to `main` (which will become the default branch): - - ```bash - cd newproject - git init . - git branch -M main - git remote add origin git@github.com:smlx/newproject.git - git add . - git commit -am 'chore: create repository from template' - git push -u origin main - ``` - -1. Create the `badges` branch for storing the README coverage badge. - - ```bash - git checkout --orphan badges - git rm -rf . - rm -f .gitignore - echo 'This branch exists only to store the coverage badge in the README on `main`.' > README.md - git add README.md - git commit -m 'chore: initialize the badges branch' - git push origin badges - ``` - -Then customize the code for your repository: - -1. Check out a new branch to set up the repo `git checkout -b setup main` - -1. Update the code for your project: - - * rename `cmd/go-cli-github` to `cmd/$YOUR_COMMAND` - * update `.github/workflows/build.yaml`, replacing `go-cli-github` with `$YOUR_COMMAND`. - * update `.goreleaser.yaml` to build `cmd/$YOUR_COMMAND` - * update the links at the top of `README.md` - * update the contact email in `SECURITY.md` - -1. Commit and push: - - ```bash - git add . - git commit -am 'chore: update template for new project' - git push -u origin setup - ``` -1. Open a PR, wait until all the checks go green, then merge the PR. - -Configure the repository: - -1. Go to repository Settings > General: - - 1. Features - - * Disable wiki and projects (unless you plan to use them!) - - 1. Pull Requests - - * Allow merge commits only for Pull Requests - * Allow auto-merge - * Automatically delete head branches - -1. Go to repository Settings > Advanced Security, and enable: - - * Private vulnerability reporting - - * Dependabot - - * Dependabot alerts - * Dependabot security updates - * Grouped security updates - * Dependabot on Actions runners - - * Code Scanning - - * CodeQL analysis > Set up > Default - - * Secret Protection - - * Push protection - -1. Go to repository Settings > Rules > Rulesets, and import the `protect-default-branch.json` ruleset. - -That's it. - -## How to contribute - -Issues are welcome. - -PRs are also welcome, but keep in mind that this is a very opinionated template, so not all changes will be accepted. -PRs also need to ensure that test coverage remains high, and best practices are followed. +This branch exists only to contains the coverage badge in the README on `main`. diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index a6bb6da..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,15 +0,0 @@ -# Security Policy - -## Supported Versions - -Please do not use older minor versions, as these are not supported. -Only the latest minor version will receive patch releases. - -## Reporting a Vulnerability - -To report a security issue, please [privately report a security vulnerability](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability) through GitHub. -If you do not have a GitHub account, please email scott@smlx.dev with a description of the issue, the steps you took to create the issue, affected versions, and, if known, mitigations for the issue. -We will endeavour to respond within 3 working days of your email. - -If an issue is confirmed as a vulnerability, we will open a Security Advisory. -This project follows a 30 day disclosure timeline. diff --git a/cmd/another-binary/main.go b/cmd/another-binary/main.go deleted file mode 100644 index da6bcaa..0000000 --- a/cmd/another-binary/main.go +++ /dev/null @@ -1,8 +0,0 @@ -// Package main implements the command-line interface of a server. -package main - -import "fmt" - -func main() { - fmt.Println("Hello, World!") -} diff --git a/cmd/go-cli-github/main.go b/cmd/go-cli-github/main.go deleted file mode 100644 index e7640b8..0000000 --- a/cmd/go-cli-github/main.go +++ /dev/null @@ -1,22 +0,0 @@ -// Package main implements the command-line interface of a server. -package main - -import ( - "github.com/alecthomas/kong" -) - -// CLI represents the command-line interface. -type CLI struct { - Version VersionCmd `kong:"cmd,help='Print version information'"` - Serve ServeCmd `kong:"cmd,default=1,help='(default) Example serve command'"` -} - -func main() { - // parse CLI config - cli := CLI{} - kctx := kong.Parse(&cli, - kong.UsageOnError(), - ) - // execute CLI - kctx.FatalIfErrorf(kctx.Run()) -} diff --git a/cmd/go-cli-github/serve.go b/cmd/go-cli-github/serve.go deleted file mode 100644 index fe7016c..0000000 --- a/cmd/go-cli-github/serve.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "fmt" - "time" - - "github.com/smlx/go-cli-github/internal/server" -) - -// ServeCmd represents the `serve` command. -type ServeCmd struct{} - -// Run the serve command. -func (*ServeCmd) Run() error { - fmt.Println(server.New(time.Now).Serve()) - return nil -} diff --git a/cmd/go-cli-github/version.go b/cmd/go-cli-github/version.go deleted file mode 100644 index f80aa88..0000000 --- a/cmd/go-cli-github/version.go +++ /dev/null @@ -1,41 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "runtime" -) - -// These variables are set by GoReleaser during the build. -var ( - commit string - date string - projectName string - version string -) - -// VersionCmd represents the `version` command. -type VersionCmd struct{} - -// Run the Version command. -func (*VersionCmd) Run() error { - v, err := json.Marshal( - struct { - ProjectName string - Version string - Commit string - BuildDate string - GoVersion string - }{ - projectName, - version, - commit, - date, - runtime.Version(), - }) - if err != nil { - return err - } - _, err = fmt.Println(string(v)) - return err -} diff --git a/go.mod b/go.mod deleted file mode 100644 index 0941a6b..0000000 --- a/go.mod +++ /dev/null @@ -1,13 +0,0 @@ -module github.com/smlx/go-cli-github - -go 1.22.2 - -require ( - github.com/alecthomas/assert/v2 v2.11.0 - github.com/alecthomas/kong v1.12.1 -) - -require ( - github.com/alecthomas/repr v0.4.0 // indirect - github.com/hexops/gotextdiff v1.0.3 // indirect -) diff --git a/go.sum b/go.sum deleted file mode 100644 index 81cc1bc..0000000 --- a/go.sum +++ /dev/null @@ -1,8 +0,0 @@ -github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= -github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/kong v1.12.1 h1:iq6aMJDcFYP9uFrLdsiZQ2ZMmcshduyGv4Pek0MQPW0= -github.com/alecthomas/kong v1.12.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= -github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= -github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= diff --git a/internal/server/serve.go b/internal/server/serve.go deleted file mode 100644 index 1113065..0000000 --- a/internal/server/serve.go +++ /dev/null @@ -1,55 +0,0 @@ -// Package server implements an example server. -package server - -import ( - "fmt" - "time" -) - -// Server is an example server. -type Server struct { - // now is a function returning a time that the server will consider the - // current instant. - now func() time.Time -} - -// New constructs a new Server, which greets people based on the time returned -// by the given nowFunc. If nowFunc is nil, the Server will default to time.Now. -func New(nowFunc func() time.Time) *Server { - return &Server{ - now: nowFunc, - } -} - -// Serve is an example function. -func (*Server) Serve() string { - return "example serve command" -} - -// Greet is an example fuzzable function. -// name is free form, but birthDate must be in YYYY-MM-DD format. -func (s *Server) Greet(name, birthDate string) (string, error) { - b, err := time.ParseInLocation("2006-01-02", birthDate, time.Local) - if err != nil { - return "", fmt.Errorf("couldn't parse birthDate: %v", err) - } - now := s.now() - if now.Before(b) { - return "", fmt.Errorf("time travel detected") - } - // calculate time since birthday this year - d := now.Sub( - time.Date(now.Year(), b.Month(), b.Day(), 0, 0, 0, 0, time.Local)) - switch { - case d < 0: - // calculate time since birthday last year - d = now.Sub( - time.Date(now.Year()-1, b.Month(), b.Day(), 0, 0, 0, 0, time.Local)) - fallthrough - case d > 0: - return fmt.Sprintf("Hello %s, happy belated birthday for %d days ago.", - name, int(d.Hours()/24)), nil - default: - return fmt.Sprintf("Hello %s, happy birthday!", name), nil - } -} diff --git a/internal/server/serve_test.go b/internal/server/serve_test.go deleted file mode 100644 index 0fb934f..0000000 --- a/internal/server/serve_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package server_test - -import ( - "testing" - "time" - - "github.com/alecthomas/assert/v2" - "github.com/smlx/go-cli-github/internal/server" -) - -func nowTestFunc() time.Time { - t, err := time.ParseInLocation("2006-01-02", "2023-12-12", time.Local) - if err != nil { - panic(err) - } - return t -} - -func TestServe(t *testing.T) { - var testCases = map[string]struct { - input string - expect string - }{ - "test Serve": {input: "", expect: "example serve command"}, - } - for name, tc := range testCases { - t.Run(name, func(tt *testing.T) { - s := server.New(nowTestFunc) - result := s.Serve() - assert.Equal(tt, tc.expect, result, name) - }) - } -} - -func TestGreet(t *testing.T) { - var testCases = map[string]struct { - input []string - expect string - expectError bool - }{ - "boomer": { - input: []string{"Jim", "1963-02-03"}, - expect: "Hello Jim, happy belated birthday for 312 days ago.", - }, - "the doctor": { - input: []string{"Who", "2963-02-03"}, - expect: "time travel detected", - expectError: true, - }, - "late birthday": { - input: []string{"Foo", "2000-12-22"}, - expect: "Hello Foo, happy belated birthday for 355 days ago.", - }, - } - for name, tc := range testCases { - t.Run(name, func(tt *testing.T) { - s := server.New(nowTestFunc) - result, err := s.Greet(tc.input[0], tc.input[1]) - if tc.expectError { - assert.EqualError(tt, err, tc.expect, name) - } else { - assert.NoError(tt, err, name) - assert.Equal(tt, tc.expect, result, name) - } - }) - } -} - -func FuzzGreet(f *testing.F) { - f.Add("Joe", "2020-04-02") - f.Fuzz(func(t *testing.T, name, birthDate string) { - s := server.New(nowTestFunc) - out, err := s.Greet(name, birthDate) - if err != nil && out != "" { - t.Errorf("%q, %v", out, err) - } - }) -} diff --git a/protect-default-branch.json b/protect-default-branch.json deleted file mode 100644 index 52c5ddd..0000000 --- a/protect-default-branch.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "id": 239413, - "name": "protect-default-branch", - "target": "branch", - "source_type": "Repository", - "source": "smlx/go-cli-github", - "enforcement": "active", - "conditions": { - "ref_name": { - "exclude": [], - "include": [ - "~DEFAULT_BRANCH" - ] - } - }, - "rules": [ - { - "type": "deletion" - }, - { - "type": "non_fast_forward" - }, - { - "type": "creation" - }, - { - "type": "pull_request", - "parameters": { - "required_approving_review_count": 1, - "dismiss_stale_reviews_on_push": false, - "require_code_owner_review": false, - "require_last_push_approval": false, - "required_review_thread_resolution": false, - "automatic_copilot_code_review_enabled": false, - "allowed_merge_methods": [ - "merge", - "squash", - "rebase" - ] - } - }, - { - "type": "required_status_checks", - "parameters": { - "strict_required_status_checks_policy": true, - "do_not_enforce_on_create": false, - "required_status_checks": [ - { - "context": "lint-actions", - "integration_id": 15368 - }, - { - "context": "lint-commits", - "integration_id": 15368 - }, - { - "context": "lint-go", - "integration_id": 15368 - }, - { - "context": "test-go", - "integration_id": 15368 - }, - { - "context": "dependency-review", - "integration_id": 15368 - } - ] - } - }, - { - "type": "code_scanning", - "parameters": { - "code_scanning_tools": [ - { - "tool": "CodeQL", - "security_alerts_threshold": "medium_or_higher", - "alerts_threshold": "errors_and_warnings" - } - ] - } - } - ], - "bypass_actors": [ - { - "actor_id": 5, - "actor_type": "RepositoryRole", - "bypass_mode": "pull_request" - } - ] -} \ No newline at end of file