diff --git a/.github/config/repos-to-release.txt b/.github/config/repos-to-release.txt new file mode 100644 index 0000000..976a9af --- /dev/null +++ b/.github/config/repos-to-release.txt @@ -0,0 +1 @@ +https://github.com/gridsuite/ci-cd-test \ No newline at end of file diff --git a/.github/workflows/dispatch-release.yml b/.github/workflows/dispatch-release.yml index 67427eb..5db024f 100644 --- a/.github/workflows/dispatch-release.yml +++ b/.github/workflows/dispatch-release.yml @@ -1,11 +1,61 @@ -name: Prepare release +name: Dispatch release on: workflow_dispatch: + inputs: + release-version: + description: Release version (vX.X) + required: true + type: string + branch-name: + description: Branch to release (prepare-release-X.X) + required: true + type: string + pat-token: + description: PAT token (with workflow permissions) jobs: - say-hello: + dispatch-release: runs-on: ubuntu-latest + permissions: + contents: read + steps: - - name: Echo message - run: echo "Hello" \ No newline at end of file + - name: Checkout aggregator repository + uses: actions/checkout@v4 + with: + submodules: false + ref: release-workflow + + - name: Load repo list from file or input + id: load_repos + run: | + if [[ -z "${{ github.event.inputs.repos_to_release }}" ]]; then + echo "ℹ️ No user input → load .github/config/repos-to-release.txt" + list="$(cat .github/config/repos-to-release.txt)" + else + echo "ℹ️ Input found → load user input" + list="${{ github.event.inputs.repos_to_release }}" + fi + echo "list<> $GITHUB_OUTPUT + echo "$list" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create tags and trigger release workflows + run: | + while read url; do + + version=${{github.event.inputs.release-version}} + branch_name=${{github.event.inputs.branch-name}} + + owner=$(echo "$url" | cut -d/ -f4) + repo=$(echo "$url" | cut -d/ -f5 | sed 's/\.git$//') + + gh api repos/$owner/$repo/actions/workflows/release.yml/dispatches \ + -f ref=main \ + -f inputs[releaseVersion]="$version" \ + -f inputs[gitReference]="$branch_name" + + done <<< "${{ steps.load_repos.outputs.list }}" + env: + GH_TOKEN: ${{ github.event.inputs.pat-token }} diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 67427eb..cf6a8b8 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -2,10 +2,112 @@ name: Prepare release on: workflow_dispatch: + inputs: + repos_to_release: + description: "Manual list of repositories to release (.github/config/repos-to-release.txt content if left empty)" + default: "" + required: false + target_date: + description: "Date of last commit to inlude (ISO 8601, ex: 2024-09-13T23:59:59Z - default : last friday 23:59:59)." + required: false + release-version: + description: "Version for new tag (ex: 2.8)" + required: true + secrets: + VERSIONBUMP_GHAPP_PRIVATE_KEY: + required: true jobs: - say-hello: + prepare-release: runs-on: ubuntu-latest steps: - - name: Echo message - run: echo "Hello" \ No newline at end of file + - name: Checkout aggregator repository + uses: actions/checkout@v4 + with: + submodules: false + ref: release-workflow + + - uses: actions/create-github-app-token@21cfef2b496dd8ef5b904c159339626a10ad380e # v1 v1.11.6 + id: app-token + name: Generate app token + with: + app-id: ${{ vars.GRIDSUITE_ACTIONS_APPID }} + private-key: ${{ secrets.VERSIONBUMP_GHAPP_PRIVATE_KEY }} + owner: gridsuite + + - name: Get GitHub App User ID + id: get-user-id + run: | + echo $(gh api "/users/${RUNGHA_APP_SLUG}[bot]") + echo "user-id=$(gh api "/users/${RUNGHA_APP_SLUG}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + RUNGHA_APP_SLUG: ${{ steps.app-token.outputs.app-slug }} # just for defense against script injection + + - name: Setup git user + run: | + git config --global user.name "${RUNGHA_APP_SLUG}[bot]" + git config --global user.email "${RUNGHA_USER_ID}+${RUNGHA_APP_SLUG}[bot]@users.noreply.github.com" + env: + RUNGHA_APP_SLUG: ${{ steps.app-token.outputs.app-slug }} # just for defense against script injection + RUNGHA_USER_ID: ${{ steps.get-user-id.outputs.user-id }} # just for defense against script injection + + - name: Load repo list from file or input + id: load_repos + run: | + if [[ -z "${{ github.event.inputs.repos_to_release }}" ]]; then + echo "ℹ️ No user input → load .github/config/repos-to-release.txt" + list="$(cat .github/config/repos-to-release.txt)" + else + echo "ℹ️ Input found → load user input" + list="${{ github.event.inputs.repos_to_release }}" + fi + echo "list<> $GITHUB_OUTPUT + echo "$list" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Extract last commit date (last friday 23:59 UTC if left empty) + id: load_date + run: | + if [ -z "${{ github.event.inputs.target_date }}" ]; then + date_value=$(date -u -d "last friday 23:59" +"%Y-%m-%dT%H:%M:%SZ") + else + date_value="${{ github.event.inputs.target_date }}" + fi + echo "date_value=$date_value" >> $GITHUB_OUTPUT + echo "This limit date will be used : $date_value" + + - name: Lister les SHAs des commits + run: | + mkdir public_repos + cd public_repos + + while read url; do + url_with_token="${url/https:\/\/github.com/https:\/\/x-access-token:${TOKEN}@github.com}" + git clone "$url_with_token" + folder=$(basename "$url" .git) + cd $folder + commit_date="${{ steps.load_date.outputs.date_value }}" + commit_hash=$(git rev-list -n 1 --before="$commit_date" main) + git checkout $commit_hash + + branch_name="prepare-release-${{github.event.inputs.release-version}}" + # Check if *branch_name* already exists + if git ls-remote --exit-code origin "refs/heads/$branch_name"; then + echo "❌ Warning for $folder: Branch $branch_name already exists" + exit 1 + fi + git checkout -b "$branch_name" + + if ! git push origin "$branch_name"; then + echo "❌ Error for $folder: Failed to push $branch_name" + exit 1 + fi + + commit_message=$(git log -1 --pretty=%s | cut -c1-50) + + echo "✅ $folder : $branch_name branch created → $commit_hash | $commit_message" + cd - > /dev/null + done <<< "${{ steps.load_repos.outputs.list }}" + env: + TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.gitmodules b/.gitmodules index 542b53f..cb12a9b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,389 +12,389 @@ path = backend/libs/powsybl-dynawo url = https://github.com/powsybl/powsybl-dynawo branch = main - ignore = all + ignore = all [submodule "powsybl-open-loadflow"] path = backend/libs/powsybl-open-loadflow url = https://github.com/powsybl/powsybl-open-loadflow branch = main - ignore = all + ignore = all [submodule "powsybl-network-store"] path = backend/libs/powsybl-network-store url = https://github.com/powsybl/powsybl-network-store branch = main - ignore = all + ignore = all [submodule "powsybl-single-line-diagram-server"] path = backend/servers/powsybl-single-line-diagram-server url = https://github.com/powsybl/powsybl-single-line-diagram-server branch = main - ignore = all + ignore = all [submodule "powsybl-network-conversion-server"] path = backend/servers/powsybl-network-conversion-server url = https://github.com/powsybl/powsybl-network-conversion-server branch = main - ignore = all + ignore = all [submodule "powsybl-case"] path = backend/libs/powsybl-case url = https://github.com/powsybl/powsybl-case branch = main - ignore = all + ignore = all [submodule "powsybl-parent"] path = backend/build/powsybl-parent url = https://github.com/powsybl/powsybl-parent branch = main - ignore = all + ignore = all [submodule "powsybl-entsoe"] path = backend/libs/powsybl-entsoe url = https://github.com/powsybl/powsybl-entsoe branch = main - ignore = all + ignore = all [submodule "java-docker"] path = docker/java-docker url = https://github.com/powsybl/java-docker branch = main - ignore = all + ignore = all [submodule "powsybl-ws-commons"] path = backend/libs/powsybl-ws-commons url = https://github.com/powsybl/powsybl-ws-commons branch = main - ignore = all + ignore = all [submodule "study-server"] path = backend/servers/study-server url = https://github.com/gridsuite/study-server branch = main - ignore = all + ignore = all [submodule "network-map-server"] path = backend/servers/network-map-server url = https://github.com/gridsuite/network-map-server branch = main - ignore = all + ignore = all [submodule "deployment"] path = tools/deployment url = https://github.com/gridsuite/deployment branch = main - ignore = all + ignore = all [submodule "gridstudy-app"] path = frontend/apps/gridstudy-app url = https://github.com/gridsuite/gridstudy-app branch = main - ignore = all + ignore = all [submodule "odre-server"] path = backend/servers/odre-server url = https://github.com/gridsuite/odre-server branch = main - ignore = all + ignore = all [submodule "oidc-mock-server"] path = tools/oidc-mock-server url = https://github.com/gridsuite/oidc-mock-server branch = main - ignore = all + ignore = all [submodule "broadcast-event"] path = tools/broadcast-event url = https://github.com/gridsuite/broadcast-event branch = main - ignore = all + ignore = all [submodule "network-modification-server"] path = backend/servers/network-modification-server url = https://github.com/gridsuite/network-modification-server branch = main - ignore = all + ignore = all [submodule "gateway"] path = backend/servers/gateway url = https://github.com/gridsuite/gateway branch = main - ignore = all + ignore = all [submodule "geo-data-app"] path = frontend/apps/geo-data-app url = https://github.com/gridsuite/geo-data-app branch = main - ignore = all + ignore = all [submodule "gridsuite.github.io"] path = docs/gridsuite.github.io url = https://github.com/gridsuite/gridsuite.github.io branch = main - ignore = all + ignore = all [submodule "commons-ui"] path = frontend/libs/commons-ui url = https://github.com/gridsuite/commons-ui branch = main - ignore = all + ignore = all [submodule "case-import-job"] path = backend/jobs/case-import-job url = https://github.com/gridsuite/case-import-job branch = main - ignore = all + ignore = all [submodule "loadflow-server"] path = backend/servers/loadflow-server url = https://github.com/gridsuite/loadflow-server branch = main - ignore = all + ignore = all [submodule "balances-adjustment-server"] path = backend/servers/balances-adjustment-server url = https://github.com/gridsuite/balances-adjustment-server branch = main - ignore = all + ignore = all [submodule "merge-orchestrator-server"] path = backend/servers/merge-orchestrator-server url = https://github.com/gridsuite/merge-orchestrator-server branch = main - ignore = all + ignore = all [submodule "gridapp-template"] path = frontend/apps/gridapp-template url = https://github.com/gridsuite/gridapp-template branch = main - ignore = all + ignore = all [submodule "case-validation-server"] path = backend/servers/case-validation-server url = https://github.com/gridsuite/case-validation-server branch = main - ignore = all + ignore = all [submodule "merge-notification-server"] path = backend/servers/merge-notification-server url = https://github.com/gridsuite/merge-notification-server branch = main - ignore = all + ignore = all [submodule "cgmes-assembling-job"] path = backend/jobs/cgmes-assembling-job url = https://github.com/gridsuite/cgmes-assembling-job branch = main - ignore = all + ignore = all [submodule "cgmes-boundary-server"] path = backend/servers/cgmes-boundary-server url = https://github.com/gridsuite/cgmes-boundary-server branch = main - ignore = all + ignore = all [submodule "gridmerge-app"] path = frontend/apps/gridmerge-app url = https://github.com/gridsuite/gridmerge-app branch = main - ignore = all + ignore = all [submodule "dependencies"] path = backend/build/dependencies url = https://github.com/gridsuite/dependencies branch = main - ignore = all + ignore = all [submodule "java-hades2-docker"] path = docker/java-hades2-docker url = https://github.com/gridsuite/java-hades2-docker branch = main - ignore = all + ignore = all [submodule "actions-server"] path = backend/servers/actions-server url = https://github.com/gridsuite/actions-server branch = main - ignore = all + ignore = all [submodule "security-analysis-server"] path = backend/servers/security-analysis-server url = https://github.com/gridsuite/security-analysis-server branch = main - ignore = all + ignore = all [submodule "gridactions-app"] path = frontend/apps/gridactions-app url = https://github.com/gridsuite/gridactions-app branch = main - ignore = all + ignore = all [submodule "test-cases"] path = tools/test-cases url = https://github.com/gridsuite/test-cases branch = main - ignore = all + ignore = all [submodule "config-server"] path = backend/servers/config-server url = https://github.com/gridsuite/config-server branch = main - ignore = all + ignore = all [submodule "config-notification-server"] path = backend/servers/config-notification-server url = https://github.com/gridsuite/config-notification-server branch = main - ignore = all + ignore = all [submodule "directory-server"] path = backend/servers/directory-server url = https://github.com/gridsuite/directory-server branch = main - ignore = all + ignore = all [submodule "java-dynawo-docker"] path = docker/java-dynawo-docker url = https://github.com/gridsuite/java-dynawo-docker branch = main - ignore = all + ignore = all [submodule "dynamic-simulation-server"] path = backend/servers/dynamic-simulation-server url = https://github.com/gridsuite/dynamic-simulation-server branch = main - ignore = all + ignore = all [submodule "dynamic-security-analysis-server"] path = backend/servers/dynamic-security-analysis-server url = https://github.com/gridsuite/dynamic-security-analysis-server branch = main - ignore = all + ignore = all [submodule "cgmes-boundary-import-job"] path = backend/jobs/cgmes-boundary-import-job url = https://github.com/gridsuite/cgmes-boundary-import-job branch = main - ignore = all + ignore = all [submodule "griddyna-app"] path = frontend/apps/griddyna-app url = https://github.com/gridsuite/griddyna-app branch = main - ignore = all + ignore = all [submodule "filter-server"] path = backend/servers/filter-server url = https://github.com/gridsuite/filter-server branch = main - ignore = all + ignore = all [submodule "dynamic-mapping-server"] path = backend/servers/dynamic-mapping-server url = https://github.com/gridsuite/dynamic-mapping-server branch = main - ignore = all + ignore = all [submodule "report-server"] path = backend/servers/report-server url = https://github.com/gridsuite/report-server branch = main - ignore = all + ignore = all [submodule "gridexplore-app"] path = frontend/apps/gridexplore-app url = https://github.com/gridsuite/gridexplore-app branch = main - ignore = all + ignore = all [submodule "directory-notification-server"] path = backend/servers/directory-notification-server url = https://github.com/gridsuite/directory-notification-server branch = main - ignore = all + ignore = all [submodule "explore-server"] path = backend/servers/explore-server url = https://github.com/gridsuite/explore-server branch = main - ignore = all + ignore = all [submodule "documentation"] path = docs/documentation url = https://github.com/gridsuite/documentation branch = main - ignore = all + ignore = all [submodule "case-import-server"] path = backend/servers/case-import-server url = https://github.com/gridsuite/case-import-server branch = main - ignore = all + ignore = all [submodule "cgmes-gl-server"] path = backend/servers/cgmes-gl-server url = https://github.com/gridsuite/cgmes-gl-server branch = main - ignore = all + ignore = all [submodule "geo-data-server"] path = backend/servers/geo-data-server url = https://github.com/gridsuite/geo-data-server branch = main - ignore = all + ignore = all [submodule "admin-tools"] path = tools/admin-tools url = https://github.com/gridsuite/admin-tools branch = main - ignore = all + ignore = all [submodule "java-simulator-docker"] path = docker/java-simulator-docker url = https://github.com/gridsuite/java-simulator-docker branch = main - ignore = all + ignore = all [submodule "sensitivity-analysis-server"] path = backend/servers/sensitivity-analysis-server url = https://github.com/gridsuite/sensitivity-analysis-server branch = main - ignore = all + ignore = all [submodule "shortcircuit-server"] path = backend/servers/shortcircuit-server url = https://github.com/gridsuite/shortcircuit-server branch = main - ignore = all + ignore = all [submodule "study-notification-server"] path = backend/servers/study-notification-server url = https://github.com/gridsuite/study-notification-server branch = main - ignore = all + ignore = all [submodule "timeseries-server"] path = backend/servers/timeseries-server url = https://github.com/gridsuite/timeseries-server branch = main - ignore = all + ignore = all [submodule "user-admin-server"] path = backend/servers/user-admin-server url = https://github.com/gridsuite/user-admin-server branch = main - ignore = all + ignore = all [submodule "voltage-init-server"] path = backend/servers/voltage-init-server url = https://github.com/gridsuite/voltage-init-server branch = main - ignore = all + ignore = all [submodule "powsybl-case-datasource"] path = backend/libs/powsybl-case-datasource url = https://github.com/powsybl/powsybl-case-datasource branch = main - ignore = all + ignore = all [submodule "powsybl-case-server"] path = backend/servers/powsybl-case-server url = https://github.com/powsybl/powsybl-case-server branch = main - ignore = all + ignore = all [submodule "powsybl-dependencies"] path = backend/build/powsybl-dependencies url = https://github.com/powsybl/powsybl-dependencies branch = main - ignore = all + ignore = all [submodule "powsybl-diagram"] path = backend/libs/powsybl-diagram url = https://github.com/powsybl/powsybl-diagram branch = main - ignore = all + ignore = all [submodule "powsybl-diagram-viewer"] path = frontend/libs/powsybl-diagram-viewer url = https://github.com/powsybl/powsybl-diagram-viewer branch = main - ignore = all + ignore = all [submodule "powsybl-network-store-server"] path = backend/servers/powsybl-network-store-server url = https://github.com/powsybl/powsybl-network-store-server branch = main - ignore = all + ignore = all [submodule "powsybl-network-hypothesis"] path = backend/libs/powsybl-network-hypothesis url = https://github.com/powsybl/powsybl-network-hypothesis branch = main - ignore = all + ignore = all [submodule "powsybl-ws-dependencies"] path = backend/build/powsybl-ws-dependencies url = https://github.com/powsybl/powsybl-ws-dependencies branch = main - ignore = all + ignore = all [submodule "backend/libs/powsybl-optimizer"] path = backend/libs/powsybl-optimizer url = https://github.com/powsybl/powsybl-optimizer branch = main - ignore = all + ignore = all [submodule "frontend/apps/gridadmin-app"] path = frontend/apps/gridadmin-app url = https://github.com/gridsuite/gridadmin-app.git branch = main - ignore = all + ignore = all [submodule "backend/libs/filter"] path = backend/libs/filter url = https://github.com/gridsuite/filter branch = main - ignore = all + ignore = all [submodule "backend/servers/study-config-server"] path = backend/servers/study-config-server url = https://github.com/gridsuite/study-config-server branch = main - ignore = all + ignore = all [submodule "user-identity-oidc-replication-server"] path = backend/servers/user-identity-oidc-replication-server url = https://github.com/gridsuite/user-identity-oidc-replication-server branch = main - ignore = all + ignore = all [submodule "backend/libs/network-modification"] path = backend/libs/network-modification url = https://github.com/gridsuite/network-modification branch = main - ignore = all + ignore = all