From 2829be7f0409e97fe24a4ab835300d9eaea8211c Mon Sep 17 00:00:00 2001 From: Johannes Fleck Date: Fri, 30 Oct 2026 16:35:21 +0100 Subject: [PATCH 1/3] feat: add cockpit --- release/EXAMPLE_PROCESS.md | 11 +++ release/README.md | 41 +++++++---- release/common.sh | 16 ++++- release/config.yaml | 1 + release/create-release-branch.sh | 17 ++++- release/create-release-candidate-branch.sh | 81 +++++++++++++++++++++- release/merge-release-candidate.sh | 30 +++++++- release/post-release.sh | 74 +++++++++++++++++++- release/tag-release-candidate.sh | 37 +++++++++- release/test_common.bats | 19 +++++ 10 files changed, 302 insertions(+), 25 deletions(-) diff --git a/release/EXAMPLE_PROCESS.md b/release/EXAMPLE_PROCESS.md index 0c7d890..c6444f8 100644 --- a/release/EXAMPLE_PROCESS.md +++ b/release/EXAMPLE_PROCESS.md @@ -9,6 +9,7 @@ It is a good idea to do a dry-run check locally, and then delete the local state # Create and switch to branch: release-YY.M. ./release/create-release-branch.sh -b YY.M -w products ./release/create-release-branch.sh -b YY.M -w operators +./release/create-release-branch.sh -b YY.M -w cockpit ./release/create-release-branch.sh -b YY.M -w demos # Clone to /tmp/stackable-release-YY.M/docker-images and/or enter the directory. @@ -20,11 +21,13 @@ It is a good idea to do a dry-run check locally, and then delete the local state # Raise a PR (dry-run). ./release/create-release-candidate-branch.sh -t YY.M.X-rc1 -w products ./release/create-release-candidate-branch.sh -t YY.M.X-rc1 -w operators +./release/create-release-candidate-branch.sh -t YY.M.X-rc1 -w cockpit # Pretend the PR exists, and exit. # This doesn't really test much. ./release/merge-release-candidate.sh -t YY.M.X-rc1 -w products ./release/merge-release-candidate.sh -t YY.M.X-rc1 -w operators +./release/merge-release-candidate.sh -t YY.M.X-rc1 -w cockpit # Clone to /tmp/stackable-release-YY.M/docker-images and/or enter the directory. # Fetch and switch to branch: release-YY.M. @@ -33,6 +36,7 @@ It is a good idea to do a dry-run check locally, and then delete the local state # Tag the HEAD commit (in this case it would be the same as `main` where this branch was based). ./release/tag-release-candidate.sh -t YY.M.X-rc1 -w products ./release/tag-release-candidate.sh -t YY.M.X-rc1 -w operators +./release/tag-release-candidate.sh -t YY.M.X-rc1 -w cockpit # TODO: ./release/post-release.sh ``` @@ -55,6 +59,7 @@ This procedure would be done until a viable release-candidate can be selected. # Push the branch. ./release/create-release-branch.sh -b YY.M -w products -p ./release/create-release-branch.sh -b YY.M -w operators -p +./release/create-release-branch.sh -b YY.M -w cockpit -p ./release/create-release-branch.sh -b YY.M -w demos -p # Clone to /tmp/stackable-release-YY.M/docker-images and/or enter the directory. @@ -65,6 +70,7 @@ This procedure would be done until a viable release-candidate can be selected. # Raise a PR. ./release/create-release-candidate-branch.sh -t YY.M.X-rc1 -w products -p ./release/create-release-candidate-branch.sh -t YY.M.X-rc1 -w operators -p +./release/create-release-candidate-branch.sh -t YY.M.X-rc1 -w cockpit -p ``` Ask people to do approvals. @@ -80,6 +86,7 @@ Once all approvals are done, merge the changes and tag the release branch `HEAD` # Merge the PR (this does not seem to wait for checks to complete). ./release/merge-release-candidate.sh -t YY.M.X-rc1 -w products -p ./release/merge-release-candidate.sh -t YY.M.X-rc1 -w operators -p +./release/merge-release-candidate.sh -t YY.M.X-rc1 -w cockpit -p ``` It is still worth checking that all PRs are merged. @@ -94,6 +101,7 @@ It is still worth checking that all PRs are merged. # Push tag. ./release/tag-release-candidate.sh -t YY.M.X-rc1 -w products -p ./release/tag-release-candidate.sh -t YY.M.X-rc1 -w operators -p +./release/tag-release-candidate.sh -t YY.M.X-rc1 -w cockpit -p ``` > [!CAUTION] @@ -123,6 +131,7 @@ Once the release candidate has been deemed good, do the release proper: # Raise a PR. ./release/create-release-candidate-branch.sh -t YY.M.X -w products -p ./release/create-release-candidate-branch.sh -t YY.M.X -w operators -p +./release/create-release-candidate-branch.sh -t YY.M.X -w cockpit -p ``` Ask people to do approvals. @@ -138,6 +147,7 @@ Once all approvals are done, merge the changes and tag the release branch `HEAD` # Merge the PR (this does not seem to wait for checks to complete). ./release/merge-release-candidate.sh -t YY.M.X -w products -p ./release/merge-release-candidate.sh -t YY.M.X -w operators -p +./release/merge-release-candidate.sh -t YY.M.X -w cockpit -p # Clone to /tmp/stackable-release-YY.M/docker-images and/or enter the directory. # Fetch, including tags. @@ -148,6 +158,7 @@ Once all approvals are done, merge the changes and tag the release branch `HEAD` # Push tag. ./release/tag-release-candidate.sh -t YY.M.X -w products -p ./release/tag-release-candidate.sh -t YY.M.X -w operators -p +./release/tag-release-candidate.sh -t YY.M.X -w cockpit -p ``` > [!CAUTION] diff --git a/release/README.md b/release/README.md index c6408c3..6da78aa 100644 --- a/release/README.md +++ b/release/README.md @@ -41,6 +41,16 @@ These steps are repeated for each release tag i.e. for both release-candidates a # build failures are not yet sent to the #notifications-container-images channel yet. # repeat the above with e.g. the tag 25.3.0 once a release candidate is accepted. +# continue with cockpit ... +# same flow as the operators: branch, RC PR, merge, tag +./release/create-release-branch.sh -b 25.3 -w cockpit # Only add the -p flag after testing locally first +./release/create-release-candidate-branch.sh -t 25.3.0-rc1 -w cockpit # Only add the -p flag after testing locally first +./release/merge-release-candidate.sh -t 25.3.0-rc1 -w cockpit # Only add the -p flag after testing locally first +./release/tag-release-candidate.sh -t 25.3.0-rc1 -w cockpit # Only add the -p flag after testing locally first + +# monitor the GH action that builds the cockpit image and Helm chart for success. +# repeat the above with e.g. the tag 25.3.0 once a release candidate is accepted. + # continue with the demos ... # create and push the release branch (demos are intentionally branch-only: # no RC branches, no tagging, no post-release steps) @@ -112,14 +122,15 @@ A set of scripts that automates some release steps. The release process has mult 4. Call `tag-release-candidate.sh` - This will: - tag merge commit from above, triggering github actions to build the product images and operators 5. Call `post-release.sh`- This will: - - update the operator CHANGELOG.md in `main` with changes from the release tag - - create PRs for all operators + - update the operator and cockpit CHANGELOG.md in `main` with changes from the release tag + - create PRs for all operators and cockpit > [!NOTE] > - Steps 2-4 will check out the release branch (or clone it if does exist locally) and so can be run independently of each other. > - Any changes should be done manually between steps 2 and 3 i.e. by making changes in the PR branch and/or cherry-picking commits from main. > - Demos only require step 1 (branch creation). They are intentionally not tagged or given release candidates. +> - Cockpit follows the same steps as the operators. ## Install requirements @@ -163,13 +174,13 @@ pipx inject jinja2-cli pyyaml To create release branches use the `create-release-branch.sh` script, called from the repository root folder. The syntax is given below: ```shell -./release/create-release-branch.sh -b [-p] [-c] [-w products|operators|demos|all] +./release/create-release-branch.sh -b [-p] [-c] [-w products|operators|cockpit|demos|all] ``` - `-b `: the release number (mandatory). This must be a semver-compatible value (i.e. without leading zeros) such as `23.1`, `23.10` etc. and will be used to create a branch with the name `release-` e.g. `release-23.1`. - `-p`: push flag (optional, default is "false"). If provided, the created branches plus any changes made as part of this process will be pushed to the origin. - `-c`: cleanup flag (optional, default is "false"). If provided, the repository folders will be torn down on completion. -- `-w`: where to create the branch. It can be "products", "operators", "demos" or "all". +- `-w`: where to create the branch. It can be "products", "operators", "cockpit", "demos" or "all". N.B. the flags cannot be combined (e.g. `-p -c` but not `-pc) @@ -192,13 +203,13 @@ e.g. To create release tags use the `create-release-candidate-branch.sh` script, called from the repository root folder. The syntax is given below: ```shell -./release/create-release-candidate-branch.sh -t [-p] [-c] [-w products|operators|all] +./release/create-release-candidate-branch.sh -t [-p] [-c] [-w products|operators|cockpit|all] ``` - `-t `: the release tag (mandatory). This must be a semver-compatible value (i.e. major/minor/path, without leading zeros) such as `23.1.0`, `23.10.3-rc1` etc. and will be used to create a tag with the name. - `-p`: push flag (optional, default is "false"). If provided, the changes and PRs made as part of this process will be pushed to the origin. - `-c`: cleanup flag (optional, default is "false"). If provided, the repository folders will be torn down on completion. -- `-w`: where to create the tag and update versions in code. It can be "products", "operators" or "all". +- `-w`: where to create the tag and update versions in code. It can be "products", "operators", "cockpit" or "all". N.B. the flags cannot be combined (e.g. `-p -c` but not `-pc) @@ -220,6 +231,7 @@ e.g. - update the `release-tag` in helm charts - rebuilds the helm charts - bumps the changelog + - for cockpit: sets the version in `package.json`, `package-lock.json` and the Helm `Chart.yaml` instead of the Rust/docs updates above - optional: pushes the new branch (if requested with "-p") - optional: deletes the temporary folder (if requested with "-c") @@ -233,12 +245,12 @@ Product and operator images will be built when these PRs are created or updated, To merge PRs use the `merge-release-candidate.sh` script, called from the repository root folder. The syntax is given below: ```shell -./release/merge-release-candidate.sh -t [-p] [-w products|operators|all] +./release/merge-release-candidate.sh -t [-p] [-w products|operators|cockpit|all] ``` - `-t `: the release tag (mandatory). This must be a semver-compatible value (i.e. major/minor/path, without leading zeros) such as `23.1.0`, `23.10.3-rc1` etc. and will be used to identify the PR (which was created using this tag). - `-p`: push flag (optional, default is "false"). If provided, the PRs will be approved and merged. -- `-w`: where to create the tag and update versions in code. It can be "products", "operators" or "all". +- `-w`: where to create the tag and update versions in code. It can be "products", "operators", "cockpit" or "all". e.g. @@ -259,13 +271,13 @@ e.g. The final step is to tag the merge commit from above: this is done using the `tag-release-candidate.sh` script, called from the repository root folder. The syntax is given below: ```shell -./release/tag-release-candidate.sh -t [-p] [-c] [-w products|operators|all] +./release/tag-release-candidate.sh -t [-p] [-c] [-w products|operators|cockpit|all] ``` - `-t `: the release tag (mandatory). This must be a semver-compatible value (i.e. major/minor/path, without leading zeros) such as `23.1.0`, `23.10.3-rc1` etc. and will be used to create a tag with the name. - `-p`: push flag (optional, default is "false"). If provided, the created commits and tags made as part of this process will be pushed to the origin. - `-c`: cleanup flag (optional, default is "false"). If provided, the repository folders will be torn down on completion. -- `-w`: where to create the tag and update versions in code. It can be "products", "operators" or "all". +- `-w`: where to create the tag and update versions in code. It can be "products", "operators", "cockpit" or "all". #### What this script does @@ -281,12 +293,12 @@ The final step is to tag the merge commit from above: this is done using the `ta Some post release steps are performed with `release/post-release.sh` script, called from the repository root folder. The syntax is given below: ```shell -./release/post-release.sh -t [-p] [-w products|operators|all] +./release/post-release.sh -t [-p] [-w products|operators|cockpit|all] ``` - `-t `: the release tag (mandatory). This must be a semver-compatible value (i.e. major/minor/path, without leading zeros) such as `23.1.0`, `23.10.3` etc. and will be used to create a tag with the name. - `-p`: push flag (optional, default is "false"). If provided, the created commits and tags made as part of this process will be pushed to the origin. -- `-w`: which repositories to update the changelogs for. It can be "products", "operators", "all" (defaults to "all"). +- `-w`: which repositories to update the changelogs for. It can be "products", "operators", "cockpit", "all" (defaults to "all"). #### What this script does @@ -294,6 +306,7 @@ Some post release steps are performed with `release/post-release.sh` script, cal - checks that the release tag exists and that the docker-images repository has a clean working copy - merges the CHANGELOG.md from the release tag into main - creates PRs for all operators +- does the same for the cockpit repository ## Build actions @@ -325,6 +338,10 @@ on: ... ``` +### Cockpit image and Helm chart + +The cockpit image and Helm chart are built by `build.yaml` in the cockpit repository when a matching tag is pushed. The tag filter there must accept CalVer tags (two-digit year, e.g. `26.3.0`), otherwise tagging builds nothing. + ## Post-release steps Once the release is complete and all steps above have been verified, the documentation needs to be updated and built. This is done in a separate suite of scripts found https://github.com/stackabletech/documentation/tree/main/scripts[here]. Follow the steps given in the two scripts (there are prompts provided which allow for early-exit if things are not as they should be!). diff --git a/release/common.sh b/release/common.sh index d47ed00..5746d61 100644 --- a/release/common.sh +++ b/release/common.sh @@ -103,6 +103,16 @@ verify_release() { fi fi + # package.json version (cockpit) + if [ -f "$dir/package.json" ]; then + local package_ver + package_ver=$(yq -p json '.version' "$dir/package.json") + if [ "$package_ver" != "$tag" ]; then + >&2 echo " FAIL: package.json version is '$package_ver', expected '$tag'" + errors=$((errors + 1)) + fi + fi + # Helm Chart.yaml version and appVersion local chart_yaml chart_yaml=$(find "$dir/deploy/helm" -maxdepth 2 -name "Chart.yaml" -print -quit 2>/dev/null || true) @@ -334,7 +344,7 @@ validate_release_base_version() { # Derive common variables from a release tag. # Requires $INITIAL_DIR to be set (for reading config.yaml). # -# Sets: RELEASE_BASE, RELEASE_BRANCH, PR_BRANCH, DOCKER_IMAGES_REPO, TEMP_RELEASE_FOLDER +# Sets: RELEASE_BASE, RELEASE_BRANCH, PR_BRANCH, DOCKER_IMAGES_REPO, COCKPIT_REPO, TEMP_RELEASE_FOLDER # # Usage: # INITIAL_DIR="$PWD" @@ -346,13 +356,14 @@ derive_tag_vars() { RELEASE_BRANCH="release-$RELEASE_BASE" # e.g., release-26.3 PR_BRANCH="pr-$tag" # e.g., pr-26.3.0-rc1 DOCKER_IMAGES_REPO=$(yq '... comments="" | .images-repo ' "$INITIAL_DIR"/release/config.yaml) + COCKPIT_REPO=$(yq '... comments="" | .cockpit-repo ' "$INITIAL_DIR"/release/config.yaml) TEMP_RELEASE_FOLDER="/tmp/stackable-$RELEASE_BRANCH" } # Derive common variables from a release base version (YY.M). # Requires $INITIAL_DIR to be set (for reading config.yaml). # -# Sets: RELEASE_BRANCH, DOCKER_IMAGES_REPO, DEMOS_REPO, TEMP_RELEASE_FOLDER +# Sets: RELEASE_BRANCH, DOCKER_IMAGES_REPO, DEMOS_REPO, COCKPIT_REPO, TEMP_RELEASE_FOLDER # # Usage: # INITIAL_DIR="$PWD" @@ -363,6 +374,7 @@ derive_branch_vars() { RELEASE_BRANCH="release-$release_base" # e.g., release-26.3 DOCKER_IMAGES_REPO=$(yq '... comments="" | .images-repo ' "$INITIAL_DIR"/release/config.yaml) DEMOS_REPO=$(yq '... comments="" | .demos-repo ' "$INITIAL_DIR"/release/config.yaml) + COCKPIT_REPO=$(yq '... comments="" | .cockpit-repo ' "$INITIAL_DIR"/release/config.yaml) TEMP_RELEASE_FOLDER="/tmp/stackable-$RELEASE_BRANCH" } diff --git a/release/config.yaml b/release/config.yaml index c69a132..32b3231 100644 --- a/release/config.yaml +++ b/release/config.yaml @@ -1,6 +1,7 @@ --- demos-repo: demos images-repo: docker-images +cockpit-repo: cockpit operators: - airflow-operator - commons-operator diff --git a/release/create-release-branch.sh b/release/create-release-branch.sh index abce818..b5526ba 100755 --- a/release/create-release-branch.sh +++ b/release/create-release-branch.sh @@ -38,6 +38,17 @@ update_operator() ( push_branch "$operator" ) +update_cockpit() ( + ensure_clone "$COCKPIT_REPO" "--branch main" + cd "$COCKPIT_REPO" + assert_cwd_is_repo "$COCKPIT_REPO" + assert_clean_index "$COCKPIT_REPO" + git pull && git switch "${RELEASE_BRANCH}" 2> /dev/null || git switch -c "${RELEASE_BRANCH}" + assert_on_branch "$RELEASE_BRANCH" + assert_remote_exists "$REMOTE" "$COCKPIT_REPO" + push_branch "$COCKPIT_REPO" +) + update_demos() ( ensure_clone "$DEMOS_REPO" "--branch main" cd "$DEMOS_REPO" @@ -61,10 +72,12 @@ update_repos() { case "$WHAT" in products) update_products ;; operators) for_each_operator update_operator ;; + cockpit) update_cockpit ;; demos) update_demos ;; all) update_products for_each_operator update_operator + update_cockpit update_demos ;; esac @@ -119,12 +132,12 @@ main() { parse_inputs "$@" if [ -z "${RELEASE_BASE}" ]; then - >&2 echo "Usage: create-release-branch.sh -b [-p] [-c] [-w products|operators|demos|all]" + >&2 echo "Usage: create-release-branch.sh -b [-p] [-c] [-w products|operators|cockpit|demos|all]" exit 1 fi validate_release_base_version "$RELEASE_BASE" - validate_what "$WHAT" "products" "operators" "demos" "all" + validate_what "$WHAT" "products" "operators" "cockpit" "demos" "all" check_common_dependencies ensure_temp_folder diff --git a/release/create-release-candidate-branch.sh b/release/create-release-candidate-branch.sh index 37d3cf4..87c7e09 100755 --- a/release/create-release-candidate-branch.sh +++ b/release/create-release-candidate-branch.sh @@ -109,14 +109,52 @@ rc_branch_operator() ( commit_and_push_rc "$operator" ) +rc_branch_cockpit() ( + cd "$COCKPIT_REPO" + assert_cwd_is_repo "$COCKPIT_REPO" + assert_clean_index "$COCKPIT_REPO" + git switch "$PR_BRANCH" + assert_on_branch "$PR_BRANCH" + + # package.json drives the image tag of PR builds against the release branch, + # the Chart.yaml version is checked by verify_release. + # yq is used instead of npm to avoid a Node.js dependency. It must not reformat + # the JSON files, which is checked below by counting the changed lines. + yq -i -p json -o json -I 2 ".version = \"${RELEASE_TAG}\"" package.json + yq -i -p json -o json -I 2 ".version = \"${RELEASE_TAG}\" | .packages[\"\"].version = \"${RELEASE_TAG}\"" package-lock.json + # The chart directory is named after the project, which is being renamed + local chart_yaml + chart_yaml=$(find deploy/helm -maxdepth 2 -name "Chart.yaml" -print -quit) + yq -i ".version = \"${RELEASE_TAG}\" | .appVersion = \"${RELEASE_TAG}\"" "$chart_yaml" + + local changed_lines + changed_lines=$(git diff --numstat -- package.json package-lock.json | awk '{ sum += $1 + $2 } END { print sum + 0 }') + # At most: one version line in package.json, two in package-lock.json (added and removed each) + if [ "$changed_lines" -gt 6 ]; then + >&2 echo "Error: bumping the version reformatted package.json/package-lock.json ($changed_lines lines changed):" + >&2 git diff --stat -- package.json package-lock.json + exit 1 + fi + git add package.json package-lock.json "$chart_yaml" + + # inserts a single line with tag and date + update_changelog ./CHANGELOG.md "$RELEASE_TAG" + git add CHANGELOG.md + + verify_release "." "$RELEASE_TAG" "$RELEASE_BASE" + commit_and_push_rc "$COCKPIT_REPO" +) + rc_branch_repos() { cd "$TEMP_RELEASE_FOLDER" case "$WHAT" in products) rc_branch_products ;; operators) for_each_operator rc_branch_operator ;; + cockpit) rc_branch_cockpit ;; all) rc_branch_products for_each_operator rc_branch_operator + rc_branch_cockpit ;; esac } @@ -189,6 +227,43 @@ check_operator() ( assert_tag_not_exists "$REMOTE" "$RELEASE_TAG" ) +check_cockpit() ( + echo "Checking cockpit" + + ensure_clone "$COCKPIT_REPO" + cd "$COCKPIT_REPO" + assert_cwd_is_repo "$COCKPIT_REPO" + assert_clean_index "$COCKPIT_REPO" + + # Need to update here because if we deleted the local state, or someone else continues + # we might be back on main, or on the release branch without having pulled updates from fixes. + git fetch && git switch "$RELEASE_BRANCH" + if $PUSH; then + # In push mode, we expect the remote branch to exist, so pull must not fail. + if ! git pull; then + echo "Unable to pull $RELEASE_BRANCH. Not in dry-run mode" >&2 + exit 1 + fi + else + # In dry-run mode, the release branch may only exist locally. It is ok if pull fails. + git pull 2>/dev/null || true + fi + assert_on_branch "$RELEASE_BRANCH" + # The release branch exists if the previous (create-release-branch.sh) script was run with `-p`. + if $PUSH; then + assert_remote_branch_exists "$REMOTE" "$RELEASE_BRANCH" + fi + + # The PR branch should not exist yet, otherwise a duplicate commit will be prepared + assert_remote_branch_not_exists "$REMOTE" "$PR_BRANCH" + + # create a new branch for the PR off of this + git switch "$PR_BRANCH" "$RELEASE_BRANCH" 2>/dev/null || git switch -c "$PR_BRANCH" "$RELEASE_BRANCH" + assert_on_branch "$PR_BRANCH" + + assert_tag_not_exists "$REMOTE" "$RELEASE_TAG" +) + checks() { cd "$TEMP_RELEASE_FOLDER" case "$WHAT" in @@ -197,10 +272,12 @@ checks() { echo "Checking operators" for_each_operator check_operator ;; + cockpit) check_cockpit ;; all) check_products echo "Checking operators" for_each_operator check_operator + check_cockpit ;; esac } @@ -323,12 +400,12 @@ main() { parse_inputs "$@" if [ -z "${RELEASE_TAG}" ]; then - >&2 echo "Usage: create-release-candidate-branch.sh -t [-p] [-c] [-w products|operators|all]" + >&2 echo "Usage: create-release-candidate-branch.sh -t [-p] [-c] [-w products|operators|cockpit|all]" exit 1 fi validate_tag "$RELEASE_TAG" - validate_what "$WHAT" "products" "operators" "all" + validate_what "$WHAT" "products" "operators" "cockpit" "all" ensure_temp_folder check_dependencies diff --git a/release/merge-release-candidate.sh b/release/merge-release-candidate.sh index 8c9ba1e..32a56a0 100755 --- a/release/merge-release-candidate.sh +++ b/release/merge-release-candidate.sh @@ -104,13 +104,39 @@ merge_products() { fi } +merge_cockpit() { + echo "Cockpit: $COCKPIT_REPO" + if $PUSH; then + STATE=$(gh pr view "${PR_BRANCH}" -R stackabletech/"${COCKPIT_REPO}" --jq '.state' --json state) + else + echo "Dry-run: skipping PR existence check for ${COCKPIT_REPO}" + STATE="OPEN" + fi + if [[ "$STATE" == "OPEN" ]]; then + echo "Processing ${COCKPIT_REPO} in branch ${PR_BRANCH} with state ${STATE}" + if $PUSH; then + read -p "Ask someone to approve the PR, then press Enter" + echo "Merging..." + gh pr merge "${PR_BRANCH}" --delete-branch --squash -R stackabletech/"${COCKPIT_REPO}" + else + echo "Dry-run: not reviewing/merging..." + echo + echo "Please checkout the release branch, and manually run git merge ${PR_BRANCH}" + fi + else + echo "Skipping ${COCKPIT_REPO}, PR already closed" + fi +} + merge() { case "$WHAT" in products) merge_products ;; operators) merge_operators ;; + cockpit) merge_cockpit ;; all) merge_products merge_operators + merge_cockpit ;; esac } @@ -123,12 +149,12 @@ main() { parse_inputs "$@" if [ -z "${RELEASE_TAG}" ]; then - >&2 echo "Usage: merge-release-candidate.sh -t [-p] [-w products|operators|all]" + >&2 echo "Usage: merge-release-candidate.sh -t [-p] [-w products|operators|cockpit|all]" exit 1 fi validate_tag "$RELEASE_TAG" - validate_what "$WHAT" "products" "operators" "all" + validate_what "$WHAT" "products" "operators" "cockpit" "all" check_dependencies merge } diff --git a/release/post-release.sh b/release/post-release.sh index b08fb33..2f33b0e 100755 --- a/release/post-release.sh +++ b/release/post-release.sh @@ -74,7 +74,7 @@ update_operator() ( # New branch that updates the CHANGELOG CHANGELOG_BRANCH="chore/update-changelog-from-release-$RELEASE_TAG" # Branch out from main - git switch "$CHANGELOG_BRANCH" 2>/dev/null || git switch -c "$CHANGELOG_BRANCH" + git switch "$CHANGELOG_BRANCH" 2>/dev/null || git switch -c "$CHANGELOG_BRANCH" assert_on_branch "$CHANGELOG_BRANCH" # Checkout CHANGELOG changes from the release tag git checkout "$RELEASE_TAG" -- CHANGELOG.md @@ -164,18 +164,78 @@ update_products() ( fi ) +# Check that the cockpit repo has been cloned locally, and that the release +# branch and tag exists. +check_cockpit() ( + ensure_clone "$COCKPIT_REPO" + cd "$COCKPIT_REPO" + assert_cwd_is_repo "$COCKPIT_REPO" + assert_clean_index "$COCKPIT_REPO" + + # The release branch should exist (created in a prior step) + assert_remote_branch_exists "$REMOTE" "$RELEASE_BRANCH" + + git fetch --tags + # check tags: N.B. look for exact match + if ! git tag | grep "^$RELEASE_TAG\$"; then + >&2 echo "Expected tag $RELEASE_TAG missing for $COCKPIT_REPO" + exit 1 + fi +) + +# Update the cockpit changelog on main, and check it does not differ from +# the changelog in the release branch. +update_cockpit() ( + cd "$COCKPIT_REPO" + assert_cwd_is_repo "$COCKPIT_REPO" + assert_clean_index "$COCKPIT_REPO" + + git checkout main + assert_on_branch "main" + git pull + + # New branch that updates the CHANGELOG + CHANGELOG_BRANCH="chore/update-changelog-from-release-$RELEASE_TAG" + # Branch out from main + git switch "$CHANGELOG_BRANCH" 2>/dev/null || git switch -c "$CHANGELOG_BRANCH" + assert_on_branch "$CHANGELOG_BRANCH" + # Checkout CHANGELOG changes from the release tag + git checkout "$RELEASE_TAG" -- CHANGELOG.md + # Ensure only the CHANGELOG has been modified and there + # are no conflicts. + CHANGELOG_MODIFIED=$(git status --short) + if [ "M CHANGELOG.md" != "$CHANGELOG_MODIFIED" ]; then + echo "Failed to update CHANGELOG.md in main for $COCKPIT_REPO" + exit 1 + fi + # Commit the updated CHANGELOG. + git add CHANGELOG.md + git commit -sm "Update CHANGELOG.md from release $RELEASE_TAG" + assert_clean_index "$COCKPIT_REPO" + # Maybe push and create pull request + assert_remote_exists "$REMOTE" "$COCKPIT_REPO" + if "$PUSH"; then + git push -u "${REMOTE}" "${CHANGELOG_BRANCH}" + gh pr create --reviewer stackabletech/developers --base main --head "${CHANGELOG_BRANCH}" --title "chore: Update changelog from release ${RELEASE_TAG}" --body "${PR_MSG}" + else + echo "Dry-run: not pushing..." + git push --dry-run "${REMOTE}" "${CHANGELOG_BRANCH}" + gh pr create --reviewer stackabletech/developers --dry-run --base main --head "${CHANGELOG_BRANCH}" --title "chore: Update changelog from release ${RELEASE_TAG}" --body "${PR_MSG}" + fi +) + main() { parse_inputs "$@" if [ -z "${RELEASE_TAG}" ]; then - >&2 echo "Usage: post-release.sh -t [-p] [-w products|operators|all]" + >&2 echo "Usage: post-release.sh -t [-p] [-w products|operators|cockpit|all]" exit 1 fi # Post-release is only for final releases, not release candidates. validate_tag --no-rc "$RELEASE_TAG" - validate_what "$WHAT" "products" "operators" "all" + validate_what "$WHAT" "products" "operators" "cockpit" "all" check_common_dependencies ensure_temp_folder @@ -192,6 +252,11 @@ main() { echo "Update the operator main changelog for release $RELEASE_TAG" for_each_operator update_operator ;; + cockpit) + check_cockpit + echo "Update $COCKPIT_REPO main changelog for release $RELEASE_TAG" + update_cockpit + ;; all) check_products echo "Update $DOCKER_IMAGES_REPO main changelog for release $RELEASE_TAG" @@ -199,6 +264,9 @@ main() { for_each_operator check_operator echo "Update the operator main changelog for release $RELEASE_TAG" for_each_operator update_operator + check_cockpit + echo "Update $COCKPIT_REPO main changelog for release $RELEASE_TAG" + update_cockpit ;; esac } diff --git a/release/tag-release-candidate.sh b/release/tag-release-candidate.sh index 9f84125..cde7963 100755 --- a/release/tag-release-candidate.sh +++ b/release/tag-release-candidate.sh @@ -56,14 +56,34 @@ tag_operator() ( push_branch ) +tag_cockpit() ( + cd "$COCKPIT_REPO" + assert_cwd_is_repo "$COCKPIT_REPO" + assert_clean_index "$COCKPIT_REPO" + + git switch "$RELEASE_BRANCH" + assert_on_branch "$RELEASE_BRANCH" + if $PUSH; then + git pull + else + git pull || echo "Dry-run: remote branch doesn't exist yet..." + fi + assert_on_branch "$RELEASE_BRANCH" + git tag -sm "release $RELEASE_TAG" "$RELEASE_TAG" + assert_remote_exists "$REMOTE" "$COCKPIT_REPO" + push_branch +) + tag_repos() { cd "$TEMP_RELEASE_FOLDER" case "$WHAT" in products) tag_products ;; operators) for_each_operator tag_operator ;; + cockpit) tag_cockpit ;; all) tag_products for_each_operator tag_operator + tag_cockpit ;; esac } @@ -100,14 +120,27 @@ check_operator() ( assert_tag_not_exists "$REMOTE" "$RELEASE_TAG" ) +check_cockpit() ( + ensure_clone "$COCKPIT_REPO" + cd "$COCKPIT_REPO" + assert_cwd_is_repo "$COCKPIT_REPO" + assert_clean_index "$COCKPIT_REPO" + + # The release branch should exist (created in a prior step) + assert_remote_branch_exists "$REMOTE" "$RELEASE_BRANCH" + assert_tag_not_exists "$REMOTE" "$RELEASE_TAG" +) + checks() { cd "$TEMP_RELEASE_FOLDER" case "$WHAT" in products) check_products ;; operators) for_each_operator check_operator ;; + cockpit) check_cockpit ;; all) check_products for_each_operator check_operator + check_cockpit ;; esac } @@ -172,12 +205,12 @@ main() { parse_inputs "$@" if [ -z "${RELEASE_TAG}" ]; then - >&2 echo "Usage: tag-release-candidate.sh -t [-p] [-c] [-w products|operators|all]" + >&2 echo "Usage: tag-release-candidate.sh -t [-p] [-c] [-w products|operators|cockpit|all]" exit 1 fi validate_tag "$RELEASE_TAG" - validate_what "$WHAT" "products" "operators" "all" + validate_what "$WHAT" "products" "operators" "cockpit" "all" ensure_temp_folder check_dependencies diff --git a/release/test_common.bats b/release/test_common.bats index a86bb58..63c0d45 100644 --- a/release/test_common.bats +++ b/release/test_common.bats @@ -103,6 +103,23 @@ teardown_verify_release_dir() { teardown_verify_release_dir } +@test "verify_release: passes with correct package.json version" { + setup_verify_release_dir + printf '{\n "name": "cockpit",\n "version": "26.3.0"\n}\n' > "$VERIFY_DIR/package.json" + run verify_release "$VERIFY_DIR" "26.3.0" "26.3" + [ "$status" -eq 0 ] + teardown_verify_release_dir +} + +@test "verify_release: fails when package.json version is wrong" { + setup_verify_release_dir + printf '{\n "name": "cockpit",\n "version": "0.0.1"\n}\n' > "$VERIFY_DIR/package.json" + run verify_release "$VERIFY_DIR" "26.3.0" "26.3" + [ "$status" -eq 1 ] + [[ "$output" == *"package.json version is '0.0.1'"* ]] + teardown_verify_release_dir +} + # --- update_changelog --- @test "update_changelog: inserts tag entry" { @@ -343,6 +360,7 @@ teardown_verify_release_dir() { [ "$PR_BRANCH" == "pr-26.3.0" ] [ "$TEMP_RELEASE_FOLDER" == "/tmp/stackable-release-26.3" ] [ -n "$DOCKER_IMAGES_REPO" ] + [ -n "$COCKPIT_REPO" ] } @test "derive_tag_vars: sets all variables from an RC tag" { @@ -363,6 +381,7 @@ teardown_verify_release_dir() { [ "$TEMP_RELEASE_FOLDER" == "/tmp/stackable-release-26.3" ] [ -n "$DOCKER_IMAGES_REPO" ] [ -n "$DEMOS_REPO" ] + [ -n "$COCKPIT_REPO" ] } # --- assert_cwd_is_repo (needs temp git repo) --- From 983d4bf5158f042d5d50ebb2b2cce11407c6c6c1 Mon Sep 17 00:00:00 2001 From: Johannes Fleck Date: Mon, 2 Nov 2026 11:41:57 +0100 Subject: [PATCH 2/3] fix: set the Antora version for the cockpit docs --- release/create-release-candidate-branch.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/release/create-release-candidate-branch.sh b/release/create-release-candidate-branch.sh index 87c7e09..c290a25 100755 --- a/release/create-release-candidate-branch.sh +++ b/release/create-release-candidate-branch.sh @@ -137,6 +137,12 @@ rc_branch_cockpit() ( fi git add package.json package-lock.json "$chart_yaml" + # The docs are a module of the 'home' component, like the operator docs. + # antora version should be major.minor, not patch level + yq -i ".version = \"${RELEASE_BASE}\"" docs/antora.yml + yq -i '.prerelease = false' docs/antora.yml + git add docs/antora.yml + # inserts a single line with tag and date update_changelog ./CHANGELOG.md "$RELEASE_TAG" git add CHANGELOG.md From 79d82658db306bd268f7ca265e144b5de820ceec Mon Sep 17 00:00:00 2001 From: Johannes Fleck Date: Mon, 2 Nov 2026 17:15:28 +0100 Subject: [PATCH 3/3] refactor(release): reuse operator functions for cockpit Replace the cockpit-specific copies of check/update/tag functions with the operator versions, extract a merge_repo helper in merge-release-candidate.sh, make messages repo-neutral and fix the cockpit README bullet. --- release/README.md | 2 +- release/create-release-candidate-branch.sh | 2 +- release/merge-release-candidate.sh | 86 +++++----------------- release/post-release.sh | 82 +++------------------ release/tag-release-candidate.sh | 39 ++-------- 5 files changed, 38 insertions(+), 173 deletions(-) diff --git a/release/README.md b/release/README.md index 6da78aa..d490f86 100644 --- a/release/README.md +++ b/release/README.md @@ -231,7 +231,7 @@ e.g. - update the `release-tag` in helm charts - rebuilds the helm charts - bumps the changelog - - for cockpit: sets the version in `package.json`, `package-lock.json` and the Helm `Chart.yaml` instead of the Rust/docs updates above + - for cockpit: sets the version in `package.json`, `package-lock.json` and the Helm `Chart.yaml` instead of updating `Cargo.toml` and rebuilding the Helm charts; `docs/antora.yml` and the changelog are updated like for the operators - optional: pushes the new branch (if requested with "-p") - optional: deletes the temporary folder (if requested with "-c") diff --git a/release/create-release-candidate-branch.sh b/release/create-release-candidate-branch.sh index c290a25..1256e7b 100755 --- a/release/create-release-candidate-branch.sh +++ b/release/create-release-candidate-branch.sh @@ -122,7 +122,7 @@ rc_branch_cockpit() ( # the JSON files, which is checked below by counting the changed lines. yq -i -p json -o json -I 2 ".version = \"${RELEASE_TAG}\"" package.json yq -i -p json -o json -I 2 ".version = \"${RELEASE_TAG}\" | .packages[\"\"].version = \"${RELEASE_TAG}\"" package-lock.json - # The chart directory is named after the project, which is being renamed + # Find the chart by file name rather than hard-coding the directory local chart_yaml chart_yaml=$(find deploy/helm -maxdepth 2 -name "Chart.yaml" -print -quit) yq -i ".version = \"${RELEASE_TAG}\" | .appVersion = \"${RELEASE_TAG}\"" "$chart_yaml" diff --git a/release/merge-release-candidate.sh b/release/merge-release-candidate.sh index 32a56a0..a7ff5cd 100755 --- a/release/merge-release-candidate.sh +++ b/release/merge-release-candidate.sh @@ -43,100 +43,54 @@ parse_inputs() { echo "Settings: ${PR_BRANCH}: Push: $PUSH:" } -merge_operator() { - local operator="$1" - echo "Operator: $operator" +# Merge the release candidate PR of a repository. Pass --ask-approval as the +# second argument to wait for someone to approve the PR before merging. +merge_repo() { + local repo="$1" + local ask_approval="${2:-}" + echo "Repository: $repo" if $PUSH; then - STATE=$(gh pr view "${PR_BRANCH}" -R stackabletech/"${operator}" --jq '.state' --json state) + STATE=$(gh pr view "${PR_BRANCH}" -R stackabletech/"${repo}" --jq '.state' --json state) else - echo "Dry-run: skipping PR existence check for ${operator}" + echo "Dry-run: skipping PR existence check for ${repo}" STATE="OPEN" fi if [[ "$STATE" == "OPEN" ]]; then - echo "Processing ${operator} in branch ${PR_BRANCH} with state ${STATE}" + echo "Processing ${repo} in branch ${PR_BRANCH} with state ${STATE}" if $PUSH; then echo "Reviewing..." # TODO (@NickLarsenNZ): Check if the review is merged, else loop the following # TODO (@NickLarsenNZ): Allow review if the PR author is not the current `gh` user, otherwise wait. - # gh pr review "${PR_BRANCH}" --approve -R stackabletech/"${operator}" + if [[ "$ask_approval" == "--ask-approval" ]]; then + read -p "Ask someone to approve the PR, then press Enter" + fi + # gh pr review "${PR_BRANCH}" --approve -R stackabletech/"${repo}" echo "Merging..." - gh pr merge "${PR_BRANCH}" --delete-branch --squash -R stackabletech/"${operator}" + gh pr merge "${PR_BRANCH}" --delete-branch --squash -R stackabletech/"${repo}" else echo "Dry-run: not reviewing/merging..." echo echo "Please checkout the release branch, and manually run git merge ${PR_BRANCH}" fi else - echo "Skipping ${operator}, PR already closed" + echo "Skipping ${repo}, PR already closed" fi } merge_operators() { read -p "Ask someone to approve all of the operator PRs, then press Enter" - for_each_operator merge_operator -} - -merge_products() { - echo "Products: $DOCKER_IMAGES_REPO" - if $PUSH; then - STATE=$(gh pr view "${PR_BRANCH}" -R stackabletech/"${DOCKER_IMAGES_REPO}" --jq '.state' --json state) - else - echo "Dry-run: skipping PR existence check for ${DOCKER_IMAGES_REPO}" - STATE="OPEN" - fi - if [[ "$STATE" == "OPEN" ]]; then - echo "Processing ${DOCKER_IMAGES_REPO} in branch ${PR_BRANCH} with state ${STATE}" - if $PUSH; then - echo "Reviewing..." - # TODO (@NickLarsenNZ): Check if the review is merged, else loop the following - # TODO (@NickLarsenNZ): Allow review if the PR author is not the current `gh` user, otherwise wait. - read -p "Ask someone to approve the PR, then press Enter" - # gh pr review "${PR_BRANCH}" --approve -R stackabletech/"${DOCKER_IMAGES_REPO}" - echo "Merging..." - gh pr merge "${PR_BRANCH}" --delete-branch --squash -R stackabletech/"${DOCKER_IMAGES_REPO}" - else - echo "Dry-run: not reviewing/merging..." - echo - echo "Please checkout the release branch, and manually run git merge ${PR_BRANCH}" - fi - else - echo "Skipping ${DOCKER_IMAGES_REPO}, PR already closed" - fi -} - -merge_cockpit() { - echo "Cockpit: $COCKPIT_REPO" - if $PUSH; then - STATE=$(gh pr view "${PR_BRANCH}" -R stackabletech/"${COCKPIT_REPO}" --jq '.state' --json state) - else - echo "Dry-run: skipping PR existence check for ${COCKPIT_REPO}" - STATE="OPEN" - fi - if [[ "$STATE" == "OPEN" ]]; then - echo "Processing ${COCKPIT_REPO} in branch ${PR_BRANCH} with state ${STATE}" - if $PUSH; then - read -p "Ask someone to approve the PR, then press Enter" - echo "Merging..." - gh pr merge "${PR_BRANCH}" --delete-branch --squash -R stackabletech/"${COCKPIT_REPO}" - else - echo "Dry-run: not reviewing/merging..." - echo - echo "Please checkout the release branch, and manually run git merge ${PR_BRANCH}" - fi - else - echo "Skipping ${COCKPIT_REPO}, PR already closed" - fi + for_each_operator merge_repo } merge() { case "$WHAT" in - products) merge_products ;; + products) merge_repo "$DOCKER_IMAGES_REPO" --ask-approval ;; operators) merge_operators ;; - cockpit) merge_cockpit ;; + cockpit) merge_repo "$COCKPIT_REPO" --ask-approval ;; all) - merge_products + merge_repo "$DOCKER_IMAGES_REPO" --ask-approval merge_operators - merge_cockpit + merge_repo "$COCKPIT_REPO" --ask-approval ;; esac } diff --git a/release/post-release.sh b/release/post-release.sh index 2f33b0e..2c57b49 100755 --- a/release/post-release.sh +++ b/release/post-release.sh @@ -36,11 +36,11 @@ parse_inputs() { echo "Settings: $RELEASE_BRANCH: Push: $PUSH" } -# Check that an operator repo has been cloned locally, and that the release -# branch and tag exists. +# Check that an operator (or cockpit) repo has been cloned locally, and that the +# release branch and tag exists. check_operator() ( local OPERATOR="$1" - echo "Operator: $OPERATOR" + echo "Repository: $OPERATOR" ensure_clone "$OPERATOR" cd "$OPERATOR" assert_cwd_is_repo "$OPERATOR" @@ -52,14 +52,14 @@ check_operator() ( assert_remote_branch_exists "$REMOTE" "$RELEASE_BRANCH" git fetch --tags if ! git tag | grep "^$RELEASE_TAG\$"; then - >&2 echo "Expected tag $RELEASE_TAG missing for operator $OPERATOR" + >&2 echo "Expected tag $RELEASE_TAG missing for $OPERATOR" exit 1 fi ) -# Update an operator's changelog on main, and check it does not differ from -# the changelog in the release branch. +# Update an operator's (or cockpit's) changelog on main, and check it does not +# differ from the changelog in the release branch. update_operator() ( local OPERATOR="$1" cd "$OPERATOR" @@ -82,7 +82,7 @@ update_operator() ( # are no conflicts. CHANGELOG_MODIFIED=$(git status --short) if [ "M CHANGELOG.md" != "$CHANGELOG_MODIFIED" ]; then - echo "Failed to update CHANGELOG.md in main for operator $OPERATOR" + echo "Failed to update CHANGELOG.md in main for $OPERATOR" exit 1 fi # Commit the updated CHANGELOG. @@ -164,66 +164,6 @@ update_products() ( fi ) -# Check that the cockpit repo has been cloned locally, and that the release -# branch and tag exists. -check_cockpit() ( - ensure_clone "$COCKPIT_REPO" - cd "$COCKPIT_REPO" - assert_cwd_is_repo "$COCKPIT_REPO" - assert_clean_index "$COCKPIT_REPO" - - # The release branch should exist (created in a prior step) - assert_remote_branch_exists "$REMOTE" "$RELEASE_BRANCH" - - git fetch --tags - # check tags: N.B. look for exact match - if ! git tag | grep "^$RELEASE_TAG\$"; then - >&2 echo "Expected tag $RELEASE_TAG missing for $COCKPIT_REPO" - exit 1 - fi -) - -# Update the cockpit changelog on main, and check it does not differ from -# the changelog in the release branch. -update_cockpit() ( - cd "$COCKPIT_REPO" - assert_cwd_is_repo "$COCKPIT_REPO" - assert_clean_index "$COCKPIT_REPO" - - git checkout main - assert_on_branch "main" - git pull - - # New branch that updates the CHANGELOG - CHANGELOG_BRANCH="chore/update-changelog-from-release-$RELEASE_TAG" - # Branch out from main - git switch "$CHANGELOG_BRANCH" 2>/dev/null || git switch -c "$CHANGELOG_BRANCH" - assert_on_branch "$CHANGELOG_BRANCH" - # Checkout CHANGELOG changes from the release tag - git checkout "$RELEASE_TAG" -- CHANGELOG.md - # Ensure only the CHANGELOG has been modified and there - # are no conflicts. - CHANGELOG_MODIFIED=$(git status --short) - if [ "M CHANGELOG.md" != "$CHANGELOG_MODIFIED" ]; then - echo "Failed to update CHANGELOG.md in main for $COCKPIT_REPO" - exit 1 - fi - # Commit the updated CHANGELOG. - git add CHANGELOG.md - git commit -sm "Update CHANGELOG.md from release $RELEASE_TAG" - assert_clean_index "$COCKPIT_REPO" - # Maybe push and create pull request - assert_remote_exists "$REMOTE" "$COCKPIT_REPO" - if "$PUSH"; then - git push -u "${REMOTE}" "${CHANGELOG_BRANCH}" - gh pr create --reviewer stackabletech/developers --base main --head "${CHANGELOG_BRANCH}" --title "chore: Update changelog from release ${RELEASE_TAG}" --body "${PR_MSG}" - else - echo "Dry-run: not pushing..." - git push --dry-run "${REMOTE}" "${CHANGELOG_BRANCH}" - gh pr create --reviewer stackabletech/developers --dry-run --base main --head "${CHANGELOG_BRANCH}" --title "chore: Update changelog from release ${RELEASE_TAG}" --body "${PR_MSG}" - fi -) - main() { parse_inputs "$@" @@ -253,9 +193,9 @@ main() { for_each_operator update_operator ;; cockpit) - check_cockpit + check_operator "$COCKPIT_REPO" echo "Update $COCKPIT_REPO main changelog for release $RELEASE_TAG" - update_cockpit + update_operator "$COCKPIT_REPO" ;; all) check_products @@ -264,9 +204,9 @@ main() { for_each_operator check_operator echo "Update the operator main changelog for release $RELEASE_TAG" for_each_operator update_operator - check_cockpit + check_operator "$COCKPIT_REPO" echo "Update $COCKPIT_REPO main changelog for release $RELEASE_TAG" - update_cockpit + update_operator "$COCKPIT_REPO" ;; esac } diff --git a/release/tag-release-candidate.sh b/release/tag-release-candidate.sh index cde7963..d5bf543 100755 --- a/release/tag-release-candidate.sh +++ b/release/tag-release-candidate.sh @@ -56,34 +56,16 @@ tag_operator() ( push_branch ) -tag_cockpit() ( - cd "$COCKPIT_REPO" - assert_cwd_is_repo "$COCKPIT_REPO" - assert_clean_index "$COCKPIT_REPO" - - git switch "$RELEASE_BRANCH" - assert_on_branch "$RELEASE_BRANCH" - if $PUSH; then - git pull - else - git pull || echo "Dry-run: remote branch doesn't exist yet..." - fi - assert_on_branch "$RELEASE_BRANCH" - git tag -sm "release $RELEASE_TAG" "$RELEASE_TAG" - assert_remote_exists "$REMOTE" "$COCKPIT_REPO" - push_branch -) - tag_repos() { cd "$TEMP_RELEASE_FOLDER" case "$WHAT" in products) tag_products ;; operators) for_each_operator tag_operator ;; - cockpit) tag_cockpit ;; + cockpit) tag_operator "$COCKPIT_REPO" ;; all) tag_products for_each_operator tag_operator - tag_cockpit + tag_operator "$COCKPIT_REPO" ;; esac } @@ -106,7 +88,7 @@ check_products() ( check_operator() ( local operator="$1" - echo "Operator: $operator" + echo "Repository: $operator" ensure_clone "$operator" cd "${operator}" assert_cwd_is_repo "$operator" @@ -120,27 +102,16 @@ check_operator() ( assert_tag_not_exists "$REMOTE" "$RELEASE_TAG" ) -check_cockpit() ( - ensure_clone "$COCKPIT_REPO" - cd "$COCKPIT_REPO" - assert_cwd_is_repo "$COCKPIT_REPO" - assert_clean_index "$COCKPIT_REPO" - - # The release branch should exist (created in a prior step) - assert_remote_branch_exists "$REMOTE" "$RELEASE_BRANCH" - assert_tag_not_exists "$REMOTE" "$RELEASE_TAG" -) - checks() { cd "$TEMP_RELEASE_FOLDER" case "$WHAT" in products) check_products ;; operators) for_each_operator check_operator ;; - cockpit) check_cockpit ;; + cockpit) check_operator "$COCKPIT_REPO" ;; all) check_products for_each_operator check_operator - check_cockpit + check_operator "$COCKPIT_REPO" ;; esac }