diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..610653669 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,68 @@ +name: GoRelease + +on: + pull_request: + paths: + - .github/workflows/release.yml + push: + tags: + - 'v*.*.*' +env: + GITHUB_REF: ${{ github.ref }} + +defaults: + run: + working-directory: go/src/open-cluster-management.io/ocm + +jobs: + env: + name: prepare release env + runs-on: ubuntu-latest + steps: + - name: checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 1 + path: go/src/open-cluster-management.io/ocm + - name: get release version + run: | + echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + - name: get major release version + run: | + echo "MAJOR_RELEASE_VERSION=${RELEASE_VERSION%.*}" >> $GITHUB_ENV + echo "TRIMED_RELEASE_VERSION=${RELEASE_VERSION#v}" >> $GITHUB_ENV + outputs: + MAJOR_RELEASE_VERSION: ${{ env.MAJOR_RELEASE_VERSION }} + RELEASE_VERSION: ${{ env.RELEASE_VERSION }} + release: + name: release + runs-on: ubuntu-latest + needs: [ env ] + steps: + - name: checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 1 + path: go/src/open-cluster-management.io/ocm + - name: Set up Python 3.x + uses: actions/setup-python@v4 + with: + # Semantic version range syntax or exact version of a Python version + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install PyGithub + - name: generate changelog + run: | + python hack/changelog.py ${{ secrets.GITHUB_TOKEN }} ${{ needs.env.outputs.RELEASE_VERSION }} > /home/runner/work/changelog.txt + cat /home/runner/work/changelog.txt + - name: publish release + if: github.event_name != 'pull_request' + uses: softprops/action-gh-release@v0.1.5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + body_path: /home/runner/work/changelog.txt + draft: true + generate_release_notes: true diff --git a/.github/workflows/releaseimage.yml b/.github/workflows/releaseimage.yml new file mode 100644 index 000000000..2bf996566 --- /dev/null +++ b/.github/workflows/releaseimage.yml @@ -0,0 +1,133 @@ +name: GoRelease + +on: + push: + tags: + - 'v*.*.*' +env: + # Common versions + GO_VERSION: '1.20' + GO_REQUIRED_MIN_VERSION: '' + GOPATH: '/home/runner/work/ocm/ocm/go' + GITHUB_REF: ${{ github.ref }} + +defaults: + run: + working-directory: go/src/open-cluster-management.io/ocm + +jobs: + env: + name: prepare release env + runs-on: ubuntu-latest + steps: + - name: checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 1 + path: go/src/open-cluster-management.io/ocm + - name: get release version + run: | + echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + - name: get major release version + run: | + echo "MAJOR_RELEASE_VERSION=${RELEASE_VERSION%.*}" >> $GITHUB_ENV + echo "TRIMED_RELEASE_VERSION=${RELEASE_VERSION#v}" >> $GITHUB_ENV + outputs: + MAJOR_RELEASE_VERSION: ${{ env.MAJOR_RELEASE_VERSION }} + RELEASE_VERSION: ${{ env.RELEASE_VERSION }} + images: + name: images + runs-on: ubuntu-latest + needs: [ env ] + strategy: + matrix: + arch: [ amd64, arm64 ] + steps: + - name: checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 1 + path: go/src/open-cluster-management.io/ocm + - name: install Go + uses: actions/setup-go@v4 + with: + go-version: ${{ env.GO_VERSION }} + - name: install imagebuilder + run: go install github.com/openshift/imagebuilder/cmd/imagebuilder@v1.2.3 + - name: pull base image + run: docker pull registry.access.redhat.com/ubi8/ubi-minimal:latest --platform=linux/${{ matrix.arch }} + - name: images + run: | + IMAGE_TAG=${{ needs.env.outputs.RELEASE_VERSION }}-${{ matrix.arch }} \ + IMAGE_BUILD_EXTRA_FLAGS="--build-arg OS=linux --build-arg ARCH=${{ matrix.arch }}" \ + make images + - name: push + run: | + echo ${{ secrets.DOCKER_PASSWORD }} | docker login quay.io --username ${{ secrets.DOCKER_USER }} --password-stdin + docker push quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }}-${{ matrix.arch }} + docker push quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }}-${{ matrix.arch }} + docker push quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }}-${{ matrix.arch }} + docker push quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }}-${{ matrix.arch }} + docker push quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }}-${{ matrix.arch }} + image-manifest: + name: image manifest + runs-on: ubuntu-latest + needs: [ env, images ] + steps: + - name: create + run: | + echo ${{ secrets.DOCKER_PASSWORD }} | docker login quay.io --username ${{ secrets.DOCKER_USER }} --password-stdin + # registration + docker manifest create quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 \ + quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 + # work + docker manifest create quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 \ + quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 + # placement + docker manifest create quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 \ + quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 + # addon-manager + docker manifest create quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 \ + quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 + # registration-operator + docker manifest create quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 \ + quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 + - name: annotate + run: | + # registration + docker manifest annotate quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 --arch amd64 + docker manifest annotate quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 --arch arm64 + # work + docker manifest annotate quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 --arch amd64 + docker manifest annotate quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 --arch arm64 + # placement + docker manifest annotate quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 --arch amd64 + docker manifest annotate quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 --arch arm64 + # addon-manager + docker manifest annotate quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 --arch amd64 + docker manifest annotate quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 --arch arm64 + # registration-operator + docker manifest annotate quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }}-amd64 --arch amd64 + docker manifest annotate quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }} \ + quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }}-arm64 --arch arm64 + - name: push + run: | + docker manifest push quay.io/open-cluster-management/registration:${{ needs.env.outputs.RELEASE_VERSION }} + docker manifest push quay.io/open-cluster-management/work:${{ needs.env.outputs.RELEASE_VERSION }} + docker manifest push quay.io/open-cluster-management/placement:${{ needs.env.outputs.RELEASE_VERSION }} + docker manifest push quay.io/open-cluster-management/addon-manager:${{ needs.env.outputs.RELEASE_VERSION }} + docker manifest push quay.io/open-cluster-management/registration-operator:${{ needs.env.outputs.RELEASE_VERSION }} diff --git a/deploy/cluster-manager/config/operator/operator.yaml b/deploy/cluster-manager/config/operator/operator.yaml index 3c842dc11..4b2181988 100644 --- a/deploy/cluster-manager/config/operator/operator.yaml +++ b/deploy/cluster-manager/config/operator/operator.yaml @@ -70,5 +70,5 @@ spec: initialDelaySeconds: 2 resources: requests: - cpu: 100m - memory: 128Mi + cpu: 2m + memory: 16Mi diff --git a/deploy/cluster-manager/olm-catalog/cluster-manager/manifests/cluster-manager.clusterserviceversion.yaml b/deploy/cluster-manager/olm-catalog/cluster-manager/manifests/cluster-manager.clusterserviceversion.yaml index 46f57064b..303889019 100644 --- a/deploy/cluster-manager/olm-catalog/cluster-manager/manifests/cluster-manager.clusterserviceversion.yaml +++ b/deploy/cluster-manager/olm-catalog/cluster-manager/manifests/cluster-manager.clusterserviceversion.yaml @@ -59,7 +59,7 @@ metadata: categories: Integration & Delivery,OpenShift Optional certified: "false" containerImage: quay.io/open-cluster-management/registration-operator:latest - createdAt: "2023-09-12T15:35:29Z" + createdAt: "2023-09-19T07:31:35Z" description: Manages the installation and upgrade of the ClusterManager. operators.operatorframework.io/builder: operator-sdk-v1.28.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 @@ -561,8 +561,8 @@ spec: initialDelaySeconds: 2 resources: requests: - cpu: 100m - memory: 128Mi + cpu: 2m + memory: 16Mi securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/deploy/klusterlet/config/operator/operator.yaml b/deploy/klusterlet/config/operator/operator.yaml index 2abdbfb9b..b65efba6e 100644 --- a/deploy/klusterlet/config/operator/operator.yaml +++ b/deploy/klusterlet/config/operator/operator.yaml @@ -73,8 +73,8 @@ spec: initialDelaySeconds: 2 resources: requests: - cpu: 100m - memory: 128Mi + cpu: 2m + memory: 16Mi # Uncomment the following configuration lines to add hostAliases for hub api server, # if the server field in your hub cluster kubeconfig is a domain name instead of an ipv4 address. # For example, https://xxx.yyy.zzz. diff --git a/deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml b/deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml index 5b24b8de4..2997cb2a7 100644 --- a/deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml +++ b/deploy/klusterlet/olm-catalog/klusterlet/manifests/klusterlet.clusterserviceversion.yaml @@ -31,7 +31,7 @@ metadata: categories: Integration & Delivery,OpenShift Optional certified: "false" containerImage: quay.io/open-cluster-management/registration-operator:latest - createdAt: "2023-09-12T15:35:29Z" + createdAt: "2023-09-19T07:31:35Z" description: Manages the installation and upgrade of the Klusterlet. operators.operatorframework.io/builder: operator-sdk-v1.28.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 @@ -305,8 +305,8 @@ spec: initialDelaySeconds: 2 resources: requests: - cpu: 100m - memory: 128Mi + cpu: 2m + memory: 16Mi securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/deploy/klusterlet/olm-catalog/klusterlet/manifests/operator.open-cluster-management.io_klusterlets.yaml b/deploy/klusterlet/olm-catalog/klusterlet/manifests/operator.open-cluster-management.io_klusterlets.yaml index adaadabc6..04c30cb72 100644 --- a/deploy/klusterlet/olm-catalog/klusterlet/manifests/operator.open-cluster-management.io_klusterlets.yaml +++ b/deploy/klusterlet/olm-catalog/klusterlet/manifests/operator.open-cluster-management.io_klusterlets.yaml @@ -49,16 +49,17 @@ spec: description: DeployOption contains the options of deploying a klusterlet properties: mode: - description: 'Mode can be Default, Hosted or Singleton. It is - Default mode if not specified In Default mode, all klusterlet + description: 'Mode can be Default, Hosted, Singleton or SingletonHosted. + It is Default mode if not specified In Default mode, all klusterlet related resources are deployed on the managed cluster. In Hosted mode, only crd and configurations are installed on the spoke/managed cluster. Controllers run in another cluster (defined as management-cluster) and connect to the mangaged cluster with the kubeconfig in secret of "external-managed-kubeconfig"(a kubeconfig of managed-cluster with cluster-admin permission). In Singleton mode, registration/work - agent is started as a single deployment. Note: Do not modify - the Mode field once it''s applied.' + agent is started as a single deployment. In SingletonHosted + mode, agent is started as a single deployment in hosted mode. + Note: Do not modify the Mode field once it''s applied.' type: string type: object externalServerURLs: diff --git a/hack/changelog.py b/hack/changelog.py new file mode 100644 index 000000000..937bef17f --- /dev/null +++ b/hack/changelog.py @@ -0,0 +1,116 @@ +import sys + +from enum import Enum +from github import Github +from github import Auth + +emojiFeature = str('✨') +emojiBugfix = str('🐛') +emojiDocs = str('📖') +emojiInfra = str('🌱') +emojiBreaking = str('⚠') + + +class PRType(Enum): + UncategorizedPR = 1 + BreakingPR = 2 + FeaturePR = 3 + BugfixPR = 4 + DocsPR = 5 + InfraPR = 6 + + +def pr_type_from_title(pr_title: str): + t = pr_title.strip() + if len(pr_title) == 0: + return PRType.UncategorizedPR, t + + if pr_title.startswith(':sparkles:') or pr_title.startswith(emojiFeature): + return PRType.FeaturePR, t.removeprefix(':sparkles:').removeprefix(emojiFeature).strip() + elif pr_title.startswith(':bug:') or pr_title.startswith(emojiBugfix): + return PRType.BugfixPR, t.removeprefix(':bug:').removeprefix(emojiBugfix).strip() + elif pr_title.startswith(':book:') or pr_title.startswith(emojiDocs): + return PRType.DocsPR, t.removeprefix(':book:').removeprefix(emojiDocs).strip() + elif pr_title.startswith(':seedling:') or pr_title.startswith(emojiInfra): + return PRType.InfraPR, t.removeprefix(':seedling:').removeprefix(emojiInfra).strip() + elif pr_title.startswith(':warning:') or pr_title.startswith(emojiBreaking): + return PRType.BreakingPR, t.removeprefix(':warning:').removeprefix(emojiBreaking).strip() + + return PRType.UncategorizedPR, t + + +def change_entry(pr_title, number, author): + return "%s (#%d) @%s" % (pr_title, number, author) + + +def section_if_present(changes: [], pr_title): + if len(changes) > 0: + print("") + print("## %s\n" % pr_title) + print("") + for change in changes: + print("- %s\n" % change) + + +if __name__ == '__main__': + args = sys.argv[1:] + auth = Auth.Token(args[0]) + release_tag = args[1] + g = Github(auth=auth) + repo = g.get_repo("open-cluster-management-io/ocm") + pulls = repo.get_pulls(state='closed', sort='created', base='main', direction='desc') + + # get the last release tag + tags = repo.get_tags() + if tags.totalCount == 0: + print("no tags in the repo") + sys.exit() + elif tags.totalCount == 1: + last_release_tag = tags[0].name + else: + last_release_tag = tags[1].name + + # get related PR from the last release tag + last_release_pr = 0 + for tag in tags: + if tag.name == last_release_tag: + tag_pulls = tag.commit.get_pulls() + last_release_pr = tag_pulls[0].number + break + + # collect all PRs from the last release tag + features = [] + bugs = [] + breakings = [] + docs = [] + infras = [] + uncategorized = [] + for pr in pulls: + if pr.number == last_release_pr: + break + if pr.is_merged(): + prtype, title = pr_type_from_title(pr.title) + if prtype == PRType.FeaturePR: + features.append(change_entry(title, pr.number, pr.user.login)) + elif prtype == PRType.BugfixPR: + bugs.append(change_entry(title, pr.number, pr.user.login)) + elif prtype == PRType.DocsPR: + docs.append(change_entry(title, pr.number, pr.user.login)) + elif prtype == PRType.InfraPR: + infras.append(change_entry(title, pr.number, pr.user.login)) + elif prtype == PRType.BreakingPR: + breakings.append(change_entry(title, pr.number, pr.user.login)) + elif prtype == PRType.UncategorizedPR: + uncategorized.append(change_entry(title, pr.number, pr.user.login)) + + # Print + print("# Open Cluster Management %s" % release_tag) + print("\n**changes since [%s](https://github.com/open-cluster-management-io/releases/%s)**\n" + % (last_release_tag, last_release_tag)) + section_if_present(breakings, ":warning: Breaking Changes") + section_if_present(features, ":sparkles: New Features") + section_if_present(bugs, ":bug: Bug Fixes") + section_if_present(docs, ":book: Documentation") + section_if_present(infras, ":seedling: Infra & Such") + print("") + print("Thanks to all our contributors!*")