Skip to content

Commit a157024

Browse files
committed
Merge branch 'development' into pr/WimJongeneel/10247
2 parents 160f502 + 4e016cb commit a157024

File tree

26 files changed

+382
-86
lines changed

26 files changed

+382
-86
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
name: Branch Deletion Phase One (PR Creation)
2+
permissions:
3+
contents: write
4+
pull-requests: write
5+
on:
6+
schedule:
7+
- cron: '00 22 1 * *' # 10PM on 1st of every month
8+
workflow_dispatch:
9+
inputs:
10+
min_age_days:
11+
description: "Minimum age in days since merge"
12+
required: true
13+
default: 27
14+
type: number
15+
jobs:
16+
identify-branches:
17+
if: github.repository_owner == 'mendix'
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
token: ${{ secrets.GITHUB_TOKEN }}
25+
persist-credentials: true
26+
27+
- name: Fetch all branches
28+
run: |
29+
echo "Fetching all branches from remote..."
30+
git fetch origin '+refs/heads/*:refs/remotes/origin/*' --prune
31+
echo "Fetched branches:"
32+
git branch -r
33+
34+
- name: Process branches
35+
id: branch-data
36+
run: |
37+
set -e
38+
echo "Finding all branches for processing..."
39+
ALL_BRANCHES=$(git branch -r | grep -v "origin/HEAD" | sed 's/origin\///')
40+
41+
echo "All branches found:"
42+
printf "%s\n" "${ALL_BRANCHES[@]}"
43+
44+
MIN_AGE_DAYS=${{ github.event.inputs.min_age_days || 27 }}
45+
46+
# Arrays to hold branches
47+
PROTECTED_BRANCHES=()
48+
MERGED_BRANCHES_TO_PROCESS=()
49+
BRANCHES_TO_DELETE=()
50+
BRANCHES_TOO_RECENT=()
51+
52+
CURRENT_DATE=$(date +%Y%m%d)
53+
echo "CURRENT_DATE=$CURRENT_DATE" >> $GITHUB_ENV
54+
55+
# Check branches
56+
for BRANCH in $ALL_BRANCHES; do
57+
branch_lower=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]')
58+
# Identify protected branches
59+
if [[ $branch_lower =~ (backup|development|main|master|production) ]]; then
60+
if git branch -r --merged origin/development | grep -q "origin/$BRANCH"; then
61+
PROTECTED_BRANCHES+=("$BRANCH (protected name, merged)")
62+
else
63+
PROTECTED_BRANCHES+=("$BRANCH (protected name, not merged)")
64+
fi
65+
else
66+
# Process non-protected merged branches
67+
if git branch -r --merged origin/development | grep -q "origin/$BRANCH"; then
68+
MERGED_BRANCHES_TO_PROCESS+=("$BRANCH")
69+
else
70+
UNMERGED_BRANCHES+=("$BRANCH (not merged)")
71+
fi
72+
fi
73+
done
74+
75+
# Process potential deletion
76+
for BRANCH in "${MERGED_BRANCHES_TO_PROCESS[@]}"; do
77+
MERGE_HASH=$(git log --grep="Merge branch.*$BRANCH" origin/development -n 1 --pretty=format:"%H" ||
78+
git log --grep="Merge pull request.*$BRANCH" origin/development -n 1 --pretty=format:"%H")
79+
[ -z "$MERGE_HASH" ] && MERGE_HASH=$(git log -n 1 origin/$BRANCH --pretty=format:"%H")
80+
81+
MERGE_DATE=$(git show -s --format=%ct $MERGE_HASH)
82+
DAYS_AGO=$(( ($(date +%s) - MERGE_DATE) / 86400 ))
83+
84+
if [[ $DAYS_AGO -ge $MIN_AGE_DAYS ]]; then
85+
BRANCHES_TO_DELETE+=("$BRANCH ($DAYS_AGO days)")
86+
else
87+
BRANCHES_TOO_RECENT+=("$BRANCH ($DAYS_AGO days)")
88+
fi
89+
done
90+
91+
# Display non-deleted branches for logging
92+
ALL_NON_DELETED_BRANCHES=("${PROTECTED_BRANCHES[@]}" "${BRANCHES_TOO_RECENT[@]}" "${UNMERGED_BRANCHES[@]}")
93+
IFS=$'\n' ALL_NON_DELETED_BRANCHES=($(sort <<<"${ALL_NON_DELETED_BRANCHES[*]}"))
94+
unset IFS
95+
96+
if [ ${#BRANCHES_TO_DELETE[@]} -eq 0 ]; then
97+
echo "No branches found for deletion."
98+
echo "NO_BRANCHES=true" >> $GITHUB_ENV
99+
exit 0
100+
else
101+
echo "NO_BRANCHES=false" >> $GITHUB_ENV
102+
fi
103+
104+
# Create report
105+
echo "# Branch Cleanup Report - $(date +%Y-%m-%d)" > branch-report.branchreport
106+
echo "## Branches for deletion (merged >=${MIN_AGE_DAYS} days ago):" >> branch-report.branchreport
107+
echo '```' >> branch-report.branchreport
108+
printf "%s\n" "${BRANCHES_TO_DELETE[@]}" >> branch-report.branchreport
109+
echo '```' >> branch-report.branchreport
110+
echo "## Branches not eligible for deletion:" >> branch-report.branchreport
111+
echo '```' >> branch-report.branchreport
112+
printf "%s\n" "${ALL_NON_DELETED_BRANCHES[@]}" >> branch-report.branchreport
113+
echo '```' >> branch-report.branchreport
114+
115+
echo "BRANCHES_TO_DELETE<<EOF" >> $GITHUB_ENV
116+
printf "%s\n" "${BRANCHES_TO_DELETE[@]}" >> $GITHUB_ENV
117+
echo "EOF" >> $GITHUB_ENV
118+
echo "ALL_NON_DELETED_BRANCHES<<EOF" >> $GITHUB_ENV
119+
printf "%s\n" "${ALL_NON_DELETED_BRANCHES[@]}" >> $GITHUB_ENV
120+
echo "EOF" >> $GITHUB_ENV
121+
122+
- name: Create Deletion PR
123+
if: env.NO_BRANCHES != 'true'
124+
uses: peter-evans/create-pull-request@v6
125+
with:
126+
commit-message: "Branch cleanup proposal"
127+
title: "[AUTO] Branch Deletion Candidates - ${{ env.CURRENT_DATE }}"
128+
body: |
129+
## Branches for deletion (merged to development)
130+
```
131+
${{ env.BRANCHES_TO_DELETE }}
132+
```
133+
134+
## Branches not eligible for deletion
135+
```
136+
${{ env.ALL_NON_DELETED_BRANCHES }}
137+
```
138+
## ⚠️ Warning
139+
Merging this PR will:
140+
1. Delete the branches listed in the "Branches for deletion" section.
141+
2. Remove the temporary branch-report.branchreport file.
142+
branch: branch-cleanup-${{ env.CURRENT_DATE }}
143+
assignees: MarkvanMents,OlufunkeMoronfolu
144+
reviewers: MarkvanMents,OlufunkeMoronfolu
145+
labels: Internal WIP
146+
add-paths: |
147+
branch-report.branchreport
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Branch Deletion Phase Two (PR Processing)
2+
on:
3+
pull_request:
4+
types:
5+
- closed
6+
branches:
7+
- 'development'
8+
paths:
9+
- '**.branchreport'
10+
permissions:
11+
contents: write
12+
jobs:
13+
delete-branches-and-cleanup:
14+
if: |
15+
github.event.pull_request.merged == true &&
16+
startsWith(github.event.pull_request.title, '[AUTO] Branch Deletion Candidates')
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0
23+
token: ${{ secrets.GITHUB_TOKEN }}
24+
ref: ${{ github.event.repository.default_branch }}
25+
- name: Delete branch report file
26+
run: |
27+
# Check if file exists and delete it
28+
if [ -f "branch-report.branchreport" ]; then
29+
# Configure Git with your username
30+
git config --global user.name "github-actions[bot]"
31+
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
32+
33+
git rm branch-report.branchreport
34+
git commit -m "Remove temporary branch report file"
35+
git push
36+
echo "Removed branch-report.branchreport file"
37+
else
38+
echo "branch-report.branchreport file not found"
39+
fi
40+
- name: Extract branches and delete
41+
env:
42+
PR_BODY: ${{ github.event.pull_request.body }}
43+
run: |
44+
echo "PR Body Content:"
45+
echo "$PR_BODY"
46+
echo "-----------------------------------"
47+
48+
echo "Extracting branch names for deletion..."
49+
50+
# Extract lines between the markers using awk
51+
DELETION_LIST=$(echo "$PR_BODY" | awk '
52+
BEGIN { print_lines = 0; }
53+
/Branches for deletion/ { print_lines = 1; next; }
54+
/Branches not eligible for deletion/ { print_lines = 0; }
55+
print_lines == 1 && !/^```/ && NF > 0 {
56+
print $1;
57+
}
58+
')
59+
60+
echo "Branches identified for deletion:"
61+
echo "$DELETION_LIST"
62+
echo "-----------------------------------"
63+
64+
if [ -z "$DELETION_LIST" ]; then
65+
echo "No branches found for deletion"
66+
exit 0
67+
fi
68+
# Configure Git with your username
69+
git config --global user.name "github-actions[bot]"
70+
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
71+
72+
# Process each branch
73+
echo "$DELETION_LIST" | while read -r BRANCH; do
74+
# Skip empty lines
75+
[ -z "$BRANCH" ] && continue
76+
77+
echo "Processing branch: '$BRANCH'"
78+
79+
# Final protection check
80+
branch_lower=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]')
81+
if [[ $branch_lower =~ (backup|development|main|master|production) ]]; then
82+
echo "Skipping protected branch: $BRANCH"
83+
continue
84+
fi
85+
echo "Attempting to delete branch: $BRANCH"
86+
# Check if branch exists before trying to delete
87+
if git ls-remote --heads origin "$BRANCH" | grep -q "$BRANCH"; then
88+
echo "Branch exists, proceeding with deletion"
89+
git push origin --delete "$BRANCH" || {
90+
echo "Failed to delete branch: $BRANCH"
91+
echo "Error code: $?"
92+
}
93+
else
94+
echo "Branch $BRANCH does not exist or is not accessible"
95+
fi
96+
done

content/en/docs/deployment/mendix-cloud-deploy/behavior-of-app.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,11 @@ Apps running in Mendix Cloud are subject to certain limitations. These behaviors
5858
Therefore, do not assume that an established WebSocket connection will remain open indefinitely. To ensure connection stability and prevent unexpected disconnections:
5959
* Enable periodic keepalive checks (for example, every 25–30 seconds). This ensures the connection remains active and prevents Network Address Translators (NATs) and firewalls from dropping long-idle tunnels.
6060
* Implement robust reconnection logic to gracefully handle connectivity loss and automatically reestablish dropped connections.
61+
62+
## Move to Kubernetes
63+
64+
* Only [supported Mendix versions](https://docs.mendix.com/releasenotes/studio-pro/lts-mts/) are able to move to Kubernetes.
65+
* The platform configures `CF_INSTANCE_INDEX=0` for 1 of the instances to define a leader instance and to make [Community Commons](/appstore/modules/community-commons-function-library/) function `GetCFInstanceIndex` partially backwards compatible. The leader instance will return `0` while all follower instances will return `-1`. We advise stopping the use of the `GetCFInstanceIndex` function as it is specific to Cloud Foundry.
66+
* If your model is using the [SAML module](https://marketplace.mendix.com/link/component/1174), these versions are compatible with Kubernetes:
67+
* Mendix 9 – Version 3.6.19 and higher.
68+
* Mendix 10 – Version 4.1.0 and higher.

content/en/docs/deployment/mendix-cloud-deploy/environments-details.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ In the **Application Status** section of the **General** tab, you can find the f
9292
* **Project ID** – the unique identifier of the app
9393
* **Environment ID** – the unique identifier of the environment
9494
* **Running Since** – the date the app was started, if it is running
95-
* **Name** – the type of environment (Acceptance, Production, Test, or the name of a [flexible environment](/developerportal/deploy/mendix-cloud-deploy/#flexible-environments)); for more information, see the [Naming of Environments](#naming) section below
95+
* **Display Name** – the type of environment (Acceptance, Production, Test, or the name of a [flexible environment](/developerportal/deploy/mendix-cloud-deploy/#flexible-environments)); for more information, see the [Naming of Environments](#naming) section below
96+
* **Subdomain Suffix** – the application's subdomain name
9697
* **URL** – the URL of the app
9798
* **Custom Domains** – any [custom domains](/developerportal/deploy/custom-domains/) of the app; to add a new domain, click **Add Custom Domain**
9899
* **Studio Pro Target** – a **Yes** or **No** value indicating whether the environment is the designated deployment target from Studio Pro; for more information, see [Studio Pro Deployment Settings](/developerportal/deploy/studio-deployment-settings/)
@@ -103,18 +104,19 @@ In the **Application Status** section of the **General** tab, you can find the f
103104

104105
#### Naming of Environments – Flexible Environments in Mendix Cloud {#naming}
105106

106-
If you are the app's [Technical Contact](/developerportal/general/app-roles/#technical-contact), you can rename the environments.
107+
If you are the app's [Technical Contact](/developerportal/general/app-roles/#technical-contact), you can rename the environment’s **Subdomain Suffix** or **Display Name** by clicking **Change** next to either of the options.
107108

108-
To rename an environment, follow these steps:
109-
110-
1. Click **Change** next to the name of the environment.
111-
2. Enter the new name, which must meet the following requirements:
112-
* Consists of at least two characters.
113-
* Consists of only alphanumeric characters and hyphens (`a-z`, `A-Z`, `0-9`, and `-`).
114-
* Does not begin or end with a hyphen.
109+
* **Display Name requirements**:
110+
* Must start and end with an alphanumeric or non-latin character
111+
* Must contain two or more alphanumeric or non-latin characters and hyphens (–)
112+
* Maximum of 200 characters are allowed
113+
* **Subdomain Suffix requirements**
114+
* Consists of at least two characters
115+
* Consists of only alphanumeric characters and hyphens (`a-z`, `A-Z`, `0-9`, and `-`)
116+
* Does not begin or end with a hyphen
115117

116118
{{% alert color="info" %}}
117-
After you rename an environment, it may take up to 15 minutes before you can access an app via its URL. This is because the URL includes the name of the environment, and the old value needs to be removed from the DNS cache. It may take considerably longer for the change to be visible worldwide.
119+
After you rename an environment’s subdomain suffix, it may take up to 15 minutes before you can access an app via its URL. This is because the URL includes the subdomain name of the environment, and the old value needs to be removed from the DNS cache. It may take considerably longer for the change to be visible worldwide.
118120
{{% /alert %}}
119121

120122
### Deployment Package Details
@@ -139,7 +141,6 @@ It also includes the option to change your plan. For details, refer to [Changing
139141
* **Database Plan Space** – the storage capacity of the database
140142
* **Database Plan Memory** – the database's RAM size
141143
* **File Storage** – available size for storing blobs
142-
* **Backup Storage** – total size available for database backup files
143144
* **Multi-AZ Enabled** – a **Yes** or **No** value indicating whether multiple availability zones are enabled
144145

145146
#### Scaling {#scaling}

content/en/docs/deployment/private-cloud/private-cloud-cluster/private-cloud-standard-operator.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ weight: 30
77

88
## Introduction
99

10-
When running the Mendix Operator in Standard mode, you must install it separately for every namespace where a Mendix app is deployed. However, the [Custom Resource Definitions (CRDs)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) are global and installed at the cluster level - shared and visible among all namespaces in a given Kubernetes/OpenShift cluster. This can potentially lead to redundancies and conflicts, as well as issues when upgrading a single Mendix Operator installation.
11-
12-
To avoid these potential issues, you can [run the Mendix Operator in Global mode](/developerportal/deploy/global-operator/). However, the Standard mode is still available for existing customers, and to support use cases that require having a separate Operator instance for every namespace.
10+
When running the Mendix Operator in Standard mode, you must install it separately for every namespace where a Mendix app is deployed.
1311

1412
{{% alert color="warning" %}}
1513
It is essential to ensure that each namespace is exclusively managed by a single Operator. The deployment of two Operators, particularly with distinct versions, to manage the same namespace, may lead to conflicts, resulting in the cancellation and rollback of each operator's modifications.

content/en/docs/marketplace/genai/reference-guide/mcp-modules/mcp-server.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ The current version has the following limitations:
2525
* Prompts can only return a single message.
2626
* The client connection remains active for only 15 minutes, as the Mendix runtime currently does not support async requests.
2727
* Running an MCP Server is currently only supported on single-instance environments.
28-
* User authorization can currently only be applied on request but not at the tool/prompt level. As a result, the current user is not available within tool/prompt microflows, and entity access or XPath constraints can not be enabled out of the box. This is due to the capabilities offered by the official MCP Java SDK which does not support reusing a Mendix user session in the executed tools/prompts.
28+
* The tool fails to return responses with large payloads to the client successfully. This issue is currently under investigation.
2929

3030
Note that the MCP Server module is still in its early version and latest versions may include breaking changes. Since both the open-source protocol and the Java SDK are still evolving and regularly updated, these changes may also affect this module.
3131

@@ -56,7 +56,9 @@ The selected microflow must adhere to the following principles:
5656
* The Input type should be `MCPServer` and/or `System.HttpRequest`, to extract required values, such as HttpHeaders from the request.
5757
* The return value needs to be a `System.User` object which represents the user who sent the request.
5858

59-
Inside of your microflow, you can implement your custom logic to authenticate the user. For example, you can use username and password (basic auth), Mendix SSO, or external identity providers (IdP) as long as a `User` is returned. Note that the example authentication microflow within the module only implements the most basic authentication.
59+
Within your microflow, you can implement your custom logic to authenticate the user. For example, you can use username and password (basic auth), Mendix SSO, or external identity providers (IdP) as long as a `User` is returned. Note that the example authentication microflow within the module only implements basic authentication.
60+
61+
The `User` returned in the microflow is used for all subsequent prompt and tool microflows within the same session. This makes the `currentUser` and `currentSession` variables available, allowing you to apply entity access for user-based access control based on the default Mendix entity access settings.
6062

6163
#### Protocol Version
6264

@@ -74,7 +76,7 @@ The selected microflow must adhere to the following principles:
7476
For an example, see the `Example Implementations` folder inside of the module.
7577

7678
{{% alert color="warning" %}}
77-
Function calling is a highly effective capability and should be used with caution. Tool microflows currently do not run in the context of the authenticated user, and thus cannot apply entity access.
79+
Function calling is a highly effective capability and should be used with caution.
7880

7981
Mendix strongly recommends keeping the user in the loop (such as by using confirmation logic which is integrated into many MCP clients), if the tool microflows have a potential impact on the real world on behalf of the end-user. Examples include sending emails, posting content online, or making purchases. In such cases, evaluate the use cases and implement security measures when exposing these tools to external AI systems via MCP.
8082
{{% /alert %}}

0 commit comments

Comments
 (0)