chore: add admin mail management to delegated settings #128
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-FileCopyrightText: 2024 IONOS Productivity | |
| # SPDX-License-Identifier: MIT | |
| # | |
| # This workflow automates submodule updates in ncw-server when PRs are merged to main. | |
| # | |
| # How it works: | |
| # 1. Triggers when a PR with milestone "ncw-<nnn>" is merged to main in the submodule repo | |
| # 2. Creates a pre-release in the submodule repository | |
| # 3. Checks if branch "rc/ncw-<nnn>" exists in ncw-server | |
| # 4. If rc branch exists: | |
| # - Creates update branch from "rc/ncw-<nnn>" | |
| # - Creates PR to merge into "rc/ncw-<nnn>" | |
| # 5. If rc branch doesn't exist: | |
| # - Creates update branch from BASE_BRANCH | |
| # - Creates PR to merge into BASE_BRANCH | |
| # 6. PR includes milestone attachment for tracking | |
| # | |
| # To adapt for other submodules: | |
| # 1. Copy this workflow file to the submodule repository's .github/workflows/ | |
| # 2. Update the 'if' condition in create-submodule-pr job | |
| # 3. Update the env variables in create-submodule-pr job: | |
| # - SUBMODULE_NAME: Directory name in ncw-server (e.g., "IONOS") | |
| # - SUBMODULE_REPO: Full repository name (e.g., "IONOS-Productivity/ncw-config") | |
| # - TARGET_REPO: Where the submodule lives (typically "IONOS-Productivity/ncw-server") | |
| # - BASE_BRANCH: Default target branch (typically "ionos-dev") | |
| # - COMMIT_PREFIX: Commit message prefix (e.g., "IONOS(config)") | |
| # - MILESTONE_PREFIX: Milestone prefix pattern (e.g., "ncw" for milestones like "ncw-3") | |
| # 4. Ensure NCW_SERVER_PAT secret is configured in the submodule repository | |
| # | |
| name: Create pre-release and update ncw-server submodule | |
| on: | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| create-prerelease: | |
| runs-on: [ubuntu-latest] | |
| outputs: | |
| sha: ${{ steps.commit-info.outputs.sha }} | |
| short_sha: ${{ steps.commit-info.outputs.short_sha }} | |
| tag_name: ${{ steps.commit-info.outputs.short_sha }} | |
| release_url: ${{ steps.create-release.outputs.html_url }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get commit information | |
| id: commit-info | |
| run: | | |
| echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
| echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | |
| - name: Check GitHub CLI installation | |
| id: check-gh | |
| run: | | |
| if command -v gh &> /dev/null; then | |
| echo "installed=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "installed=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Install GitHub CLI | |
| if: steps.check-gh.outputs.installed != 'true' | |
| run: | | |
| echo "Installing GitHub CLI..." | |
| curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg | |
| sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg | |
| echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null | |
| sudo apt update | |
| sudo apt install gh -y | |
| - name: Create pre-release | |
| id: create-release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Check if the release already exists | |
| if gh release view "${{ steps.commit-info.outputs.short_sha }}" --repo "${{ github.repository }}" > /dev/null 2>&1; then | |
| # Release exists, get its URL | |
| RELEASE_URL=$(gh release view "${{ steps.commit-info.outputs.short_sha }}" --repo "${{ github.repository }}" --json url -q ".url") | |
| else | |
| # Release does not exist, create it | |
| RELEASE_URL=$(gh release create "${{ steps.commit-info.outputs.short_sha }}" \ | |
| --title "Pre-release ${{ steps.commit-info.outputs.short_sha }}" \ | |
| --generate-notes \ | |
| --prerelease \ | |
| --repo "${{ github.repository }}") | |
| fi | |
| echo "html_url=$RELEASE_URL" >> $GITHUB_OUTPUT | |
| create-submodule-pr: | |
| needs: create-prerelease | |
| runs-on: [ubuntu-latest] | |
| # Update this condition to match SUBMODULE_REPO when adapting for other submodules | |
| if: github.repository == 'IONOS-Productivity/ncw-config' | |
| env: | |
| # Configuration for submodule updates - customize these values for different submodules | |
| SUBMODULE_NAME: IONOS # Submodule directory name in ncw-server | |
| SUBMODULE_REPO: IONOS-Productivity/ncw-config # Source repository (must match 'if' condition above) | |
| TARGET_REPO: IONOS-Productivity/ncw-server # Target repository containing the submodule | |
| BASE_BRANCH: ionos-dev # Default base branch for PRs | |
| COMMIT_PREFIX: "IONOS(config)" # Prefix for commit messages and PR titles | |
| MILESTONE_PREFIX: ncw # Milestone prefix (e.g., "ncw" for "ncw-3") | |
| steps: | |
| - name: Get milestone from merged PR | |
| id: get-milestone | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Use GitHub API to get PRs associated with this commit | |
| # This is more reliable than searching, as it uses commit-to-PR association | |
| PR_DATA=$(gh api "repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" \ | |
| --jq '[.[] | select(.merged_at != null)] | .[0] | {number: .number, milestone: .milestone.title}') | |
| PR_NUMBER=$(echo "$PR_DATA" | jq -r '.number // empty') | |
| MILESTONE=$(echo "$PR_DATA" | jq -r '.milestone // empty') | |
| if [ -n "$PR_NUMBER" ]; then | |
| echo "milestone=$MILESTONE" >> $GITHUB_OUTPUT | |
| if [ -n "$MILESTONE" ]; then | |
| echo "::notice::Found PR #$PR_NUMBER with milestone: $MILESTONE" | |
| else | |
| echo "::notice::Found PR #$PR_NUMBER but no milestone set" | |
| fi | |
| else | |
| echo "milestone=" >> $GITHUB_OUTPUT | |
| echo "::notice::No merged PR found for commit ${{ github.sha }}" | |
| fi | |
| - name: Checkout ncw-server repository | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: ${{ env.TARGET_REPO }} | |
| token: ${{ secrets.NCW_SERVER_PAT }} | |
| ref: ${{ env.BASE_BRANCH }} | |
| fetch-depth: 0 | |
| sparse-checkout: | | |
| ${{ env.SUBMODULE_NAME }} | |
| .gitmodules | |
| - name: Check GitHub CLI installation | |
| id: check-gh | |
| run: | | |
| if command -v gh &> /dev/null; then | |
| echo "installed=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "installed=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Install GitHub CLI | |
| if: steps.check-gh.outputs.installed != 'true' | |
| run: | | |
| echo "Installing GitHub CLI..." | |
| curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg | |
| sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg | |
| echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null | |
| sudo apt update | |
| sudo apt install gh -y | |
| - name: Update submodule | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| # Configure git to use HTTPS instead of SSH for GitHub | |
| git config --global url."https://github.com/".insteadOf "git@github.com:" | |
| git config --global url."https://".insteadOf "ssh://" | |
| # Determine base branch from milestone | |
| SELECTED_BASE_BRANCH="${{ env.BASE_BRANCH }}" | |
| MILESTONE="${{ steps.get-milestone.outputs.milestone }}" | |
| # Fetch all branches to check for rc branches | |
| git fetch origin | |
| if [ -n "$MILESTONE" ]; then | |
| # Check if milestone matches pattern <prefix>-<nnn> (e.g., ncw-3) | |
| MILESTONE_PATTERN="^${{ env.MILESTONE_PREFIX }}-[0-9]+$" | |
| if [[ "$MILESTONE" =~ $MILESTONE_PATTERN ]]; then | |
| RC_BRANCH="rc/$MILESTONE" | |
| echo "::notice::Checking for release candidate branch: $RC_BRANCH" | |
| # Check if rc branch exists | |
| if git ls-remote --heads origin "$RC_BRANCH" | grep -q "$RC_BRANCH"; then | |
| SELECTED_BASE_BRANCH="$RC_BRANCH" | |
| echo "::notice::Using base branch: $SELECTED_BASE_BRANCH" | |
| else | |
| echo "::notice::Branch $RC_BRANCH not found, using ${{ env.BASE_BRANCH }}" | |
| fi | |
| else | |
| echo "::notice::Milestone '$MILESTONE' doesn't match ${{ env.MILESTONE_PREFIX }}-<nnn> pattern, using ${{ env.BASE_BRANCH }}" | |
| fi | |
| else | |
| echo "::notice::No milestone found, using ${{ env.BASE_BRANCH }}" | |
| fi | |
| # Create a new branch for the update directly from the selected base branch | |
| # Replace slashes with dashes for cleaner branch names | |
| SUBMODULE_NAME_CLEAN=$(echo "${{ env.SUBMODULE_NAME }}" | tr '/' '-') | |
| BRANCH_NAME="update-${SUBMODULE_NAME_CLEAN}-submodule-${{ needs.create-prerelease.outputs.short_sha }}" | |
| git checkout -B "$BRANCH_NAME" "origin/$SELECTED_BASE_BRANCH" | |
| # Export the selected base branch for use in PR creation | |
| echo "SELECTED_BASE_BRANCH=$SELECTED_BASE_BRANCH" >> $GITHUB_ENV | |
| # Initialize only the target submodule | |
| git submodule update --init "${{ env.SUBMODULE_NAME }}" | |
| # Update the submodule to the new commit | |
| cd "${{ env.SUBMODULE_NAME }}" | |
| git fetch origin main | |
| git checkout ${{ needs.create-prerelease.outputs.sha }} | |
| # Get the commit message for description | |
| COMMIT_MSG=$(git log -1 --pretty=format:'%s') | |
| cd .. | |
| # Commit the submodule update with release link | |
| RELEASE_URL="https://github.com/${{ env.SUBMODULE_REPO }}/releases/tag/${{ needs.create-prerelease.outputs.short_sha }}" | |
| git add "${{ env.SUBMODULE_NAME }}" | |
| git commit -m "${{ env.COMMIT_PREFIX }}: update submodule ${{ needs.create-prerelease.outputs.short_sha }} ($COMMIT_MSG)" \ | |
| -m "" \ | |
| -m "$RELEASE_URL" \ | |
| -m "" \ | |
| -m "Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>" | |
| # Push the branch | |
| git push origin "$BRANCH_NAME" | |
| - name: Create Pull Request | |
| env: | |
| GH_TOKEN: ${{ secrets.NCW_SERVER_PAT }} | |
| run: | | |
| # Replace slashes with dashes for cleaner branch names | |
| SUBMODULE_NAME_CLEAN=$(echo "${{ env.SUBMODULE_NAME }}" | tr '/' '-') | |
| BRANCH_NAME="update-${SUBMODULE_NAME_CLEAN}-submodule-${{ needs.create-prerelease.outputs.short_sha }}" | |
| MILESTONE="${{ steps.get-milestone.outputs.milestone }}" | |
| # Get the commit message from submodule | |
| cd "${{ env.SUBMODULE_NAME }}" | |
| COMMIT_MSG=$(git log -1 --pretty=format:'%s') | |
| cd .. | |
| RELEASE_URL="https://github.com/${{ env.SUBMODULE_REPO }}/releases/tag/${{ needs.create-prerelease.outputs.short_sha }}" | |
| # Build PR body with milestone info if available | |
| PR_BODY="${{ env.COMMIT_PREFIX }}: update submodule ${{ needs.create-prerelease.outputs.short_sha }} ($COMMIT_MSG) | |
| $RELEASE_URL" | |
| if [ -n "$MILESTONE" ]; then | |
| PR_BODY="$PR_BODY | |
| Milestone: $MILESTONE" | |
| fi | |
| PR_BODY="$PR_BODY | |
| --- | |
| Auto-generated PR from ${{ env.SUBMODULE_NAME }} repository merge to main branch." | |
| # Check if a PR already exists for this branch | |
| EXISTING_PR_URL=$(gh pr list \ | |
| --repo "${{ env.TARGET_REPO }}" \ | |
| --head "$BRANCH_NAME" \ | |
| --state open \ | |
| --json url \ | |
| --jq '.[0].url') | |
| if [ -n "$EXISTING_PR_URL" ]; then | |
| PR_URL="$EXISTING_PR_URL" | |
| echo "::notice::PR already exists: $PR_URL" | |
| else | |
| # Create PR with milestone if available | |
| # Use the same base branch that was used to create the update branch | |
| if [ -z "$SELECTED_BASE_BRANCH" ]; then | |
| echo "::error::SELECTED_BASE_BRANCH is not set. Expected previous step to define it." | |
| exit 1 | |
| fi | |
| TARGET_BRANCH="$SELECTED_BASE_BRANCH" | |
| if [ -n "$MILESTONE" ]; then | |
| PR_URL=$(gh pr create \ | |
| --repo "${{ env.TARGET_REPO }}" \ | |
| --title "${{ env.COMMIT_PREFIX }}: update submodule ${{ needs.create-prerelease.outputs.short_sha }} ($COMMIT_MSG)" \ | |
| --body "$PR_BODY" \ | |
| --base "$TARGET_BRANCH" \ | |
| --head "$BRANCH_NAME" \ | |
| --milestone "$MILESTONE") | |
| else | |
| PR_URL=$(gh pr create \ | |
| --repo "${{ env.TARGET_REPO }}" \ | |
| --title "${{ env.COMMIT_PREFIX }}: update submodule ${{ needs.create-prerelease.outputs.short_sha }} ($COMMIT_MSG)" \ | |
| --body "$PR_BODY" \ | |
| --base "$TARGET_BRANCH" \ | |
| --head "$BRANCH_NAME") | |
| fi | |
| echo "::notice::Created PR: $PR_URL" | |
| fi | |
| log-details: | |
| needs: [create-prerelease, create-submodule-pr] | |
| runs-on: [ubuntu-latest] | |
| if: always() | |
| steps: | |
| - name: Log workflow details | |
| run: | | |
| echo "::notice::✅ Created pre-release with tag ${{ needs.create-prerelease.outputs.tag_name }}" | |
| echo "::notice::🔗 Release URL: ${{ needs.create-prerelease.outputs.release_url }}" | |
| if [ "${{ needs.create-submodule-pr.result }}" == "success" ]; then | |
| echo "::notice::📦 Submodule update PR created for ncw-server" | |
| fi | |
| echo "::notice::💾 Commit: ${{ needs.create-prerelease.outputs.sha }}" |