diff --git a/.github/configs/ct.yaml b/.github/configs/ct.yaml new file mode 100644 index 0000000..5988d3b --- /dev/null +++ b/.github/configs/ct.yaml @@ -0,0 +1,14 @@ +## Reference: https://github.com/helm/chart-testing/blob/master/doc/ct_lint-and-install.md +## +remote: origin +target-branch: main +chart-dirs: + - helm/ +chart-repos: + - buttahtoast=https://buttahtoast.github.io/helm-charts/ + - bitnami=https://charts.bitnami.com/bitnami +validate-chart-schema: true +validate-maintainers: false +validate-yaml: true +exclude-deprecated: true +check-version-increment: false \ No newline at end of file diff --git a/.github/configs/lintconf.yaml b/.github/configs/lintconf.yaml new file mode 100644 index 0000000..f52bab7 --- /dev/null +++ b/.github/configs/lintconf.yaml @@ -0,0 +1,42 @@ +--- +rules: + braces: + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + brackets: + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + colons: + max-spaces-before: 0 + max-spaces-after: 1 + commas: + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 + comments: + require-starting-space: true + min-spaces-from-content: 1 + document-end: disable + document-start: disable # No --- to start a file + empty-lines: + max: 2 + max-start: 0 + max-end: 0 + hyphens: + max-spaces-after: 1 + indentation: + spaces: consistent + indent-sequences: whatever # - list indentation will handle both indentation and without + check-multi-line-strings: false + key-duplicates: enable + line-length: disable # Lines can be any length + new-line-at-end-of-file: enable + new-lines: + type: unix + trailing-spaces: enable + truthy: + level: warning \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8213ada --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gomod" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/check-actions.yaml b/.github/workflows/check-actions.yaml new file mode 100644 index 0000000..b6bc489 --- /dev/null +++ b/.github/workflows/check-actions.yaml @@ -0,0 +1,23 @@ +name: Check actions +permissions: {} + +on: + push: + branches: + - '*' + pull_request: + branches: [ "master", "main" ] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + - name: Ensure SHA pinned actions + uses: zgosalvez/github-actions-ensure-sha-pinned-actions@f32435541e24cd6a4700a7f52bb2ec59e80603b1 # v2.1.4 + with: + # slsa-github-generator requires using a semver tag for reusable workflows. + # See: https://github.com/slsa-framework/slsa-github-generator#referencing-slsa-builders-and-generators + allowlist: | + slsa-framework/slsa-github-generator \ No newline at end of file diff --git a/.github/workflows/check-commit.yml b/.github/workflows/check-commit.yml new file mode 100644 index 0000000..0d6b52a --- /dev/null +++ b/.github/workflows/check-commit.yml @@ -0,0 +1,23 @@ +name: Check Commit +permissions: {} + +on: + push: + branches: [ "*" ] + pull_request: + branches: [ "*" ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + commit_lint: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + with: + fetch-depth: 0 + - uses: wagoid/commitlint-github-action@6319f54d83768b60acd6fd60e61007ccc583e62f #v5.4.3 + with: + firstParent: true diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 0000000..c6d3cda --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,35 @@ +name: Integration Test + +on: + pull_request: + branches: + - "master" + push: + branches: + - "master" + +permissions: read-all + +jobs: + integration-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Check secret + id: checksecret + uses: oliverbaehler/github-actions/exists@8dfd42735c85f6c58d5d4d6f3232cd0e39d1fe73 # v0.1.0 + with: + value: ${{ secrets.CODECOV_TOKEN }} + - uses: actions/setup-go@v4 + with: + go-version: '1.19' + - name: Run integration tests + run: | + make integration-test + - name: Upload coverage reports to Codecov + if: steps.checksecret.outputs.result == 'true' + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 + with: + files: ./test/integration/cover.out + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..b40280e --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,30 @@ +name: Build images +permissions: {} + +on: + push: + branches: + - '*' + pull_request: + branches: [ "master", "main" ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-images: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + - name: ko build + run: VERSION=${{ github.ref_name }} REPOSITORY=${GITHUB_REPOSITORY} make ko-build-all + - name: Trivy Scan Image + uses: aquasecurity/trivy-action@fbd16365eb88e12433951383f5e99bd901fc618f # v0.12.0 + with: + scan-type: 'fs' + ignore-unfixed: true + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' \ No newline at end of file diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..514388a --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,67 @@ +name: Publish images +permissions: {} +on: + push: + tags: + - "v*" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: + publish-images: + runs-on: ubuntu-latest + permissions: + packages: write + id-token: write + outputs: + container-digest: ${{ steps.publish.outputs.digest }} + steps: + - name: Checkout + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + - name: "Extract Version" + id: extract_version + run: | + GIT_TAG=${GITHUB_REF##*/} + VERSION=${GIT_TAG##v} + echo "version=$(echo $VERSION)" >> $GITHUB_OUTPUT + - name: Run Trivy vulnerability (Repo) + uses: aquasecurity/trivy-action@fbd16365eb88e12433951383f5e99bd901fc618f # v0.12.0 + with: + scan-type: 'fs' + ignore-unfixed: true + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + - name: Install Cosign + uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2 + - name: Publish with KO + id: publish + uses: oliverbaehler/github-actions/ko-publish-image@8dfd42735c85f6c58d5d4d6f3232cd0e39d1fe73 # v0.1.0 + with: + makefile-target: ko-publish-all + registry: ghcr.io + registry-username: ${{ github.actor }} + registry-password: ${{ secrets.GITHUB_TOKEN }} + repository: ${{ github.repository_owner }} + version: ${{ steps.extract_version.outputs.version }} + sign-image: true + sbom-name: svc-ingress-propagator + sbom-repository: ghcr.io/${{ github.repository_owner }}/sbom + signature-repository: ghcr.io/${{ github.repository_owner }}/signatures + main-path: ./cmd/ + env: + REPOSITORY: ${{ github.repository }} + VERSION: ${{ steps.extract_version.outputs.version }} + generate-provenance: + needs: publish-images + permissions: + id-token: write # To sign the provenance. + packages: write # To upload assets to release. + actions: read # To read the workflow path. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0 + with: + image: ghcr.io/${{ github.repository_owner }}/svc-ingress-propagator + digest: "${{ needs.publish-images.outputs.container-digest }}" + registry-username: ${{ github.actor }} + secrets: + registry-password: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/helm-publish.yml b/.github/workflows/helm-publish.yml new file mode 100644 index 0000000..649a682 --- /dev/null +++ b/.github/workflows/helm-publish.yml @@ -0,0 +1,52 @@ +name: Publish charts +permissions: read-all +on: + push: + tags: + - "v*" +jobs: + publish-helm: + runs-on: ubuntu-20.04 + permissions: + contents: write + id-token: write + packages: write + outputs: + chart-digest: ${{ steps.helm_publish.outputs.digest }} + steps: + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + - uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2 + - name: "Extract Version" + id: extract_version + run: | + GIT_TAG=${GITHUB_REF##*/} + VERSION=${GIT_TAG##v} + echo "version=$(echo $VERSION)" >> $GITHUB_OUTPUT + - name: Helm | Publish + id: helm_publish + uses: oliverbaehler/github-actions/helm-oci-chart@dev + with: + registry: ghcr.io + repository: ${{ github.repository_owner }}/charts + name: "svc-ingress-propagator" + path: "./helm" + app-version: ${{ steps.extract_version.outputs.version }} + version: ${{ steps.extract_version.outputs.version }} + registry-username: ${{ github.actor }} + registry-password: ${{ secrets.GITHUB_TOKEN }} + update-dependencies: 'true' # Defaults to false + sign-image: 'true' + signature-repository: ghcr.io/${{ github.repository_owner }}/signatures + helm-provenance: + needs: publish-helm + permissions: + id-token: write # To sign the provenance. + packages: write # To upload assets to release. + actions: read # To read the workflow path. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0 + with: + image: ghcr.io/${{ github.repository_owner }}/charts/svc-ingress-propagator + digest: "${{ needs.publish-helm.outputs.chart-digest }}" + registry-username: ${{ github.actor }} + secrets: + registry-password: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml new file mode 100644 index 0000000..e1446c0 --- /dev/null +++ b/.github/workflows/helm-test.yml @@ -0,0 +1,50 @@ +name: Test charts +permissions: {} + +on: + push: + branches: [ "*" ] + pull_request: + branches: [ "master", "main" ] + +jobs: + lint: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + with: + fetch-depth: 0 + - uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3 + - name: Setup Chart Linting + id: lint + uses: helm/chart-testing-action@e8788873172cb653a90ca2e819d79d65a66d4e76 # v2.4.0 + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --config .github/configs/ct.yaml) + if [[ -n "$changed" ]]; then + echo "::set-output name=changed::true" + fi + - name: Run chart-testing (lint) + run: ct lint --debug --config .github/configs/ct.yaml --lint-conf .github/configs/lintconf.yaml + - name: Run docs-testing (helm-docs) + id: helm-docs + run: | + make helm-docs + if [[ $(git diff --stat) != '' ]]; then + echo -e '\033[0;31mDocumentation outdated! (Run make helm-docs locally and commit)\033[0m ❌' + git diff --color + exit 1 + else + echo -e '\033[0;32mDocumentation up to date\033[0m ✔' + fi + + ## Create KIND Cluster + - name: Create kind cluster + uses: helm/kind-action@dda0770415bac9fc20092cacbc54aa298604d140 # v1.8.0 + if: steps.list-changed.outputs.changed == 'true' + + # Install Charts + - name: Run chart-testing (install) + run: ct install --debug --config .github/configs/ct.yaml + if: steps.list-changed.outputs.changed == 'true' diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml new file mode 100644 index 0000000..1d0900e --- /dev/null +++ b/.github/workflows/releaser.yml @@ -0,0 +1,32 @@ +name: Go Release + +permissions: {} +on: + push: + tags: + - 'v*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + create-release: + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + steps: + - name: Checkout + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + - uses: creekorful/goreportcard-action@1f35ced8cdac2cba28c9a2f2288a16aacfd507f9 # v1.0 + - uses: anchore/sbom-action/download-syft@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 + - name: Install Cosign + uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2 + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0 + with: + version: latest + args: release --clean --timeout 90m --debug + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..87bc83e --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,75 @@ +project_name: svc-ingress-propagator +env: + - COSIGN_EXPERIMENTAL=true + - GO111MODULE=on +before: + hooks: + - go mod download +gomod: + proxy: true + +builds: + - main: cmd/main.go + binary: "{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}" + env: + - CGO_ENABLED=0 + goarch: + - amd64 + goos: + - linux + flags: + - -trimpath + mod_timestamp: '{{ .CommitTimestamp }}' + ldflags: + - >- + -X github.com/buttahtoast/{{ .ProjectName }}/cmd.Version={{ .Tag }} + -X github.com/buttahtoast/{{ .ProjectName }}/cmd.GitCommit={{ .Commit }} + -X github.com/buttahtoast/{{ .ProjectName }}/cmd.BuildDate={{ .Date }} +release: + footer: | + **Full Changelog**: https://github.com/buttahtoast/{{ .ProjectName }}/compare/{{ .PreviousTag }}...{{ .Tag }} + + **Docker Images** + - `ghcr.io/buttahtoast/{{ .ProjectName }}:{{ .Tag }}` + - `ghcr.io/buttahtoast/{{ .ProjectName }}:latest` +checksum: + name_template: 'checksums.txt' +changelog: + sort: asc + use: github + filters: + exclude: + - '^test:' + - '^chore' + - 'merge conflict' + - Merge pull request + - Merge remote-tracking branch + - Merge branch + groups: + - title: Dependency updates + regexp: '^.*?(feat|fix)\(deps\)!?:.+$' + order: 300 + - title: 'New Features' + regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$' + order: 100 + - title: 'Bug fixes' + regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$' + order: 200 + - title: 'Documentation updates' + regexp: ^.*?doc(\([[:word:]]+\))??!?:.+$ + order: 400 + - title: 'Build process updates' + regexp: ^.*?build(\([[:word:]]+\))??!?:.+$ + order: 400 + - title: Other work + order: 9999 +sboms: + - artifacts: archive +signs: +- cmd: cosign + args: + - "sign-blob" + - "--output-signature=${signature}" + - "${artifact}" + - "--yes" + artifacts: all diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000..189134e --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,11 @@ +const Configuration = { + extends: ['@commitlint/config-conventional'], + plugins: ['commitlint-plugin-function-rules'], + rules: { + 'type-enum': [2, 'always', ['chore', 'ci', 'docs', 'feat', 'test', 'fix', 'sec']], + 'body-max-line-length': [1, 'always', 500], + }, + defaultIgnores: true, + }; + + module.exports = Configuration; \ No newline at end of file diff --git a/target/kustomization.yaml b/hack/target/kustomization.yaml similarity index 100% rename from target/kustomization.yaml rename to hack/target/kustomization.yaml diff --git a/target/rbac/binding.yaml b/hack/target/rbac/binding.yaml similarity index 100% rename from target/rbac/binding.yaml rename to hack/target/rbac/binding.yaml diff --git a/target/rbac/kustomization.yaml b/hack/target/rbac/kustomization.yaml similarity index 100% rename from target/rbac/kustomization.yaml rename to hack/target/rbac/kustomization.yaml diff --git a/target/rbac/role.yaml b/hack/target/rbac/role.yaml similarity index 100% rename from target/rbac/role.yaml rename to hack/target/rbac/role.yaml diff --git a/target/rbac/serviceaccount.yaml b/hack/target/rbac/serviceaccount.yaml similarity index 100% rename from target/rbac/serviceaccount.yaml rename to hack/target/rbac/serviceaccount.yaml