From 35b2fdbd6fdc4c95c4fff5ff8d78d836d3eda8c8 Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Thu, 31 Aug 2023 15:14:44 -0700 Subject: [PATCH] Copy GitHub setup from crossplane-runtime Signed-off-by: Nic Cope --- .github/ISSUE_TEMPLATE/bug_report.md | 40 ++++ .github/ISSUE_TEMPLATE/feature_request.md | 24 +++ .github/PULL_REQUEST_TEMPLATE.md | 35 ++++ .github/renovate.json5 | 104 ++++++++++ .github/stale.yml | 38 ++++ .github/workflows/backport.yml | 33 ++++ .github/workflows/ci.yml | 227 ++++++++++++++++++++++ .github/workflows/commands.yml | 91 +++++++++ .github/workflows/promote.yml | 48 +++++ .github/workflows/tag.yml | 26 +++ 10 files changed, 666 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/renovate.json5 create mode 100644 .github/stale.yml create mode 100644 .github/workflows/backport.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/commands.yml create mode 100644 .github/workflows/promote.yml create mode 100644 .github/workflows/tag.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..a7b73b8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,40 @@ +--- +name: Bug Report +about: Help us diagnose and fix bugs in Crossplane +labels: bug +--- + + +### What happened? + + + +### How can we reproduce it? + + +### What environment did it happen in? +Crossplane version: + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..c385d79 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,24 @@ +--- +name: Feature Request +about: Help us make Crossplane more useful +labels: enhancement +--- + + +### What problem are you facing? + + +### How could Crossplane help solve your problem? + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..7627d1a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,35 @@ + + +### Description of your changes + + +Fixes # + +I have: + +- [ ] Read and followed Crossplane's [contribution process]. +- [ ] Run `make reviewable test` to ensure this PR is ready for review. + +### How has this code been tested + + + +[contribution process]: https://git.io/fj2m9 diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 0000000..9e05c1b --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,104 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base", + "helpers:pinGitHubActionDigests" + ], +// We only want renovate to rebase PRs when they have conflicts, +// default "auto" mode is not required. + "rebaseWhen": "conflicted", +// The maximum number of PRs to be created in parallel + "prConcurrentLimit": 5, + "postUpdateOptions": ["gomodTidy"], +// By default renovate will auto detect whether semantic commits have been used +// in the recent history and comply with that, we explicitly disable it + "semanticCommits": "disabled", +// All PRs should have a label + "labels": ["automated"], + "regexManagers": [ + { + "description": "Bump Go version ued in workflows", + "fileMatch": ["^\\.github\\/workflows\\/[^/]+\\.ya?ml$"], + "matchStrings": [ + "GO_VERSION: '(?.*?)'\\n" + ], + "datasourceTemplate": "golang-version", + "depNameTemplate": "golang" + }, { + "description": "Bump golangci-lint version in workflows and the Makefile", + "fileMatch": ["^\\.github\\/workflows\\/[^/]+\\.ya?ml$","^Makefile$"], + "matchStrings": [ + "GOLANGCI_VERSION: 'v(?.*?)'\\n", + "GOLANGCILINT_VERSION = (?.*?)\\n" + ], + "datasourceTemplate": "github-tags", + "depNameTemplate": "golangci/golangci-lint", + "extractVersionTemplate": "^v(?.*)$" + }, { + "description": "Bump Go required version in workflows and the Makefile", + "fileMatch": ["^\\.github\\/workflows\\/[^/]+\\.ya?ml$", "^Makefile$"], + "matchStrings": [ + "GO_REQUIRED_VERSION = (?.*?)\\n", + ], + "datasourceTemplate": "golang-version", + "depNameTemplate": "golang", + "versioningTemplate": "loose", + "extractVersionTemplate": "^(?\\d+\\.\\d+)" + } + ], +// PackageRules disabled below should be enabled in case of vulnerabilities + "vulnerabilityAlerts": { + "enabled": true + }, + "osvVulnerabilityAlerts": true, + "packageRules": [ + { + "description": "Only get docker image updates every 2 weeks to reduce noise", + "matchDatasources": ["docker"], + "schedule": ["every 2 week on monday"], + "enabled": true, + }, { + "description": "Ignore k8s.io/client-go older versions, they switched to semantic version and old tags are still available in the repo", + "matchDatasources": [ + "go" + ], + "matchDepNames": [ + "k8s.io/client-go" + ], + "allowedVersions": "<1.0" + }, { + "description": "Only get dependency digest updates every month to reduce noise", + "matchDatasources": [ + "go" + ], + "matchUpdateTypes": [ + "digest", + ], + "extends": ["schedule:monthly"], + }, { + "description": "Single PR for all kubernetes dependency updates, as they usually are all linked", + "matchDatasources": [ + "go" + ], + "groupName": "kubernetes deps", + "matchUpdateTypes": [ + "major", + "minor", + "patch" + ], + "matchPackagePrefixes": [ + "k8s.io", + "sigs.k8s.io" + ] + }, { + "description": "Ignore oss-fuzz, it's not using tags, we'll stick to master", + "matchDepTypes": [ + "action" + ], + "matchDepNames": [ + "google/oss-fuzz" + ], + "enabled": false + } + ] +} diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 0000000..f6c6e0a --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,38 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before a stale Issue or Pull Request is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 7 + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - security + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Label to use when marking as stale +staleLabel: wontfix + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. + +# Comment to post when closing a stale Issue or Pull Request. +closeComment: > + This issue has been automatically closed due to inactivity. Please re-open + if this still requires investigation. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +# Limit to only `issues` or `pulls` +only: issues diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 0000000..b893d36 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,33 @@ +name: Backport + +on: + # NOTE(negz): This is a risky target, but we run this action only when and if + # a PR is closed, then filter down to specifically merged PRs. We also don't + # invoke any scripts, etc from within the repo. I believe the fact that we'll + # be able to review PRs before this runs makes this fairly safe. + # https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ + pull_request_target: + types: [closed] + # See also commands.yml for the /backport triggered variant of this workflow. + +jobs: + # NOTE(negz): I tested many backport GitHub actions before landing on this + # one. Many do not support merge commits, or do not support pull requests with + # more than one commit. This one does. It also handily links backport PRs with + # new PRs, and provides commentary and instructions when it can't backport. + # The main gotchas with this action are that it _only_ supports merge commits, + # and that PRs _must_ be labelled before they're merged to trigger a backport. + open-pr: + runs-on: ubuntu-22.04 + if: github.event.pull_request.merged + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + with: + fetch-depth: 0 + + - name: Open Backport PR + uses: zeebe-io/backport-action@bd68141f079bd036e45ea8149bc9d174d5a04703 # v1.4.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + github_workspace: ${{ github.workspace }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..aae2f9f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,227 @@ +name: CI + +on: + push: + branches: + - master + - release-* + pull_request: {} + workflow_dispatch: {} + +env: + # Common versions + GO_VERSION: '1.21.0' + GOLANGCI_VERSION: 'v1.54.2' + +jobs: + check-diff: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + with: + submodules: true + + - name: Setup Go + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Find the Go Build Cache + id: go + run: echo "::set-output name=cache::$(make go.cachedir)" + + - name: Cache the Go Build Cache + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: ${{ steps.go.outputs.cache }} + key: ${{ runner.os }}-build-check-diff-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-build-check-diff- + + - name: Cache Go Dependencies + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: .work/pkg + key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-pkg- + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Check Diff + run: make check-diff + + detect-noop: + runs-on: ubuntu-22.04 + outputs: + noop: ${{ steps.noop.outputs.should_skip }} + steps: + - name: Detect No-op Changes + id: noop + uses: fkirc/skip-duplicate-actions@12aca0a884f6137d619d6a8a09fcc3406ced5281 # v5.3.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + paths_ignore: '["**.md", "**.png", "**.jpg"]' + do_not_skip: '["workflow_dispatch", "schedule", "push"]' + concurrent_skipping: false + + lint: + runs-on: ubuntu-22.04 + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + with: + submodules: true + + - name: Setup Go + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Find the Go Build Cache + id: go + run: echo "::set-output name=cache::$(make go.cachedir)" + + - name: Cache the Go Build Cache + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: ${{ steps.go.outputs.cache }} + key: ${{ runner.os }}-build-lint-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-build-lint- + + - name: Cache Go Dependencies + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: .work/pkg + key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-pkg- + + - name: Vendor Dependencies + run: make vendor vendor.check + + # We could run 'make lint' to ensure our desired Go version, but we prefer + # this action because it leaves 'annotations' (i.e. it comments on PRs to + # point out linter violations). + - name: Lint + uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3 + with: + version: ${{ env.GOLANGCI_VERSION }} + skip-cache: true # We do our own caching. + + codeql: + runs-on: ubuntu-22.04 + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + with: + submodules: true + + - name: Setup Go + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Find the Go Build Cache + id: go + run: echo "::set-output name=cache::$(make go.cachedir)" + + - name: Cache the Go Build Cache + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: ${{ steps.go.outputs.cache }} + key: ${{ runner.os }}-build-check-diff-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-build-check-diff- + + - name: Cache Go Dependencies + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: .work/pkg + key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-pkg- + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Initialize CodeQL + uses: github/codeql-action/init@a09933a12a80f87b87005513f0abb1494c27a716 # v2 + with: + languages: go + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@a09933a12a80f87b87005513f0abb1494c27a716 # v2 + + trivy-scan-fs: + runs-on: ubuntu-22.04 + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + with: + submodules: true + + - name: Run Trivy vulnerability scanner in fs mode + uses: aquasecurity/trivy-action@41f05d9ecffa2ed3f1580af306000f734b733e54 # 0.11.2 + with: + scan-type: 'fs' + ignore-unfixed: true + skip-dirs: design + scan-ref: '.' + exit-code: '1' + severity: 'CRITICAL,HIGH' + + unit-tests: + runs-on: ubuntu-22.04 + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + with: + submodules: true + + - name: Fetch History + run: git fetch --prune --unshallow + + - name: Setup Go + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Find the Go Build Cache + id: go + run: echo "::set-output name=cache::$(make go.cachedir)" + + - name: Cache the Go Build Cache + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: ${{ steps.go.outputs.cache }} + key: ${{ runner.os }}-build-unit-tests-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-build-unit-tests- + + - name: Cache Go Dependencies + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3 + with: + path: .work/pkg + key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-pkg- + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Run Unit Tests + run: make -j2 test + + - name: Publish Unit Test Coverage + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3 + with: + flags: unittests + file: _output/tests/linux_amd64/coverage.txt diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml new file mode 100644 index 0000000..5308231 --- /dev/null +++ b/.github/workflows/commands.yml @@ -0,0 +1,91 @@ +name: Comment Commands + +on: issue_comment + +jobs: + points: + runs-on: ubuntu-22.04 + if: startsWith(github.event.comment.body, '/points') + + steps: + - name: Extract Command + id: command + uses: xt0rted/slash-command-action@bf51f8f5f4ea3d58abc7eca58f77104182b23e88 # v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + command: points + reaction: "true" + reaction-type: "eyes" + allow-edits: "false" + permission-level: write + - name: Handle Command + uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6 + env: + POINTS: ${{ steps.command.outputs.command-arguments }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const points = process.env.POINTS + + if (isNaN(parseInt(points))) { + console.log("Malformed command - expected '/points '") + github.reactions.createForIssueComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: context.payload.comment.id, + content: "confused" + }) + return + } + const label = "points/" + points + + // Delete our needs-points-label label. + try { + await github.issues.deleteLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: ['needs-points-label'] + }) + console.log("Deleted 'needs-points-label' label.") + } + catch(e) { + console.log("Label 'needs-points-label' probably didn't exist.") + } + + // Add our points label. + github.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: [label] + }) + console.log("Added '" + label + "' label.") + + # NOTE(negz): See also backport.yml, which is the variant that triggers on PR + # merge rather than on comment. + backport: + runs-on: ubuntu-22.04 + if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/backport') + steps: + - name: Extract Command + id: command + uses: xt0rted/slash-command-action@bf51f8f5f4ea3d58abc7eca58f77104182b23e88 # v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + command: backport + reaction: "true" + reaction-type: "eyes" + allow-edits: "false" + permission-level: write + + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + with: + fetch-depth: 0 + + - name: Open Backport PR + uses: zeebe-io/backport-action@bd68141f079bd036e45ea8149bc9d174d5a04703 # v1.4.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + github_workspace: ${{ github.workspace }} diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml new file mode 100644 index 0000000..860648e --- /dev/null +++ b/.github/workflows/promote.yml @@ -0,0 +1,48 @@ +name: Promote + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version (e.g. v0.1.0)' + required: true + channel: + description: 'Release channel' + required: true + default: 'alpha' + +env: + # Common users. We can't run a step 'if secrets.AWS_USR != ""' but we can run + # a step 'if env.AWS_USR' != ""', so we copy these to succinctly test whether + # credentials have been provided before trying to run steps that need them. + DOCKER_USR: ${{ secrets.DOCKER_USR }} + AWS_USR: ${{ secrets.AWS_USR }} + +jobs: + promote-artifacts: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + with: + submodules: true + + - name: Fetch History + run: git fetch --prune --unshallow + + - name: Login to Docker + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2 + if: env.DOCKER_USR != '' + with: + username: ${{ secrets.DOCKER_USR }} + password: ${{ secrets.DOCKER_PSW }} + + - name: Promote Artifacts in S3 and Docker Hub + if: env.AWS_USR != '' && env.DOCKER_USR != '' + run: make -j2 promote BRANCH_NAME=${GITHUB_REF##*/} + env: + VERSION: ${{ github.event.inputs.version }} + CHANNEL: ${{ github.event.inputs.channel }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_USR }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_PSW }} diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml new file mode 100644 index 0000000..a5a6dda --- /dev/null +++ b/.github/workflows/tag.yml @@ -0,0 +1,26 @@ +name: Tag + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version (e.g. v0.1.0)' + required: true + message: + description: 'Tag message' + required: true + +jobs: + create-tag: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3 + + - name: Create Tag + uses: negz/create-tag@39bae1e0932567a58c20dea5a1a0d18358503320 # v1 + with: + version: ${{ github.event.inputs.version }} + message: ${{ github.event.inputs.message }} + token: ${{ secrets.GITHUB_TOKEN }}