From acf0d8c0a8dee49e3c698f370a9be177356be058 Mon Sep 17 00:00:00 2001 From: Aliza Held Date: Thu, 12 Feb 2026 15:30:55 +0100 Subject: [PATCH 1/2] IONOS(ci): Add workflow to promote artifacts upon QA-approval Signed-off-by: Aliza Held --- .github/workflows/promote-artifact.yml | 89 ++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/promote-artifact.yml diff --git a/.github/workflows/promote-artifact.yml b/.github/workflows/promote-artifact.yml new file mode 100644 index 0000000000000..9e20f5ba39075 --- /dev/null +++ b/.github/workflows/promote-artifact.yml @@ -0,0 +1,89 @@ +name: Promote QA-approved artifacts to stable branch + +# - Takes a commit SHA as input +# - Fast-forward merges it to ionos-stable (no new commits) +# - Promotes the exact artifact from Artifactory (no rebuild) + +on: + workflow_dispatch: + +env: + REGISTRY: ghcr.io + SHA: ${{ github.sha }} + ARTIFACTORY_REPOSITORY_SNAPSHOT: ionos-productivity-ncwserver-snapshot + CACHE_VERSION: v1.0 + +permissions: + contents: write + +jobs: + promote-git: + # Fast-forward merge SHA from ionos-dev into ionos-stable + # (This ensures commit-hash is identical) + runs-on: ubuntu-latest + steps: + - name: Checkout server + id: checkout_server + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Verify SHA is in ionos-dev + id: verify_sha + run: | + git checkout ionos-stable + git fetch origin ionos-stable ionos-dev + #verify SHA is on ionos-dev + if ! git merge-base --is-ancestor "$SHA" origin/ionos-dev; then + echo "Error: SHA does not exist on ionos-dev: $SHA" + exit 1 + fi + + - name: Fast-forward merge + id: ff_merge + run: | + # Merge will fail if not possible + if ! git merge --ff-only "$SHA"; then + echo "Fast-forward merge not possible" + exit 1 + else + git push origin ionos-stable + fi + + promote-artifact: + # Copy specified artifact to the release repo -> No rebuild + # (ionos-productivity-ncwserver-release) + needs: promote-git + runs-on: ubuntu-latest + steps: + - name: Setup JFrog CLI + id: setup_jf + uses: jfrog/setup-jfrog-cli@7c95feb32008765e1b4e626b078dfd897c4340ad # v4.4.1 + env: + JF_URL: ${{ secrets.JF_ARTIFACTORY_URL }} + JF_USER: ${{ secrets.JF_ARTIFACTORY_USER }} + JF_ACCESS_TOKEN: ${{ secrets.JF_ACCESS_TOKEN }} + + - name: Ping the JF server + run: | + # Ping the server + jf rt ping + + - name: Find artifacts matching the SHA + id: find_artifact + run: | + if ! jf rt search "ionos-productivity-ncwserver-snapshot/dev/*/$SHA/*.tar.gz"; then + echo "No artifact with SHA $SHA found." + exit 1 + else + echo "Artifact found for SHA $SHA" + fi + + - name: Copy artifact to target + id: copy_artifact + run: | + jf rt copy \ + "ionos-productivity-ncwserver-snapshot/dev/*/$SHA/*" \ + "ionos-productivity-ncwserver-release/$SHA/" \ + --flat=false + From a120461ee6c88d02d3dde377f6a9900892754e57 Mon Sep 17 00:00:00 2001 From: Aliza Held Date: Fri, 27 Feb 2026 15:17:11 +0100 Subject: [PATCH 2/2] IONOS(ci): Update to integrate feedback Signed-off-by: Aliza Held --- .github/workflows/promote-artifact.yml | 63 ++++++++++++++++++++------ 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/.github/workflows/promote-artifact.yml b/.github/workflows/promote-artifact.yml index 9e20f5ba39075..4db32d08877a7 100644 --- a/.github/workflows/promote-artifact.yml +++ b/.github/workflows/promote-artifact.yml @@ -6,11 +6,16 @@ name: Promote QA-approved artifacts to stable branch on: workflow_dispatch: - + inputs: + sha: + description: 'Commit SHA to promote from ionos-dev to ionos-stable and copy artifacts for' + required: true + type: string env: REGISTRY: ghcr.io - SHA: ${{ github.sha }} + SHA: ${{ inputs.sha }} ARTIFACTORY_REPOSITORY_SNAPSHOT: ionos-productivity-ncwserver-snapshot + ARTIFACTORY_REPOSITORY_RELEASE: ionos-productivity-ncwserver-release CACHE_VERSION: v1.0 permissions: @@ -31,9 +36,14 @@ jobs: - name: Verify SHA is in ionos-dev id: verify_sha run: | - git checkout ionos-stable - git fetch origin ionos-stable ionos-dev - #verify SHA is on ionos-dev + set -euo pipefail + git fetch origin ionos-dev ionos-stable + git checkout -B ionos-stable origin/ionos-stable + if ! git rev-parse --verify "$SHA^{commit}" >/dev/null 2>&1; then + echo "Error: SHA is not a valid commit: $SHA" + exit 1 + fi + # verify SHA is on ionos-dev if ! git merge-base --is-ancestor "$SHA" origin/ionos-dev; then echo "Error: SHA does not exist on ionos-dev: $SHA" exit 1 @@ -42,12 +52,13 @@ jobs: - name: Fast-forward merge id: ff_merge run: | + set -euo pipefail # Merge will fail if not possible if ! git merge --ff-only "$SHA"; then echo "Fast-forward merge not possible" exit 1 else - git push origin ionos-stable + git push origin HEAD:ionos-stable fi promote-artifact: @@ -72,18 +83,44 @@ jobs: - name: Find artifacts matching the SHA id: find_artifact run: | - if ! jf rt search "ionos-productivity-ncwserver-snapshot/dev/*/$SHA/*.tar.gz"; then + # Expected Artifactory layout: + # ionos-productivity-ncwserver-snapshot/ + # dev//$SHA/ + # + # We search for a single .tar.gz artifact for the given SHA and + # derive its containing directory. This avoids using wildcards + # for the branch component when copying to the release repo. + set -e + SEARCH_RESULT=$(jf rt search --format=json --limit=2 "${{ env.ARTIFACTORY_REPOSITORY_SNAPSHOT }}/dev/*/$SHA/*.tar.gz") + MATCH_COUNT=$(echo "$SEARCH_RESULT" | jq '.results | length') + + if [ "$MATCH_COUNT" -eq 0 ]; then echo "No artifact with SHA $SHA found." exit 1 - else - echo "Artifact found for SHA $SHA" fi - + + if [ "$MATCH_COUNT" -gt 1 ]; then + echo "Multiple artifacts found for SHA $SHA; expected exactly one." + echo "$SEARCH_RESULT" + exit 1 + fi + + ARTIFACT_REPO=$(echo "$SEARCH_RESULT" | jq -r '.results[0].repo') + ARTIFACT_PATH=$(echo "$SEARCH_RESULT" | jq -r '.results[0].path') + # Derive the directory that contains all artifacts for this SHA + ARTIFACT_DIR_PATH=$(dirname "$ARTIFACT_PATH") + ARTIFACT_DIR="$ARTIFACT_REPO/$ARTIFACT_DIR_PATH" + + echo "Using artifact directory: $ARTIFACT_DIR" + # Expose the directory as a step output for the copy step + echo "artifact_dir=$ARTIFACT_DIR" >> "$GITHUB_OUTPUT" - name: Copy artifact to target id: copy_artifact run: | jf rt copy \ - "ionos-productivity-ncwserver-snapshot/dev/*/$SHA/*" \ - "ionos-productivity-ncwserver-release/$SHA/" \ - --flat=false + "${{ steps.find_artifact.outputs.artifact_dir }}/*" \ + "${{ env.ARTIFACTORY_REPOSITORY_RELEASE }}/stable/${SHA}/" + - name: Confirm promoted artifacts + run: | + jf rt search --format=table "${{ env.ARTIFACTORY_REPOSITORY_RELEASE }}/stable/${SHA}/*"