diff --git a/.github/workflows/backport-trigger.yml b/.github/workflows/backport-trigger.yml new file mode 100644 index 0000000..7594f69 --- /dev/null +++ b/.github/workflows/backport-trigger.yml @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2024 The Crossplane Authors +# +# SPDX-License-Identifier: CC0-1.0 + +name: Backport comment trigger + +on: issue_comment + +jobs: + backport: + runs-on: ubuntu-latest + 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.0.0 + with: + command: backport + reaction: "true" + reaction-type: "eyes" + allow-edits: "false" + permission-level: write + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + + - name: Open Backport PR + uses: zeebe-io/backport-action@be567af183754f6a5d831ae90f648954763f17f5 # v3.1.0 diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index c3881aa..e5736dd 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -12,8 +12,17 @@ on: # 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. + # See also backport-trigger.yml for the /backport triggered variant of this workflow. jobs: - backport: - uses: upbound/official-providers-ci/.github/workflows/provider-backport.yml@standard-runners + open-pr: + runs-on: ubuntu-latest + if: github.event.pull_request.merged + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + + - name: Open Backport PR + uses: zeebe-io/backport-action@be567af183754f6a5d831ae90f648954763f17f5 # v3.1.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9320565..65fe5d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,13 +12,219 @@ on: pull_request: {} workflow_dispatch: {} +env: + GO_VERSION: "1.23" + jobs: - ci: - uses: upbound/official-providers-ci/.github/workflows/provider-ci.yml@standard-runners - with: - go-version: 1.23 - upjet-based-provider: true - golangci-version: 'v1.61.0' - secrets: - UPBOUND_MARKETPLACE_PUSH_ROBOT_USR: ${{ secrets.UPBOUND_MARKETPLACE_PUSH_ROBOT_USR }} - UPBOUND_MARKETPLACE_PUSH_ROBOT_PSW: ${{ secrets.UPBOUND_MARKETPLACE_PUSH_ROBOT_PSW }} + detect-noop: + runs-on: ubuntu-latest + outputs: + noop: ${{ steps.noop.outputs.should_skip }} + steps: + - name: Detect No-op Changes + id: noop + uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf # v5.3.1 + with: + paths_ignore: '["**.md", "**.png", "**.jpg"]' + do_not_skip: '["workflow_dispatch", "schedule", "push"]' + + report-breaking-changes: + runs-on: ubuntu-latest + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + + - name: Get modified CRDs + id: modified-crds + uses: tj-actions/changed-files@b2d17f51244a144849c6b37a3a6791b98a51d86f # v35.9.2 (breaks the 'Report native schema version changes' step on newer versions) + with: + files: | + package/crds/** + + - name: Report breaking CRD OpenAPI v3 schema changes + if: steps.modified-crds.outputs.any_changed == 'true' + env: + MODIFIED_CRD_LIST: ${{ steps.modified-crds.outputs.all_changed_files }} + run: | + make crddiff + + - name: Report native schema version changes + run: | + make schema-version-diff + + lint: + runs-on: ubuntu-latest + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + steps: + - name: Cleanup Disk + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + large-packages: false + swap-storage: false + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + + - name: Setup Go + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Find the Analysis Cache + id: analysis_cache + run: | + echo "analysis_cache=$HOME/.cache/golangci-lint" >> $GITHUB_OUTPUT && \ + echo "analysis_cache_key=$(make go.lint.analysiskey)" >> $GITHUB_OUTPUT && \ + echo "analysis_cache_key_int=$(make go.lint.analysiskey-interval)" >> $GITHUB_OUTPUT + + - name: Cache Linter Analysis + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4 + id: cache-analysis + with: + path: ${{ steps.analysis_cache.outputs.analysis_cache }} + key: ${{ steps.analysis_cache.outputs.analysis_cache_key }} + restore-keys: | + ${{ steps.analysis_cache.outputs.analysis_cache_key_int }} + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Lint + env: + GOLANGCI_LINT_CACHE: ${{ steps.go_cache.outputs.analysis_cache }} + SKIP_LINTER_ANALYSIS: false + RUN_BUILDTAGGER: true + GOGC: "50" + run: make lint + + check-diff: + runs-on: ubuntu-latest + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + steps: + - name: Cleanup Disk + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + large-packages: false + swap-storage: false + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + + - name: Setup Go + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install goimports + run: go install golang.org/x/tools/cmd/goimports + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Check Diff + id: check-diff + run: | + mkdir _output + make check-diff + env: + # check-diff depends on the generate Make target, and we would like + # to save a skipped resource list + SKIPPED_RESOURCES_CSV: ../_output/skipped_resources.csv + + - name: Show diff + if: failure() && steps.check-diff.outcome == 'failure' + run: git diff + + - name: Report Statistics + run: head -1 _output/skipped_resources.csv + + - name: Publish skipped resources CSV to Github + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: skipped_resources + path: _output/skipped_resources.csv + + unit-tests: + runs-on: ubuntu-latest + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + steps: + - name: Cleanup Disk + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + large-packages: false + swap-storage: false + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + + - name: Fetch History + run: git fetch --prune --unshallow + + - name: Setup Go + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Run Unit Tests + run: make -j2 test + + local-deploy: + runs-on: ubuntu-latest + needs: detect-noop + if: needs.detect-noop.outputs.noop != 'true' + steps: + - name: Cleanup Disk + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + large-packages: false + swap-storage: false + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + + - name: Fetch History + run: git fetch --prune --unshallow + + - name: Setup Go + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Deploying locally built provider package + run: make local-deploy + + check-examples: + runs-on: ubuntu-latest + needs: detect-noop + if: ${{ needs.detect-noop.outputs.noop != 'true' }} + + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + + - name: Check Example Manifests + run: | + ./scripts/check-examples.py package/crds examples diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml deleted file mode 100644 index 3874e6d..0000000 --- a/.github/workflows/commands.yml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: 2024 The Crossplane Authors -# -# SPDX-License-Identifier: CC0-1.0 - -name: Comment Commands - -on: issue_comment - -jobs: - comment-commands: - uses: upbound/official-providers-ci/.github/workflows/provider-commands.yml@standard-runners diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml deleted file mode 100644 index 176faa7..0000000 --- a/.github/workflows/e2e.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: 2024 The Crossplane Authors -# -# SPDX-License-Identifier: CC0-1.0 - -name: End to End Testing - -on: - issue_comment: - types: [created] - -jobs: - e2e: - uses: upbound/official-providers-ci/.github/workflows/pr-comment-trigger.yml@standard-runners - with: - go-version: 1.21 - secrets: - UPTEST_CLOUD_CREDENTIALS: ${{ secrets.UPTEST_CLOUD_CREDENTIALS }} - UPTEST_DATASOURCE: ${{ secrets.UPTEST_DATASOURCE }} diff --git a/.github/workflows/native-provider-bump.yml b/.github/workflows/native-provider-bump.yml deleted file mode 100644 index b0ab535..0000000 --- a/.github/workflows/native-provider-bump.yml +++ /dev/null @@ -1,17 +0,0 @@ -# SPDX-FileCopyrightText: 2024 The Crossplane Authors -# -# SPDX-License-Identifier: CC0-1.0 - -name: Native Provider Version Bump - -on: - workflow_dispatch: {} - -jobs: - open-bump-pr: - uses: upbound/official-providers-ci/.github/workflows/native-provider-bump.yml@standard-runners - with: - provider-source: hashicorp/azuread - go-version: 1.21 - secrets: - TOKEN: ${{ secrets.OFFICIAL_PROVIDERS_GA_TOKEN }} diff --git a/.github/workflows/tag.yaml b/.github/workflows/tag.yaml index 6ae5106..def498a 100644 --- a/.github/workflows/tag.yaml +++ b/.github/workflows/tag.yaml @@ -5,7 +5,7 @@ name: Tag on: - workflow_dispatch: + workflow_dispatch: inputs: version: description: 'Release version (e.g. v0.1.0)' @@ -15,8 +15,16 @@ on: required: true jobs: - tag: - uses: upbound/official-providers-ci/.github/workflows/provider-tag.yml@standard-runners - with: - version: ${{ github.event.inputs.version }} - message: ${{ github.event.inputs.message }} + create-tag: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Create Tag + uses: negz/create-tag@39bae1e0932567a58c20dea5a1a0d18358503320 # v1 + with: + version: ${{ github.event.inputs.version }} + message: ${{ github.event.inputs.message }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/uptest-trigger.yaml b/.github/workflows/uptest-trigger.yaml new file mode 100644 index 0000000..ffcfab5 --- /dev/null +++ b/.github/workflows/uptest-trigger.yaml @@ -0,0 +1,180 @@ +# SPDX-FileCopyrightText: 2024 The Crossplane Authors +# +# SPDX-License-Identifier: CC0-1.0 + +name: End to End Testing + +on: + issue_comment: + types: [created] + +env: + GO_VERSION: "1.23" + +jobs: + debug: + runs-on: ubuntu-latest + steps: + - name: Debug + run: | + echo "Trigger keyword: '/test-examples'" + echo "Go version: ${{ env.GO_VERSION }}" + echo "github.event.comment.author_association: ${{ github.event.comment.author_association }}" + + get-example-list: + if: ${{ (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR' || github.event.comment.author_association == 'CONTRIBUTOR' ) && + github.event.issue.pull_request && + contains(github.event.comment.body, '/test-examples' ) }} + runs-on: ubuntu-latest + outputs: + example_list: ${{ steps.get-example-list-name.outputs.example-list }} + example_hash: ${{ steps.get-example-list-name.outputs.example-hash }} + + steps: + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + + - name: Checkout PR + id: checkout-pr + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr checkout ${{ github.event.issue.number }} + git submodule update --init --recursive + OUTPUT=$(git log -1 --format='%H') + echo "commit-sha=$OUTPUT" >> $GITHUB_OUTPUT + + - name: Prepare The Example List + env: + COMMENT: ${{ github.event.comment.body }} + id: get-example-list-name + run: | + PATHS=$(echo $COMMENT | sed 's/^.*\/test-examples="//g' | cut -d '"' -f 1 | sed 's/,/ /g') + EXAMPLE_LIST="" + for P in $PATHS; do EXAMPLE_LIST="${EXAMPLE_LIST},$(find $P -name '*.yaml' | tr '\n' ',')"; done + + sudo apt-get -y install coreutils + COUNT=$(echo ${EXAMPLE_LIST:1} | grep -o ".yaml" | wc -l) + if [ $COUNT -gt 1 ]; then EXAMPLE_HASH=$(echo ${EXAMPLE_LIST} | md5sum | cut -f1 -d" "); else EXAMPLE_HASH=$(echo ${EXAMPLE_LIST:1} | sed 's/.$//'); fi + + echo "Examples: ${EXAMPLE_LIST:1}" + echo "Example Hash: ${EXAMPLE_HASH}" + + echo "example-list=${EXAMPLE_LIST:1}" >> $GITHUB_OUTPUT + echo "example-hash=${EXAMPLE_HASH}" >> $GITHUB_OUTPUT + + - name: Create Pending Status Check + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + /repos/${{ github.repository }}/statuses/${{ steps.checkout-pr.outputs.commit-sha }} \ + -f state='pending' \ + -f target_url='https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' \ + -f description='Running...' \ + -f context="Uptest-${{ steps.get-example-list-name.outputs.example-hash }}" + + uptest: + if: ${{ (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR' || github.event.comment.author_association == 'CONTRIBUTOR' ) && + github.event.issue.pull_request && + contains(github.event.comment.body, '/test-examples' ) }} + runs-on: ubuntu-latest + needs: get-example-list + + steps: + - name: Cleanup Disk + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + with: + large-packages: false + swap-storage: false + + - name: Setup QEMU + uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0 + with: + platforms: all + + - name: Checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + + - name: Setup Go + uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Checkout PR + id: checkout-pr + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh pr checkout ${{ github.event.issue.number }} + git submodule update --init --recursive + OUTPUT=$(git log -1 --format='%H') + echo "commit-sha=$OUTPUT" >> $GITHUB_OUTPUT + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Run Uptest + id: run-uptest + env: + UPTEST_CLOUD_CREDENTIALS: ${{ secrets.UPTEST_CLOUD_CREDENTIALS }} + UPTEST_EXAMPLE_LIST: ${{ needs.get-example-list.outputs.example_list }} + UPTEST_TEST_DIR: ./_output/controlplane-dump + UPTEST_DATASOURCE_PATH: .work/uptest-datasource.yaml + UPTEST_UPDATE_PARAMETER: "" + run: | + mkdir -p .work && echo "${{ secrets.UPTEST_DATASOURCE }}" > .work/uptest-datasource.yaml + make e2e + + - name: Create Successful Status Check + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EXAMPLE_HASH: ${{ needs.get-example-list.outputs.example_hash }} + run: | + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + /repos/${{ github.repository }}/statuses/${{ steps.checkout-pr.outputs.commit-sha }} \ + -f state='success' \ + -f target_url='https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' \ + -f description='Passed' \ + -f context="Uptest-${EXAMPLE_HASH}" + + - name: Collect Cluster Dump + if: always() + run: | + make controlplane.dump + + - name: Upload Cluster Dump + if: always() + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: controlplane-dump + path: ./_output/controlplane-dump + + - name: Cleanup + if: always() + run: | + eval $(make --no-print-directory build.vars) + ${KUBECTL} delete managed --all || true + + - name: Create Unsuccessful Status Check + if: failure() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EXAMPLE_HASH: ${{ needs.get-example-list.outputs.example_hash }} + run: | + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + /repos/${{ github.repository }}/statuses/${{ steps.checkout-pr.outputs.commit-sha }} \ + -f state='failure' \ + -f target_url='https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' \ + -f description='Failed' \ + -f context="Uptest-${EXAMPLE_HASH}" diff --git a/Makefile b/Makefile index a88ba44..3bc1a25 100644 --- a/Makefile +++ b/Makefile @@ -244,6 +244,13 @@ schema-version-diff: ./scripts/version_diff.py config/generated.lst "$(WORK_DIR)/schema.json.$${PREV_PROVIDER_VERSION}" config/schema.json @$(OK) Checking for native state schema version changes +go.lint.analysiskey-interval: + @# cache is invalidated at least every 7 days + @echo -n golangci-lint.cache-$$(( $$(date +%s) / (7 * 86400) ))- + +go.lint.analysiskey: + @echo $$(make go.lint.analysiskey-interval)$$(sha1sum go.sum | cut -d' ' -f1) + .PHONY: cobertura submodules fallthrough run crds.clean uptest e2e crddiff schema-version-diff # ====================================================================================