diff --git a/.github/workflows/suggest_docs.yml b/.github/workflows/suggest_docs.yml index 5cac468df..9ee5ca1fa 100644 --- a/.github/workflows/suggest_docs.yml +++ b/.github/workflows/suggest_docs.yml @@ -50,4 +50,4 @@ jobs: DOCS_REPO_URL: ${{ secrets.DOCS_REPO_URL }} GH_TOKEN: ${{ secrets.GH_PAT }} run: | - python scripts/suggest_docs.py + python scripts/suggest_docs.py \ No newline at end of file diff --git a/config/crd/bases/appstudio.redhat.com_releaseplanadmissions.yaml b/config/crd/bases/appstudio.redhat.com_releaseplanadmissions.yaml index 8647dfda2..2c32384a3 100644 --- a/config/crd/bases/appstudio.redhat.com_releaseplanadmissions.yaml +++ b/config/crd/bases/appstudio.redhat.com_releaseplanadmissions.yaml @@ -24,11 +24,20 @@ spec: - jsonPath: .spec.origin name: Origin type: string + - jsonPath: .spec.approvalMode + name: Approval + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .spec.autoRelease + name: Auto-Release + type: boolean name: v1alpha1 schema: openAPIV3Schema: description: ReleasePlanAdmission is the Schema for the ReleasePlanAdmissions - API. + API. This resource controls approval workflows and automated release processes for applications. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -51,6 +60,16 @@ spec: items: type: string type: array + approvalMode: + description: ApprovalMode defines the approval process for releases (manual, automatic, or policy-based) + enum: + - manual + - automatic + - policy-based + type: string + autoRelease: + description: AutoRelease enables automatic release creation when conditions are met + type: boolean data: description: Data is an unstructured key used for providing data for the release Pipeline @@ -61,6 +80,25 @@ spec: release the Application pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + notificationConfig: + description: NotificationConfig defines notification settings for release events + properties: + channels: + description: Channels specifies where notifications should be sent (e.g., slack, email) + items: + type: string + type: array + events: + description: Events specifies which events trigger notifications + items: + enum: + - release-started + - release-completed + - release-failed + - approval-required + type: string + type: array + type: object origin: description: Origin references where the release requests should come from @@ -111,6 +149,7 @@ spec: type: string required: - applications + - approvalMode - origin - pipelineRef - policy @@ -206,6 +245,15 @@ spec: type: string type: object type: array + phase: + description: Phase represents the current phase of the ReleasePlanAdmission (e.g., Active, Pending, Disabled, Error) + enum: + - Active + - Pending + - Disabled + - Error + - Validating + type: string type: object type: object served: true diff --git a/config/crd/bases/appstudio.redhat.com_releases.yaml b/config/crd/bases/appstudio.redhat.com_releases.yaml index c56548049..9ba4e930b 100644 --- a/config/crd/bases/appstudio.redhat.com_releases.yaml +++ b/config/crd/bases/appstudio.redhat.com_releases.yaml @@ -22,6 +22,12 @@ spec: - jsonPath: .spec.releasePlan name: ReleasePlan type: string + - jsonPath: .spec.environment + name: Environment + type: string + - jsonPath: .status.phase + name: Phase + type: string - jsonPath: .status.conditions[?(@.type=="Released")].reason name: Release status type: string @@ -31,7 +37,7 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - description: Release is the Schema for the releases API + description: Release is the Schema for the releases API. This resource manages application releases across different environments with rollback capabilities. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -48,15 +54,32 @@ spec: spec: description: ReleaseSpec defines the desired state of Release. properties: + environment: + description: Environment specifies the target deployment environment (e.g., development, staging, production) + enum: + - development + - staging + - production + - testing + type: string + gracePeriodSeconds: + description: GracePeriodSeconds defines the grace period for release shutdown operations + format: int64 + minimum: 0 + type: integer releasePlan: description: ReleasePlan to use for this particular Release pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string + rollbackEnabled: + description: RollbackEnabled indicates whether automatic rollback is enabled for this release + type: boolean snapshot: description: Snapshot to be released pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string required: + - environment - releasePlan - snapshot type: object @@ -80,6 +103,16 @@ spec: description: Automated indicates whether the Release was created as part of an automated process or manually by an end-user type: boolean + phase: + description: Phase represents the current phase of the Release lifecycle (e.g., Preparing, InProgress, Completed, Failed, RolledBack) + enum: + - Preparing + - InProgress + - Completed + - Failed + - RolledBack + - Cancelled + type: string completionTime: description: CompletionTime is the time when a Release was completed format: date-time diff --git a/config/crd/bases/appstudio.redhat.com_releaseserviceconfigs.yaml b/config/crd/bases/appstudio.redhat.com_releaseserviceconfigs.yaml index 05770b496..03a26b988 100644 --- a/config/crd/bases/appstudio.redhat.com_releaseserviceconfigs.yaml +++ b/config/crd/bases/appstudio.redhat.com_releaseserviceconfigs.yaml @@ -16,11 +16,18 @@ spec: singular: releaseserviceconfig scope: Namespaced versions: - - name: v1alpha1 + - additionalPrinterColumns: + - jsonPath: .spec.debug + name: Debug + type: boolean + - jsonPath: .spec.logLevel + name: Log Level + type: string + name: v1alpha1 schema: openAPIV3Schema: description: ReleaseServiceConfig is the Schema for the releaseserviceconfigs - API + API. This resource manages global configuration settings for the release service. properties: apiVersion: description: |- @@ -71,6 +78,20 @@ spec: Debug is the boolean that specifies whether or not the Release Service should run in debug mode type: boolean + logLevel: + description: LogLevel defines the logging verbosity level for the release service + enum: + - trace + - debug + - info + - warn + - error + type: string + retryAttempts: + description: RetryAttempts specifies the maximum number of retry attempts for failed pipeline runs + minimum: 0 + maximum: 10 + type: integer defaultTimeouts: description: |- DefaultTimeouts contain the default Tekton timeouts to be used in case they are diff --git a/scripts/suggest_docs.py b/scripts/suggest_docs.py index 169de6284..e9919d287 100644 --- a/scripts/suggest_docs.py +++ b/scripts/suggest_docs.py @@ -14,6 +14,41 @@ def get_diff(): result = subprocess.run(["git", "diff", "origin/main...HEAD"], capture_output=True, text=True) return result.stdout.strip() +def get_commit_info(): + """Get commit information for the documentation PR reference""" + try: + # Get the HEAD commit - this is what GitHub Actions checked out for the PR + current_commit_result = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True, text=True) + if current_commit_result.returncode != 0: + return None + commit_hash = current_commit_result.stdout.strip() + + # Get remote origin URL to construct proper commit links + remote_url = subprocess.run(["git", "config", "--get", "remote.origin.url"], capture_output=True, text=True) + if remote_url.returncode != 0: + return None + + # Convert SSH URL to HTTPS if needed + repo_url = remote_url.stdout.strip() + if repo_url.startswith("git@github.com:"): + repo_url = repo_url.replace("git@github.com:", "https://github.com/").replace(".git", "") + elif repo_url.endswith(".git"): + repo_url = repo_url.replace(".git", "") + + # Get commit details + short_hash = commit_hash[:7] + + # Just get the current commit that triggered the pipeline + return { + 'repo_url': repo_url, + 'current_commit': commit_hash, + 'short_hash': short_hash + } + + except Exception as e: + print(f"Warning: Could not get commit info: {e}") + return None + def clone_docs_repo(): subprocess.run(["git", "clone", DOCS_REPO_URL, "docs_repo"]) os.chdir("docs_repo") @@ -133,11 +168,23 @@ def overwrite_file(file_path, new_content): print(f"Failed to write {file_path}: {e}") return False -def push_and_open_pr(modified_files): +def push_and_open_pr(modified_files, commit_info=None): subprocess.run(["git", "add"] + modified_files) + + # Build commit message with source commit references + commit_msg = "Auto-generated doc updates from code PR" + + if commit_info: + repo_name = commit_info['repo_url'].split('/')[-1] + commit_url = f"{commit_info['repo_url']}/commit/{commit_info['current_commit']}" + commit_msg += f"\n\nSource commit: {commit_info['short_hash']} from {repo_name}" + commit_msg += f"\nLink: {commit_url}" + + commit_msg += "\n\nAssisted-by: Gemini" + subprocess.run([ "git", "commit", - "-m", "Auto-generated doc updates from code PR\n\nAssisted-by: Gemini" + "-m", commit_msg ]) # Add remote with token auth gh_token = os.environ["GH_TOKEN"] @@ -146,11 +193,15 @@ def push_and_open_pr(modified_files): subprocess.run(["git", "remote", "set-url", "origin", docs_repo_url]) subprocess.run(["git", "push", "--set-upstream", "origin", BRANCH_NAME, "--force"]) + # Build PR body (simple, without commit references) + pr_body = "This PR updates the following documentation files based on code changes:\n\n" + pr_body += "\n".join([f"- `{f}`" for f in modified_files]) + pr_body += "\n\n*Note: Each commit in this PR contains references to the specific source code commits that triggered the documentation updates.*" + subprocess.run([ "gh", "pr", "create", "--title", "Auto-Generated Doc Updates from Code PR", - "--body", f"This PR updates the following documentation files based on the code changes:\n\n" + - "\n".join([f"- `{f}`" for f in modified_files]), + "--body", pr_body, "--base", "main", "--head", BRANCH_NAME ]) @@ -165,6 +216,12 @@ def main(): print("No changes detected.") return + # Get commit info before switching to docs repo + commit_info = get_commit_info() + if commit_info: + print(f"Source repository: {commit_info['repo_url']}") + print(f"Latest commit: {commit_info['short_hash']}") + clone_docs_repo() previews = get_file_previews() @@ -201,8 +258,24 @@ def main(): print("[Dry Run] Would push and open PR for the following files:") for f in modified_files: print(f"- {f}") + + if commit_info: + # Show what the commit message would look like + repo_name = commit_info['repo_url'].split('/')[-1] + commit_url = f"{commit_info['repo_url']}/commit/{commit_info['current_commit']}" + commit_msg = "Auto-generated doc updates from code PR" + commit_msg += f"\n\nSource commit: {commit_info['short_hash']} from {repo_name}" + commit_msg += f"\nLink: {commit_url}" + commit_msg += "\n\nAssisted-by: Gemini" + + print(f"\n[Dry Run] Commit message would be:") + print("=" * 50) + print(commit_msg) + print("=" * 50) + + print(f"\n[Dry Run] PR body would be simple (commit reference is in commit message only)") else: - push_and_open_pr(modified_files) + push_and_open_pr(modified_files, commit_info) else: print("All documentation is already up to date — no PR created.")