From db3519462e462dd1a182e0cb06ef47de8774c270 Mon Sep 17 00:00:00 2001 From: AdemZarrouki Date: Thu, 4 Jun 2026 11:26:55 +0200 Subject: [PATCH 1/4] #1651: update workflow of Update URLS to push status.json files to the new repo ide-urls-status --- .github/workflows/update-urls.yml | 34 ++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update-urls.yml b/.github/workflows/update-urls.yml index df34230c0b..2f192886d9 100644 --- a/.github/workflows/update-urls.yml +++ b/.github/workflows/update-urls.yml @@ -17,6 +17,12 @@ jobs: repository: devonfw/ide-urls path: ide-urls token: ${{ secrets.ACTION_PUSH_TOKEN }} + - name: Checkout ide-urls-status + uses: actions/checkout@v3 + with: + repository: devonfw/ide-urls-status + path: ide-urls-status + token: ${{ secrets.ACTION_PUSH_TOKEN }} - name: Set up Java uses: actions/setup-java@v3 with: @@ -29,14 +35,36 @@ jobs: mvn -B -ntp -Dstyle.color=always -pl url-updater exec:java -Dexec.mainClass="com.devonfw.tools.ide.url.UpdateInitiator" -Dexec.args="ide-urls PT5H30M" env: GHA_TOKEN: ${{ secrets.GHA_TOKEN }} + - name: Sync status.json files to ide-urls-status + run: | + rsync -av --delete --prune-empty-dirs \ + --exclude='.git/' \ + --include='*/' \ + --include='status.json' \ + --exclude='*' \ + ide-urls/ ide-urls-status/ + - name: Commit and push status.json files to ide-urls-status + run: | + cd ide-urls-status + git config --global user.name ${{ secrets.BUILD_USER }} + git config --global user.email ${{ secrets.BUILD_USER_EMAIL }} + git add -A + if ! git diff --cached --quiet; then + git commit -m "Update status.json" + git push + else + echo "No status.json changes" + fi - name: Commit and push to ide-urls run: | cd ide-urls git config --global user.name ${{ secrets.BUILD_USER }} git config --global user.email ${{ secrets.BUILD_USER_EMAIL }} - if git status -z | grep -q . - then - git add . + CHANGED_NON_STATUS_FILES=$(git ls-files --modified --others --exclude-standard | grep -Ev '(^|/)status\.json$' || true) + if [ -n "$CHANGED_NON_STATUS_FILES" ]; then + while IFS= read -r file; do + [ -n "$file" ] && git add "$file" + done <<< "$CHANGED_NON_STATUS_FILES" git commit -m "Update urls" git push else From b8f29f3a894ed8b9323f6f166d0d201dad7d8df6 Mon Sep 17 00:00:00 2001 From: AdemZarrouki Date: Thu, 4 Jun 2026 11:33:07 +0200 Subject: [PATCH 2/4] #1651: update changelog --- CHANGELOG.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 53a168492d..854b7e1294 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -7,7 +7,7 @@ This file documents all notable changes to https://github.com/devonfw/IDEasy[IDE Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/1846[#1846]: Fixed macOS Gatekeeper workaround -* https://github.com/devonfw/IDEasy/issues/1906[#1906]: Fixed `ide uninstall` failing on macOS +* https://github.com/devonfw/IDEasy/issues/1906[#1906]: Fixed `ide uninstall` failing on macOS * https://github.com/devonfw/IDEasy/issues/1985[#1985]: Fix path traversal errors when extracting ZIPs on Windows * https://github.com/devonfw/IDEasy/issues/1255[#1255]: Enhance snapshot version recognition in IDEasy * https://github.com/devonfw/IDEasy/issues/1964[#1964]: Fixed gui not launching with older project java versions @@ -15,6 +15,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/1849[#1849]: Add VSCodium support * https://github.com/devonfw/IDEasy/issues/1391[#1391]: Fix bashrc messed with terraform completions * https://github.com/devonfw/IDEasy/issues/1922[#1922]: Add Task CLI to IDEasy commandlets +* https://github.com/devonfw/IDEasy/issues/1651[#1651]: Move status.json files out of ide-urls to ide-urls-status The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/45?closed=1[milestone 2026.06.001]. From aaa6582a411b6af866f81aa6bc1e3b43aeb19f39 Mon Sep 17 00:00:00 2001 From: AdemZarrouki Date: Wed, 24 Jun 2026 14:03:08 +0200 Subject: [PATCH 3/4] #1651: make UpdateInitiator and UpdateManager to support separate status repository --- .../ide/url/model/folder/UrlRepository.java | 19 +++++++ .../ide/url/model/folder/UrlVersion.java | 53 ++++++++++++++++++- .../tools/ide/url/UpdateInitiator.java | 42 ++++++++++----- .../tools/ide/url/updater/UpdateManager.java | 18 ++++++- 4 files changed, 115 insertions(+), 17 deletions(-) diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/UrlRepository.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/UrlRepository.java index 429a186b26..b384026892 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/UrlRepository.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/UrlRepository.java @@ -7,6 +7,8 @@ */ public class UrlRepository extends AbstractUrlFolder { + private UrlRepository statusRepository; + /** * The constructor. * @@ -39,4 +41,21 @@ protected UrlTool newChild(String name) { return new UrlTool(this, name); } + /** + * @return the {@link UrlRepository} used to store status files. + */ + public UrlRepository getStatusRepository() { + if (this.statusRepository == null) { + return this; + } + return this.statusRepository; + } + + + /** + * @param statusRepository the {@link UrlRepository} used to store status files. + */ + public void setStatusRepository(UrlRepository statusRepository) { + this.statusRepository = statusRepository; + } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/UrlVersion.java b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/UrlVersion.java index 44fc822f92..8ab1cce95d 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/UrlVersion.java +++ b/cli/src/main/java/com/devonfw/tools/ide/url/model/folder/UrlVersion.java @@ -131,12 +131,53 @@ public static String getUrlsFileName(OperatingSystem os, SystemArchitecture arch return os + "_" + SystemArchitecture.orDefault(arch) + UrlDownloadFile.EXTENSION_URLS; } + /** + * @return the matching {@link UrlVersion} in the status repository, or this version if no separate status repository is configured. + */ + private UrlVersion getStatusVersion() { + UrlRepository statusRepository = getParent().getParent().getParent().getStatusRepository(); + String toolName = getParent().getParent().getName(); + String editionName = getParent().getName(); + String versionName = getName(); + UrlTool statusTool = statusRepository.getChild(toolName); + if (statusTool == null) { + return null; + } + UrlEdition statusEdition = statusTool.getChild(editionName); + if (statusEdition == null) { + return null; + } + return statusEdition.getChild(versionName); + } + + + /** + * @return the matching {@link UrlVersion} in the status repository. It will be created if it does not exist. + */ + private UrlVersion getOrCreateStatusVersion() { + + UrlRepository statusRepository = getParent().getParent().getParent().getStatusRepository(); + + String toolName = getParent().getParent().getName(); + String editionName = getParent().getName(); + String versionName = getName(); + + UrlTool statusTool = statusRepository.getOrCreateChild(toolName); + UrlEdition statusEdition = statusTool.getOrCreateChild(editionName); + + return statusEdition.getOrCreateChild(versionName); + } + /** * @return the {@link UrlStatusFile}. */ public UrlStatusFile getStatus() { - return (UrlStatusFile) getChild(UrlStatusFile.STATUS_JSON); + UrlVersion statusVersion = getStatusVersion(); + if (statusVersion == null) { + return null; + } + return (UrlStatusFile) statusVersion.getChild(UrlStatusFile.STATUS_JSON); } /** @@ -144,7 +185,8 @@ public UrlStatusFile getStatus() { */ public UrlStatusFile getOrCreateStatus() { - return (UrlStatusFile) getOrCreateChild(UrlStatusFile.STATUS_JSON); + UrlVersion statusVersion = getOrCreateStatusVersion(); + return (UrlStatusFile) statusVersion.getOrCreateChild(UrlStatusFile.STATUS_JSON); } /** @@ -210,7 +252,11 @@ protected boolean isAllowedChild(String name, boolean folder) { @Override public void save() { + UrlVersion statusVersion = getStatusVersion(); if (getChildCount() == 0) { + if ((statusVersion != null) && (statusVersion != this)) { + statusVersion.save(); + } return; } Path path = getPath(); @@ -220,6 +266,9 @@ public void save() { throw new IllegalStateException("Failed to create directory " + path, e); } super.save(); + if ((statusVersion != null) && (statusVersion != this)) { + statusVersion.save(); + } } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java index 0588b497f9..0ab47afa61 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/UpdateInitiator.java @@ -19,49 +19,63 @@ public class UpdateInitiator { private static final Logger logger = LoggerFactory.getLogger(UpdateInitiator.class.getName()); /** - * @param args the command-line arguments. arg[0] points to the {@code ide-urls} repository. arg[1] defines a timeout for GitHub actions in Duration - * string format and arg[2] (optional) can be used to specify a single tool to update instead of all tools, either by toolname (e.g. java) or using the Classname of - * the Updater (e.g. JavaAzulUrlUpdater). The timeout is used to prevent the GitHub action from running into a timeout error due to too long execution - * time. + * @param args the command-line arguments. arg[0] points to the {@code ide-urls} repository. arg[1] points to the {@code ide-urls-status} repository. + * arg[2] defines a timeout for GitHub actions in Duration string format and arg[3] (optional) can be used to specify a single tool to update instead of + * all tools, either by toolname (e.g. java) or using the Classname of the Updater (e.g. JavaAzulUrlUpdater). The timeout is used to prevent the GitHub + * action from running into a timeout error due to too long execution time. */ public static void main(String[] args) { if (args.length == 0) { logger.error("Error: Missing path to repository as well as missing timeout as command line arguments."); - logger.error("Usage: java UpdateInitiator "); + logger.error( + "Usage: java UpdateInitiator "); System.exit(1); } - String pathToRepo = args[0]; + if (args.length < 2) { + logger.error("Error: Missing path to URL repository and/or status repository."); + logger.error( + "Usage: java UpdateInitiator "); + System.exit(1); + } + + String pathToUrlRepo = args[0]; + String pathToStatusRepo = args[1]; Instant expirationTime = null; String selectedTool = null; - if (args.length < 2) { + if (args.length < 3) { logger.warn("Timeout was not set, setting timeout to infinite instead."); } else { try { - Duration duration = Duration.parse(args[1]); + Duration duration = Duration.parse(args[2]); expirationTime = Instant.now().plus(duration); logger.info("Timeout was set to: {}.", expirationTime); } catch (DateTimeParseException e) { logger.error("Error: Provided timeout format is not valid.", e); System.exit(1); } - if (args.length > 2) { - selectedTool = args[2]; + if (args.length > 3) { + selectedTool = args[3]; } } - Path repoPath = Path.of(pathToRepo); + Path urlRepoPath = Path.of(pathToUrlRepo); + Path statusRepoPath = Path.of(pathToStatusRepo); - if (!repoPath.toFile().isDirectory()) { - logger.error("Error: Provided path is not a valid directory."); + if (!urlRepoPath.toFile().isDirectory()) { + logger.error("Error: Provided URL repository path is not a valid directory."); + System.exit(1); + } + if (!statusRepoPath.toFile().isDirectory()) { + logger.error("Error: Provided status repository path is not a valid directory."); System.exit(1); } UrlFinalReport urlFinalReport = new UrlFinalReport(); - UpdateManager updateManager = new UpdateManager(repoPath, urlFinalReport, expirationTime); + UpdateManager updateManager = new UpdateManager(urlRepoPath, statusRepoPath, urlFinalReport, expirationTime); if (selectedTool == null) { updateManager.updateAll(); } else { diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java index e3370dda23..68f2597464 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/UpdateManager.java @@ -70,6 +70,8 @@ public class UpdateManager extends AbstractProcessorWithTimeout { private final UrlRepository urlRepository; + private final UrlRepository statusRepository; + private final UrlFinalReport urlFinalReport; private final List updaters = List.of( @@ -90,15 +92,29 @@ public class UpdateManager extends AbstractProcessorWithTimeout { * The constructor. * * @param pathToRepository the {@link Path} to the {@code ide-urls} repository to update. + * @param pathToStatusRepository the {@link Path} to the {@code ide-urls-status} repository to update. * @param expirationTime for GitHub actions url-update job */ - public UpdateManager(Path pathToRepository, UrlFinalReport urlFinalReport, Instant expirationTime) { + public UpdateManager(Path pathToRepository, Path pathToStatusRepository, UrlFinalReport urlFinalReport, Instant expirationTime) { this.urlRepository = UrlRepository.load(pathToRepository); + this.statusRepository = UrlRepository.load(pathToStatusRepository); + this.urlRepository.setStatusRepository(this.statusRepository); this.urlFinalReport = urlFinalReport; setExpirationTime(expirationTime); } + /** + * The constructor. + * + * @param pathToRepository the {@link Path} to the {@code ide-urls} repository to update. + * @param expirationTime for GitHub actions url-update job. + */ + public UpdateManager(Path pathToRepository, UrlFinalReport urlFinalReport, Instant expirationTime) { + + this(pathToRepository, pathToRepository, urlFinalReport, expirationTime); + } + /** * @return the {@link List} with all registered {@link AbstractUrlUpdater updaters}. */ From cba0d9abc80b1507cb62cd45a84c4a851101f66f Mon Sep 17 00:00:00 2001 From: AdemZarrouki Date: Thu, 25 Jun 2026 11:11:30 +0200 Subject: [PATCH 4/4] #1651: adjust workflow so that UpdateInitiator accepts 2 repos --- .github/workflows/update-urls.yml | 39 ++++++++++++------------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/.github/workflows/update-urls.yml b/.github/workflows/update-urls.yml index 2f192886d9..fa948f68a6 100644 --- a/.github/workflows/update-urls.yml +++ b/.github/workflows/update-urls.yml @@ -32,43 +32,34 @@ jobs: - name: Build and run url updater run: | mvn -B -ntp -Dstyle.color=always -pl url-updater -am install - mvn -B -ntp -Dstyle.color=always -pl url-updater exec:java -Dexec.mainClass="com.devonfw.tools.ide.url.UpdateInitiator" -Dexec.args="ide-urls PT5H30M" + mvn -B -ntp -Dstyle.color=always -pl url-updater exec:java -Dexec.mainClass="com.devonfw.tools.ide.url.UpdateInitiator" -Dexec.args="ide-urls ide-urls-status PT5H30M" env: GHA_TOKEN: ${{ secrets.GHA_TOKEN }} - - name: Sync status.json files to ide-urls-status - run: | - rsync -av --delete --prune-empty-dirs \ - --exclude='.git/' \ - --include='*/' \ - --include='status.json' \ - --exclude='*' \ - ide-urls/ ide-urls-status/ - - name: Commit and push status.json files to ide-urls-status + - name: Commit and push to ide-urls run: | - cd ide-urls-status + cd ide-urls git config --global user.name ${{ secrets.BUILD_USER }} git config --global user.email ${{ secrets.BUILD_USER_EMAIL }} - git add -A - if ! git diff --cached --quiet; then - git commit -m "Update status.json" + if git status -z | grep -q . + then + git add . + git commit -m "Update urls" git push else - echo "No status.json changes" + echo "No changes, nothing to commit." fi - - name: Commit and push to ide-urls + - name: Commit and push status.json files to ide-urls-status run: | - cd ide-urls + cd ide-urls-status git config --global user.name ${{ secrets.BUILD_USER }} git config --global user.email ${{ secrets.BUILD_USER_EMAIL }} - CHANGED_NON_STATUS_FILES=$(git ls-files --modified --others --exclude-standard | grep -Ev '(^|/)status\.json$' || true) - if [ -n "$CHANGED_NON_STATUS_FILES" ]; then - while IFS= read -r file; do - [ -n "$file" ] && git add "$file" - done <<< "$CHANGED_NON_STATUS_FILES" - git commit -m "Update urls" + if git status -z | grep -q . + then + git add . + git commit -m "Update status.json" git push else - echo "No changes, nothing to commit." + echo "No status.json changes" fi trigger_update_cve: runs-on: ubuntu-latest