From 162828c0a606a26aa0babef2fcf0e6f3b13cc5fb Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri Benedetti Date: Mon, 22 Sep 2025 11:49:19 +0200 Subject: [PATCH 1/8] Add PR creation logic --- .../workflows/update-kube-stack-version.yml | 43 +------ scripts/update_kube_stack_version.py | 110 +++++++++++++++++- 2 files changed, 110 insertions(+), 43 deletions(-) diff --git a/.github/workflows/update-kube-stack-version.yml b/.github/workflows/update-kube-stack-version.yml index 2336bd91d1..82b045924b 100644 --- a/.github/workflows/update-kube-stack-version.yml +++ b/.github/workflows/update-kube-stack-version.yml @@ -21,45 +21,12 @@ jobs: with: python-version: '3.13' - - name: Run kube-stack version update script - run: | - cd scripts - python update_kube_stack_version.py - - - name: Check for changes - id: verify-changed-files - run: | - if [ -n "$(git status --porcelain)" ]; then - echo "changed=true" >> $GITHUB_OUTPUT - else - echo "changed=false" >> $GITHUB_OUTPUT - fi - - - name: Commit and push changes - if: steps.verify-changed-files.outputs.changed == 'true' + - name: Set up Git configuration run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - git add docset.yml - git commit -m "chore: update kube-stack version [skip ci]" - git push - - name: Create Pull Request - if: steps.verify-changed-files.outputs.changed == 'true' - uses: peter-evans/create-pull-request@v5 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "chore: update kube-stack version" - title: "chore: update kube-stack version" - body: | - This PR automatically updates the kube-stack version in `docset.yml` based on the latest version from the elastic-agent repository. - - **Changes:** - - Updated kube-stack version in docset.yml - - This PR was created automatically by the weekly kube-stack version update workflow. - branch: update-kube-stack-version - delete-branch: true - labels: | - automated - documentation + - name: Run kube-stack version update script + run: | + cd scripts + python update_kube_stack_version.py --create-pr diff --git a/scripts/update_kube_stack_version.py b/scripts/update_kube_stack_version.py index 513616bbe8..f6403ef447 100755 --- a/scripts/update_kube_stack_version.py +++ b/scripts/update_kube_stack_version.py @@ -18,6 +18,8 @@ import sys import argparse import subprocess +import os +import datetime from pathlib import Path @@ -25,12 +27,15 @@ def fetch_url_content(url): """Fetch content from a URL""" try: print(f"Attempting to fetch: {url}") - with urllib.request.urlopen(url) as response: + with urllib.request.urlopen(url, timeout=30) as response: content = response.read().decode('utf-8') return content except urllib.error.URLError as e: print(f"Failed to retrieve content: {e.reason}") return None + except Exception as e: + print(f"Unexpected error fetching URL: {e}") + return None def get_latest_collector_version(): @@ -40,7 +45,11 @@ def get_latest_collector_version(): # Run git command to get the latest semantic version tag cmd = ['git', 'ls-remote', '--tags', 'https://github.com/elastic/elastic-agent.git'] - result = subprocess.run(cmd, capture_output=True, text=True, check=True) + result = subprocess.run(cmd, capture_output=True, text=True, check=True, timeout=60) + + if not result.stdout.strip(): + print("No output from git ls-remote command") + return None # Extract version tags and find the latest semantic version tags = [] @@ -67,8 +76,13 @@ def version_key(tag): print(f"Latest collector version: {version}") return version + except subprocess.TimeoutExpired: + print("Timeout while fetching tags from elastic-agent repository") + return None except subprocess.CalledProcessError as e: print(f"Error fetching tags from elastic-agent repository: {e}") + if e.stderr: + print(f"Error details: {e.stderr}") return None except Exception as e: print(f"Error getting latest collector version: {e}") @@ -146,10 +160,86 @@ def update_docset_kube_stack_version(version, docset_path, dry_run=False): return False +def create_pr(version, dry_run=False): + """Create a pull request with the kube-stack version update""" + if dry_run: + print(f"[DRY RUN] Would create PR for kube-stack version {version}") + return True + + try: + # Generate a unique branch name with timestamp and random suffix + timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + import random + random_suffix = random.randint(1000, 9999) + branch_name = f"update-kube-stack-{version}-{timestamp}-{random_suffix}" + + print(f"Creating branch: {branch_name}") + + # Check if we're already on a branch (avoid detached HEAD) + try: + current_branch = subprocess.run(['git', 'branch', '--show-current'], + capture_output=True, text=True, check=True).stdout.strip() + if not current_branch: + print("Warning: Not on any branch, checking out main first") + subprocess.run(['git', 'checkout', 'main'], check=True) + except subprocess.CalledProcessError: + print("Warning: Could not determine current branch") + + # Create and checkout new branch + subprocess.run(['git', 'checkout', '-b', branch_name], check=True) + + # Add and commit changes + subprocess.run(['git', 'add', 'docset.yml'], check=True) + subprocess.run(['git', 'commit', '-m', f'chore: update kube-stack version to {version} [skip ci]'], check=True) + + # Push the branch + subprocess.run(['git', 'push', '-u', 'origin', branch_name], check=True) + + # Create PR using GitHub CLI if available, otherwise provide instructions + try: + pr_body = f"""This PR automatically updates the kube-stack version in `docset.yml` to {version} based on the latest version from the elastic-agent repository. + +**Changes:** +- Updated kube-stack version from previous version to {version} + +This PR was created automatically by the kube-stack version update script.""" + + result = subprocess.run([ + 'gh', 'pr', 'create', + '--title', f'chore: update kube-stack version to {version}', + '--body', pr_body, + '--label', 'automated,documentation' + ], capture_output=True, text=True, check=True) + + print(f"Created PR: {result.stdout.strip()}") + + except (subprocess.CalledProcessError, FileNotFoundError) as e: + print(f"GitHub CLI not available or failed: {e}") + print("Branch created and pushed successfully. Please create PR manually:") + print(f"Branch: {branch_name}") + print(f"Title: chore: update kube-stack version to {version}") + print(f"URL: https://github.com/elastic/docs-content/compare/{branch_name}") + # Don't fail the script if GitHub CLI is not available + return True + + return True + + except subprocess.CalledProcessError as e: + print(f"Error creating PR: {e}") + return False + except Exception as e: + print(f"Error creating PR: {e}") + return False + + def main(): parser = argparse.ArgumentParser(description='Update kube-stack version in docset.yml') parser.add_argument('--dry-run', action='store_true', help='Show what would be updated without making changes') + parser.add_argument('--create-pr', action='store_true', default=True, + help='Create a pull request for the changes (default: True)') + parser.add_argument('--no-pr', action='store_false', dest='create_pr', + help='Do not create a pull request, just update the file') args = parser.parse_args() # Get the script directory and construct paths relative to it @@ -178,10 +268,20 @@ def main(): success = update_docset_kube_stack_version(kube_stack_version, docset_path, args.dry_run) if success: - print("Kube-stack version update completed successfully") - sys.exit(0) + if args.create_pr: + # Create PR for the changes + pr_success = create_pr(kube_stack_version, args.dry_run) + if pr_success: + print("Kube-stack version update and PR creation completed successfully") + sys.exit(0) + else: + print("Kube-stack version updated but PR creation failed") + sys.exit(1) + else: + print("Kube-stack version update completed successfully") + sys.exit(0) else: - print("No update was needed") + print("No update was needed - kube-stack version is already up to date") sys.exit(0) From f7da5dab577402a192ba4c6c328b07852fa25b30 Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri Benedetti Date: Mon, 22 Sep 2025 11:52:51 +0200 Subject: [PATCH 2/8] chore: update kube-stack version to 0.9.1 [skip ci] --- docset.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docset.yml b/docset.yml index a904166be5..ba002386d7 100644 --- a/docset.yml +++ b/docset.yml @@ -295,5 +295,5 @@ subs: intake-apis: https://www.elastic.co/docs/api/doc/observability-serverless/ models-app: "Trained Models" agent-builder: "Elastic Agent Builder" - kube-stack-version: 0.6.3 + kube-stack-version: 0.9.1 From 3a1365005c0d33664c0cd35ae96a37dc27bd3f86 Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri Benedetti Date: Mon, 22 Sep 2025 11:52:51 +0200 Subject: [PATCH 3/8] Use GH for PR creation --- .../workflows/update-kube-stack-version.yml | 31 ++++++- scripts/update_kube_stack_version.py | 80 ++++--------------- 2 files changed, 44 insertions(+), 67 deletions(-) diff --git a/.github/workflows/update-kube-stack-version.yml b/.github/workflows/update-kube-stack-version.yml index 82b045924b..925ecbc655 100644 --- a/.github/workflows/update-kube-stack-version.yml +++ b/.github/workflows/update-kube-stack-version.yml @@ -29,4 +29,33 @@ jobs: - name: Run kube-stack version update script run: | cd scripts - python update_kube_stack_version.py --create-pr + python update_kube_stack_version.py --prepare-git + + - name: Check for changes + id: verify-changed-files + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "changed=true" >> $GITHUB_OUTPUT + else + echo "changed=false" >> $GITHUB_OUTPUT + fi + + - name: Create Pull Request + if: steps.verify-changed-files.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore: update kube-stack version" + title: "chore: update kube-stack version" + body: | + This PR automatically updates the kube-stack version in `docset.yml` based on the latest version from the elastic-agent repository. + + **Changes:** + - Updated kube-stack version in docset.yml + + This PR was created automatically by the weekly kube-stack version update workflow. + branch: update-kube-stack-version + delete-branch: true + labels: | + automated + documentation diff --git a/scripts/update_kube_stack_version.py b/scripts/update_kube_stack_version.py index f6403ef447..a177eef61b 100755 --- a/scripts/update_kube_stack_version.py +++ b/scripts/update_kube_stack_version.py @@ -160,75 +160,25 @@ def update_docset_kube_stack_version(version, docset_path, dry_run=False): return False -def create_pr(version, dry_run=False): - """Create a pull request with the kube-stack version update""" +def prepare_git_changes(version, dry_run=False): + """Prepare git changes for PR creation (used by GitHub Actions)""" if dry_run: - print(f"[DRY RUN] Would create PR for kube-stack version {version}") + print(f"[DRY RUN] Would prepare git changes for kube-stack version {version}") return True try: - # Generate a unique branch name with timestamp and random suffix - timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") - import random - random_suffix = random.randint(1000, 9999) - branch_name = f"update-kube-stack-{version}-{timestamp}-{random_suffix}" - - print(f"Creating branch: {branch_name}") - - # Check if we're already on a branch (avoid detached HEAD) - try: - current_branch = subprocess.run(['git', 'branch', '--show-current'], - capture_output=True, text=True, check=True).stdout.strip() - if not current_branch: - print("Warning: Not on any branch, checking out main first") - subprocess.run(['git', 'checkout', 'main'], check=True) - except subprocess.CalledProcessError: - print("Warning: Could not determine current branch") - - # Create and checkout new branch - subprocess.run(['git', 'checkout', '-b', branch_name], check=True) - # Add and commit changes subprocess.run(['git', 'add', 'docset.yml'], check=True) subprocess.run(['git', 'commit', '-m', f'chore: update kube-stack version to {version} [skip ci]'], check=True) - # Push the branch - subprocess.run(['git', 'push', '-u', 'origin', branch_name], check=True) - - # Create PR using GitHub CLI if available, otherwise provide instructions - try: - pr_body = f"""This PR automatically updates the kube-stack version in `docset.yml` to {version} based on the latest version from the elastic-agent repository. - -**Changes:** -- Updated kube-stack version from previous version to {version} - -This PR was created automatically by the kube-stack version update script.""" - - result = subprocess.run([ - 'gh', 'pr', 'create', - '--title', f'chore: update kube-stack version to {version}', - '--body', pr_body, - '--label', 'automated,documentation' - ], capture_output=True, text=True, check=True) - - print(f"Created PR: {result.stdout.strip()}") - - except (subprocess.CalledProcessError, FileNotFoundError) as e: - print(f"GitHub CLI not available or failed: {e}") - print("Branch created and pushed successfully. Please create PR manually:") - print(f"Branch: {branch_name}") - print(f"Title: chore: update kube-stack version to {version}") - print(f"URL: https://github.com/elastic/docs-content/compare/{branch_name}") - # Don't fail the script if GitHub CLI is not available - return True - + print(f"Git changes prepared for kube-stack version {version}") return True except subprocess.CalledProcessError as e: - print(f"Error creating PR: {e}") + print(f"Error preparing git changes: {e}") return False except Exception as e: - print(f"Error creating PR: {e}") + print(f"Error preparing git changes: {e}") return False @@ -236,10 +186,8 @@ def main(): parser = argparse.ArgumentParser(description='Update kube-stack version in docset.yml') parser.add_argument('--dry-run', action='store_true', help='Show what would be updated without making changes') - parser.add_argument('--create-pr', action='store_true', default=True, - help='Create a pull request for the changes (default: True)') - parser.add_argument('--no-pr', action='store_false', dest='create_pr', - help='Do not create a pull request, just update the file') + parser.add_argument('--prepare-git', action='store_true', default=False, + help='Prepare git changes for PR creation (used by GitHub Actions)') args = parser.parse_args() # Get the script directory and construct paths relative to it @@ -268,14 +216,14 @@ def main(): success = update_docset_kube_stack_version(kube_stack_version, docset_path, args.dry_run) if success: - if args.create_pr: - # Create PR for the changes - pr_success = create_pr(kube_stack_version, args.dry_run) - if pr_success: - print("Kube-stack version update and PR creation completed successfully") + if args.prepare_git: + # Prepare git changes for GitHub Actions PR creation + git_success = prepare_git_changes(kube_stack_version, args.dry_run) + if git_success: + print("Kube-stack version update and git changes prepared successfully") sys.exit(0) else: - print("Kube-stack version updated but PR creation failed") + print("Kube-stack version updated but git preparation failed") sys.exit(1) else: print("Kube-stack version update completed successfully") From 7150389fef5958f2041f90969456c9a61600783d Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri Benedetti Date: Mon, 22 Sep 2025 11:54:35 +0200 Subject: [PATCH 4/8] Bump PR step version --- .github/workflows/update-kube-stack-version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-kube-stack-version.yml b/.github/workflows/update-kube-stack-version.yml index 925ecbc655..37ca486f38 100644 --- a/.github/workflows/update-kube-stack-version.yml +++ b/.github/workflows/update-kube-stack-version.yml @@ -42,7 +42,7 @@ jobs: - name: Create Pull Request if: steps.verify-changed-files.outputs.changed == 'true' - uses: peter-evans/create-pull-request@v5 + uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.GITHUB_TOKEN }} commit-message: "chore: update kube-stack version" From e873877cdcee2f4cef3df4b2b682b0de857e92df Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri Benedetti Date: Mon, 22 Sep 2025 11:56:15 +0200 Subject: [PATCH 5/8] Bump version in action --- .github/workflows/update-kube-stack-version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-kube-stack-version.yml b/.github/workflows/update-kube-stack-version.yml index 37ca486f38..f29fe1ff2b 100644 --- a/.github/workflows/update-kube-stack-version.yml +++ b/.github/workflows/update-kube-stack-version.yml @@ -54,7 +54,7 @@ jobs: - Updated kube-stack version in docset.yml This PR was created automatically by the weekly kube-stack version update workflow. - branch: update-kube-stack-version + branch: update-kube-stack-version-${{ github.run_id }} delete-branch: true labels: | automated From 220aba2cccd07a6cbeaa07645a15dc5bbb7eadc2 Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri Benedetti Date: Mon, 22 Sep 2025 11:57:33 +0200 Subject: [PATCH 6/8] Restore version for test --- docset.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docset.yml b/docset.yml index ba002386d7..a904166be5 100644 --- a/docset.yml +++ b/docset.yml @@ -295,5 +295,5 @@ subs: intake-apis: https://www.elastic.co/docs/api/doc/observability-serverless/ models-app: "Trained Models" agent-builder: "Elastic Agent Builder" - kube-stack-version: 0.9.1 + kube-stack-version: 0.6.3 From 80dd88a52e3448869a9c462ddfc72db87a8287ea Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri Benedetti Date: Mon, 22 Sep 2025 11:58:08 +0200 Subject: [PATCH 7/8] chore: update kube-stack version to 0.9.1 [skip ci] --- docset.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docset.yml b/docset.yml index a904166be5..ba002386d7 100644 --- a/docset.yml +++ b/docset.yml @@ -295,5 +295,5 @@ subs: intake-apis: https://www.elastic.co/docs/api/doc/observability-serverless/ models-app: "Trained Models" agent-builder: "Elastic Agent Builder" - kube-stack-version: 0.6.3 + kube-stack-version: 0.9.1 From 968e2fe6f1fbf60a63f3c5bfcb511a75b6899116 Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri Benedetti Date: Mon, 22 Sep 2025 11:58:59 +0200 Subject: [PATCH 8/8] Restore v --- docset.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docset.yml b/docset.yml index ba002386d7..a904166be5 100644 --- a/docset.yml +++ b/docset.yml @@ -295,5 +295,5 @@ subs: intake-apis: https://www.elastic.co/docs/api/doc/observability-serverless/ models-app: "Trained Models" agent-builder: "Elastic Agent Builder" - kube-stack-version: 0.9.1 + kube-stack-version: 0.6.3