diff --git a/.cursor/commands/pr-review-prioritizer.md b/.cursor/commands/pr-review-prioritizer.md new file mode 100644 index 0000000000..2fbafb7411 --- /dev/null +++ b/.cursor/commands/pr-review-prioritizer.md @@ -0,0 +1,147 @@ +# PR Review Prioritizer LLM Prompt + +You are a PR prioritization assistant that helps determine which pull request should be reviewed next based on a systematic scoring framework. + +## Your Task + +1. **Fetch PR Data**: Use the GitHub CLI to gather information about open pull requests +2. **Apply Scoring Framework**: Calculate priority scores using the PR Prioritization Framework +3. **Recommend Next Review**: Output the highest-priority PR that needs review + +## Step 1: Gather PR Information + +Use the following GitHub CLI commands to collect PR data: + +```bash +# Get basic PR information +gh pr list --state open --json number,title,author,createdAt,updatedAt,additions,deletions,isDraft,labels,reviewRequests,,comments,reviews,mergeable,baseRefName --limit 30 + +``` + +## Step 2: Apply Scoring Framework + +For each PR, calculate scores based on these metrics: + +### Age Score (Weight: 25%) +- Calculate days since `createdAt` +- Score mapping: + - 0-1 days: 0-20 points + - 2-3 days: 20-50 points + - 4-7 days: 50-80 points + - 8+ days: 80-100 points + +### Size Score (Weight: 20%) +- Use `additions + deletions` for total lines changed +- Score mapping (inverse relationship): + - 1-50 lines: 80-100 points + - 51-200 lines: 60-79 points + - 201-500 lines: 40-59 points + - 501-1000 lines: 20-39 points + - 1000+ lines: 0-19 points + + +### Author Wait Time Score (Weight: 15%) +- Calculate hours since `updatedAt` (last author activity) +- Check if author has responded to recent reviews +- Score mapping: + - 0-2 hours: 90-100 points + - 2-8 hours: 70-89 points + - 8-24 hours: 40-69 points + - 1-2 days: 20-39 points + - 2+ days: 0-19 points + +### Change Type Score (Weight: 10%) +- Analyze labels and title for change type: + - **Critical** (100 points): "hotfix", "security", "incident" + - **High** (75 points): "bug", "blocking" + - **Medium** (50 points): "feature", "enhancement" + - **Low** (25 points): "refactor", "docs", "test" + - **Very Low** (10 points): "style", "typo" + +## Step 3: Calculate Final Score + +``` +Total Score = (Age × 0.25) + (Size × 0.20) + (Wait Time × 0.15) + (Change Type × 0.10) +``` + +## Step 4: Apply Special Rules + +### Hotfix Override +- If labels contain "hotfix" or title contains "[HOTFIX]": Set score to 100 + +### Draft PR Exclusion +- Skip PRs where `isDraft: true` unless specifically requested +- Skip PRs where status is draft or WIP + +### Closed PR Exclusion +- Exclude closed PRs from the list entirely + +### Conflicting PR Exclusion +- Exclude PRs that need rebasing AND have conflicting changes (mergeable: "CONFLICTING") +- These PRs cannot be reviewed until conflicts are resolved + +### Stale PR Handling +- If age > 14 days: Flag for author ping, but still calculate score +- Include stale label in status column when present + +## Step 5: Output Format + +Provide output in this format: + +``` +## 🎯 Next PR to Review + +**PR #123: Fix critical authentication bug** +- **Priority**: 🔴 Critical (Score: 87.5) +- **Author**: @username +- **Age**: 3 days +- **Size**: 45 lines +- **Link**: https://github.com/owner/repo/pull/123 + +### Score Breakdown: +- Age Score: 50 × 0.25 = 12.5 +- Size Score: 85 × 0.20 = 17.0 +- Dependency Score: 75 × 0.30 = 22.5 +- Wait Time Score: 90 × 0.15 = 13.5 +- Change Type Score: 75 × 0.10 = 7.5 +- **Total**: 87.5 + +### Why This PR: +- Blocks 2 other PRs +- Author recently responded to feedback +- Bug fix affecting user authentication +- Manageable size for quick review + +--- + +## 📋 All PRs by Priority + +| PR | Title | Priority | Score | Age | Size | Author | Status | +|----|-------|----------|-------|-----|------|--------|--------| +| [#123](https://github.com/owner/repo/pull/123) | Fix auth bug | 🔴 Critical | 87.5 | 3d | 45 | @user1 | Ready for review | +| [#124](https://github.com/owner/repo/pull/124) | Add new feature | 🟡 Medium | 45.2 | 1d | 200 | @user2 | Needs approval | +| [#125](https://github.com/owner/repo/pull/125) | Update docs | 🟢 Low | 23.1 | 5d | 20 | @user3 | Needs rebase (Stale) | +``` + +### Special Rules for Status Column: +- Include both status and staleness in the same column +- For example: "Needs review", "Approved", "Changes requested", "Needs rebase" +- When stale label is present, append "(Stale)" to the status +- Exclude closed PRs from the list entirely +- Exclude draft PRs (isDraft: true) unless specifically requested +- Exclude PRs with conflicting changes that need rebasing + +### Excluded PRs Section: +- Include a section listing excluded PRs with clickable links +- Format: `- **[#123](https://github.com/owner/repo/pull/123)**: Title - Reason for exclusion` +- Group exclusions by reason (Conflicting/Rebase Issues, Draft PRs, etc.) + +### PR Table Sorting: +- Sort PRs by score in descending order (highest score first) +- For PRs with the same score, sort by priority in descending order (Critical > High > Medium > Low) +- This ensures the most important PRs appear at the top of the table + +## Notes + +- Use this as a guide, not absolute rule - context matters +- Do not implement the framework, just provide the output in the format specified diff --git a/.cursor/rules/add_extension_metadata.mdc b/.cursor/rules/add_extension_metadata.mdc new file mode 100644 index 0000000000..89f364d24e --- /dev/null +++ b/.cursor/rules/add_extension_metadata.mdc @@ -0,0 +1,235 @@ +--- +description: AI-guided workflow for adding dynamic plugin metadata to the RHDH Extensions Catalog +globs: catalog-entities/marketplace/**,docs/dynamic-plugins/** +alwaysApply: false +--- +# RHDH Extensions Catalog - Plugin Metadata Workflow + +This cursor rule provides an automated workflow for adding dynamic plugin metadata to the RHDH Extensions Catalog. + +## Important Documentation + +**Primary Reference**: Read `catalog-entities/marketplace/README.md` for: +- Detailed YAML structure and field explanations +- Complete examples (3scale plugin) +- RHDH-local testing setup +- Troubleshooting guide + +This rule focuses on the **workflow automation** and **validation** aspects not covered in the README. + +## Prerequisites + +Before starting, ensure you have: + +1. **Successfully exported plugin** from [RHDH Plugin Export Overlays](https://github.com/redhat-developer/rhdh-plugin-export-overlays) + - OCI URL from build output (e.g., `oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/aws-ecs:pr_1426__0.6.0!aws-ecs`) + - Plugin version and integrity information + +2. **Required tools installed**: + ```bash + # Check if tools are installed + command -v yq &> /dev/null || echo "❌ Install yq (Go version): brew install yq (macOS) or snap install yq (Linux)" + command -v ajv &> /dev/null || echo "❌ Install ajv-cli: npm install -g ajv-cli" + command -v gh &> /dev/null || echo "❌ Install GitHub CLI: brew install gh (macOS)" + ``` + + **Important**: Ensure you have the **Go-based version of yq** (mikefarah/yq), not the Python version (kislyuk/yq). + Verify with: `yq --version` (should show "mikefarah/yq") + +## Interactive Information Gathering + +When adding a plugin, gather the following information: + +### Required Information +1. **Plugin Identification** + - Plugin name (e.g., `aws-ecs`, `todo`) + - NPM package name (e.g., `@aws/amazon-ecs-plugin-for-backstage`) + - Namespace (e.g., `rhdh` for Red Hat maintained, `community` for community plugins) + +2. **Technical Details** + - OCI URL from overlay build + - Plugin version + - Backstage version compatibility + - Role: `frontend-plugin` or `backend-plugin` + +3. **User-Facing Information** + - Title and short description (2-3 lines for tile view) + - Long description (markdown, for expanded view) + - Category (one of: AI, Analytics, CI/CD, Cloud, Compliance, Cost, Developer Tools, Docs, Feature Flags, Kubernetes, Monitoring, Productivity, Reporting, Search, Security, Storage, Supply Chain, Testing) + - Tags (lowercase, kebab-case) + - Support level: `production`, `tech-preview`, or `dev-preview` + +4. **Links** + - Homepage/documentation URL + - Source code repository + - Bug tracker URL + +## Workflow Steps + +### Step 1: Create Feature Branch + +```bash +# Ensure we're on latest main +git fetch origin && git checkout main && git pull origin main + +# Create feature branch +git checkout -b add-{plugin-name}-plugin-metadata +``` + +### Step 2: Tool Verification + +```bash +# Verify required tools +for tool in yq ajv gh; do + command -v $tool &> /dev/null && echo "✓ $tool installed" || echo "❌ $tool missing" +done + +# Verify yq is the Go version +yq --version | grep -q "mikefarah" && echo "✓ yq is Go version (mikefarah/yq)" || echo "❌ Wrong yq version - install mikefarah/yq" +``` + +### Step 3: Generate Package Metadata + +For plugins from the overlay repository, use the marketplace CLI: + +```bash +# Generate package metadata from dynamic-plugins.default.yaml +npx --yes @red-hat-developer-hub/marketplace-cli generate \ + --namespace rhdh \ + -p dynamic-plugins.default.yaml \ + -o catalog-entities/marketplace/packages + +# For external plugins, create manually using examples in README +``` + +### Step 4: Create/Edit Plugin Metadata + +Create `catalog-entities/marketplace/plugins/{plugin-name}.yaml`: +- Use `catalog-entities/marketplace/plugins/3scale.yaml` as a template +- See README for complete field descriptions + +### Step 5: Update Index Files + +**Important**: Add entries in **alphabetical order**! + +Use the AI agent's editing capabilities to: +1. Add `- ./{plugin-name}.yaml` to `catalog-entities/marketplace/packages/all.yaml` in alphabetical order +2. Add `- ./{plugin-name}.yaml` to `catalog-entities/marketplace/plugins/all.yaml` in alphabetical order + +The AI agent will automatically determine the correct alphabetical position and insert the entries accordingly. + +### Step 6: Validate Files + +```bash +# Navigate to marketplace directory +cd catalog-entities/marketplace + +# Download schemas to temp directory (ajv doesn't support remote schemas well) +mkdir -p /tmp/rhdh-schemas +curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/marketplace/json-schema/packages.json" \ + -o /tmp/rhdh-schemas/packages.json +curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/marketplace/json-schema/plugins.json" \ + -o /tmp/rhdh-schemas/plugins.json + +# Convert YAML to JSON and validate Package against local schema +echo "Validating packages/{plugin-name}.yaml..." +yq eval packages/{plugin-name}.yaml -o json > /tmp/rhdh-schemas/package-temp.json +ajv validate -s /tmp/rhdh-schemas/packages.json -d /tmp/rhdh-schemas/package-temp.json + +# Convert YAML to JSON and validate Plugin against local schema +echo "Validating plugins/{plugin-name}.yaml..." +yq eval plugins/{plugin-name}.yaml -o json > /tmp/rhdh-schemas/plugin-temp.json +ajv validate -s /tmp/rhdh-schemas/plugins.json -d /tmp/rhdh-schemas/plugin-temp.json + +# Clean up temp files +rm /tmp/rhdh-schemas/package-temp.json /tmp/rhdh-schemas/plugin-temp.json +``` + +**Note**: This uses the Go-based `yq` syntax (`yq eval file.yaml -o json`). If validation fails, check that you have the correct yq version installed. + +### Step 7: Test Locally (Optional) + +Follow the RHDH-local testing instructions in the README: +1. Clone `rhdh-local` repository +2. Mount your local catalog in `compose.yaml` +3. Set `catalog.processingInterval: { seconds: 15 }` in `app-config.yaml` +4. Start with `docker compose up -d` +5. Check http://localhost:7007 → Catalog → Extensions + +### Step 8: Create Pull Request + +```bash +# Stage changes +git add catalog-entities/marketplace/packages/{plugin-name}.yaml +git add catalog-entities/marketplace/plugins/{plugin-name}.yaml +git add catalog-entities/marketplace/packages/all.yaml +git add catalog-entities/marketplace/plugins/all.yaml + +# Commit with descriptive message +git commit -m "feat: add {plugin-name} plugin to RHDH marketplace + +- Added Package entity with OCI URL and version +- Added Plugin entity with description and metadata +- Updated all.yaml indexes in alphabetical order" + +# Create PR +gh pr create --title "feat: add {plugin-name} plugin to marketplace" \ + --body "## Summary +- Added {plugin-name} plugin metadata to Extensions Catalog +- Package: \`{npm-package-name}\` version {version} +- Support level: {support-level} + +## Checklist +- [ ] Package and Plugin YAML files created +- [ ] Schemas validate successfully +- [ ] Added to all.yaml files alphabetically +- [ ] Tested locally with rhdh-local (if applicable)" +``` + +## Validation Checklist + +Before submitting: +- [ ] Tools installed (`yq` Go version, `ajv-cli`, `gh`) +- [ ] Package YAML validates against schema +- [ ] Plugin YAML validates against schema +- [ ] Both added to `all.yaml` files in **alphabetical order** +- [ ] Namespace consistent between Package and Plugin +- [ ] OCI URL correctly formatted +- [ ] All required fields populated + +## Common Issues + +### Schema Validation Fails +```bash +# Debug by checking JSON conversion (using Go-based yq) +yq eval your-file.yaml -o json | jq '.' + +# Common issues: +# - Missing required fields +# - Wrong field types +# - Invalid enum values (e.g., wrong category) +``` + +### Wrong yq Version +```bash +# Check if you have the Go version +yq --version + +# Should show: yq (https://github.com/mikefarah/yq/) version X.X.X + +# If you have the Python version (kislyuk/yq), uninstall and install Go version: +# macOS: brew install mikefarah/yq/yq +# Linux: snap install yq +``` + +### OCI URL Format +Correct format: `oci://registry/path:tag!package-name` +- Must include `!package-name` suffix +- Tag typically includes PR number and version + +## References + +- [README with detailed documentation](../../catalog-entities/marketplace/README.md) +- [Extension Schemas](https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/marketplace/json-schema) +- [RHDH Local Testing](https://github.com/redhat-developer/rhdh-local) +- [Dynamic Plugins Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) diff --git a/.cursor/rules/ci-e2e-testing.mdc b/.cursor/rules/ci-e2e-testing.mdc new file mode 100644 index 0000000000..d1e8156f2a --- /dev/null +++ b/.cursor/rules/ci-e2e-testing.mdc @@ -0,0 +1,503 @@ +--- +description: E2E/CI context of RHDH to assist the agent in testing and pipeline tasks. +globs: .ibm/**,e2e-tests/**,docs/e2e-tests/** +alwaysApply: false +--- +# RHDH (Red Hat Developer Hub) Repository Context + +This document serves as a comprehensive starting point for LLMs working with the RHDH repository. It provides detailed information about the e2e-tests, testing infrastructure and CI/CD pipeline. + +## Table of Contents + +- [E2E Testing Framework](#e2e-testing-framework) +- [CI/CD Infrastructure](#cicd-infrastructure) +- [Key Dependencies and Common Issues](#key-dependencies-and-common-issues) +- [Documentation References](#documentation-references) + +## E2E Testing Framework + +### Technology Stack +- **Testing Framework**: Playwright with TypeScript +- **Node.js Version**: 22 +- **Package Manager**: Yarn 3.8.7 +- **Test Runner**: Playwright Test +- **Reporting**: HTML, JUnit XML, List reporters + +Current versions for e2e-tests are defined in `e2e-tests/package.json` + +### Test Structure and Organization + +#### Directory Structure +```text +e2e-tests/ +├── playwright/ +│ ├── e2e/ # Main test files +│ │ └── *.spec.ts # General test files +│ ├── utils/ # Test utilities +│ ├── data/ # Test data +│ └── support/ # Test support files +``` + +#### Test File Requirements + +**Component Assignment**: Every test file (`*.spec.ts`) in the `e2e-tests` folder must have a component assigned in the `test.beforeAll` hook using the following syntax: + +```typescript +test.beforeAll(async ({ }, testInfo) => { + testInfo.annotations.push({ + type: "component", + description: "your_value", + }); +}); +``` + +**Purpose**: This component annotation is used for test categorization, reporting, and CI/CD pipeline organization. It helps identify which component or feature area each test file is validating. + +**Examples of Component Values**: +- `"authentication"` - for authentication provider tests +- `"rbac"` - for role-based access control tests +- `"plugins"` - for plugin functionality tests +- `"configuration"` - for configuration validation tests +- `"audit-log"` - for audit logging tests +- `"core"` - for core functionality tests +- `"navigation"` - for navigation and routing tests +- `"api"` - for API endpoint and integration tests +- `"integration"` - for external service integration tests +- `"monitoring"` - for monitoring and observability tests +- `"data-management"` - for data handling and management tests + +**Note**: The component description should be descriptive and consistent across related test files to ensure proper test organization and reporting. + +#### Key Test Categories + +1. **Smoke Tests** (`smoke-test.spec.ts`) + - Basic functionality verification + - Health checks and core features + +2. **Showcase Tests** (defined in `playwright.config.ts`) + - `showcase`: General functionality tests with base deployment using Helm chart + - `showcase-rbac`: General functionality tests with RBAC-enabled deployment using Helm chart + - `showcase-k8s`: Kubernetes integration tests with base deployment + - `showcase-rbac-k8s`: Kubernetes integration tests with RBAC-enabled deployment + - `showcase-operator`: General functionality tests with base deployment using Operator + - `showcase-operator-rbac`: General functionality tests with RBAC-enabled deployment using Operator + - `showcase-runtime`: Runtime environment tests + - `showcase-sanity-plugins`: Plugin sanity checks + - `showcase-upgrade`: Upgrade scenario tests + - `any-test`: Use for debugging when you need to run a specific tests + +3. **Authentication Provider Tests** (`showcase-auth-providers`) + - OIDC (Red Hat Backstage Keycloak) + - Microsoft OAuth2 + - GitHub authentication + - LDAP (Active Directory) + +4. **Plugin Tests** (`playwright/e2e/plugins/`) + - RBAC (Role-Based Access Control) + - Kubernetes actions + - Notifications + - Topology + - Quay integration + - Tekton + - Dynamic plugins info + - Adoption insights + - Analytics + +5. **Configuration Tests** (`playwright/e2e/configuration-test/`) + - Config map validation + - Environment-specific configurations + +6. **Audit Log Tests** (`playwright/e2e/audit-log/`) + - Audit logging functionality + - Compliance verification + +### Test Execution Scripts + +Available yarn scripts in `e2e-tests/package.json`: + +```bash +# Showcase tests - OpenShift deployments +yarn showcase # General showcase tests +yarn showcase-ci-nightly # General showcase tests (nightly CI alias) +yarn showcase-rbac # General showcase tests with RBAC +yarn showcase-rbac-nightly # General showcase tests with RBAC (nightly CI alias) + +# Showcase tests - Kubernetes deployments +yarn showcase-k8s-ci-nightly # Kubernetes showcase tests +yarn showcase-rbac-k8s-ci-nightly # Kubernetes showcase tests with RBAC + +# Showcase tests - Operator deployments +yarn showcase-operator-nightly # Operator showcase tests +yarn showcase-operator-rbac-nightly # Operator showcase tests with RBAC + +# Showcase tests - Other scenarios +yarn showcase-runtime # Runtime configuration tests +yarn showcase-upgrade-nightly # Upgrade scenario tests + +# Authentication provider tests +yarn showcase-auth-providers # Auth provider tests + +# Plugin tests +yarn showcase-sanity-plugins # Plugin sanity tests + +# Utility scripts +yarn lint:check # Lint checking +yarn lint:fix # Lint fixing +yarn tsc # TypeScript compilation +yarn prettier:check # Prettier checking +yarn prettier:fix # Prettier fixing +``` + +### Environment Variables + +All the important environment variables are sourced in `.ibm/pipelines/env_variables.sh` +Most of them are populated by secrets from the Vault. + +⚠️ Important Notice +Do not place any secrets directly into a file. +All sensitive information must be stored in the Vault. + +### Test Configuration + +Playwright configuration (`e2e-tests/playwright.config.ts`): +- **Timeout**: 90 seconds global, 10-15 seconds for actions +- **Retries**: 2 on CI, 0 locally +- **Workers**: 3 parallel workers +- **Viewport**: 1920x1080 +- **Video**: Enabled for all tests +- **Screenshots**: Only on failure +- **Trace**: Retain on failure + +### Key Differences: showcase-auth-providers vs Other Showcase Projects + +The `showcase-auth-providers` project has several significant differences from other showcase projects, particularly in deployment and configuration: + +#### **Namespace and Release Management** +- **Other Showcase Projects**: Use standard namespace patterns (`showcase-ci-nightly`, `showcase-rbac-nightly`) +- **showcase-auth-providers**: Uses dedicated namespace `showcase-auth-providers` and release `rhdh-auth-providers` +- **Logging**: Dedicated logs folder: `e2e-tests/auth-providers-logs` + +#### **Test Retry Configuration** +- **Other Showcase Projects**: Typically use 2 retries (CI default) +- **showcase-auth-providers**: Configured with only 1 retry due to the complexity of authentication provider setup and teardown + +#### **Configuration and Deployment Approach** +- **Other Showcase Projects**: Use Bash scripts for configuration and deployment +- **showcase-auth-providers**: Uses TypeScript for configuration and deployment management +- **Configuration Files**: Uses different configuration files compared to other showcase projects: + - `e2e-tests/playwright/e2e/auth-providers/` directory structure with TypeScript test files + - Dedicated values file: `.ibm/pipelines/value_files/values_showcase-auth-providers.yaml` + - TypeScript-based test configuration instead of Bash scripts + - Dynamic RHDH instance management (create, update, restart, delete) + +#### **Required Plugins and Dependencies** +- **Other Showcase Projects**: Standard plugin dependencies +- **showcase-auth-providers**: Requires specific plugins exported to `dynamic-plugins-root`: + - `backstage-community-plugin-catalog-backend-module-keycloak-dynamic` + - `backstage-plugin-catalog-backend-module-github-org-dynamic` + - `backstage-plugin-catalog-backend-module-msgraph-dynamic` + - `backstage-community-plugin-rbac` + +#### **Authentication Provider Coverage** +- **Other Showcase Projects**: Standard authentication testing +- **showcase-auth-providers**: Tests multiple authentication providers: + - OIDC using Red Hat Backstage Keycloak (RHBK) + - Microsoft OAuth2 provider + - GitHub authentication + - LDAP using Active Directory (commented out) + +#### **Test Structure and Files** +- **Other Showcase Projects**: Standard test file patterns +- **showcase-auth-providers**: Dedicated test structure: + - `e2e-tests/playwright/e2e/auth-providers/` directory + - Individual test files: `oidc.spec.ts`, `microsoft.spec.ts`, `github.spec.ts`, `ldap.spec.ts` + - Tests verify: supported resolvers, user/group ingestion, nested groups, session token configuration + +These differences make `showcase-auth-providers` a specialized testing environment focused on validating authentication provider integrations rather than general RHDH functionality testing. + +## CI/CD Infrastructure + +### OpenShift CI Overview + +The RHDH CI/CD pipeline uses **OpenShift CI** with **Prow-based** automation and **ephemeral clusters** for testing. + +Check the readme at `.ibm/pipelines/README.md` + +#### Key Components + +1. **Ephemeral Clusters**: AWS-based clusters in `us-east-2` region +2. **Cluster Management**: Managed via cluster claims +3. **CI Job Types**: OCP, EKS, GKE, AKS environments +4. **Authentication**: Keycloak as default provider +5. **Secrets Management**: Vault-managed secrets + +### Cluster Pools + +Available cluster pools for different OCP versions: + +- **RHDH-4-19-US-EAST-2** + - Usage: OCP v4.19 nightly jobs + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-19-0-amd64-aws-us-east-2_clusterpool.yaml) + +- **RHDH-4-18-US-EAST-2** + - Usage: OCP v4.18 nightly jobs + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-18-0-amd64-aws-us-east-2_clusterpool.yaml) + +- **RHDH-4-17-US-EAST-2** + - Usage: PR checks on main branch and OCP v4.17 nightly jobs + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-17-0-amd64-aws-us-east-2_clusterpool.yaml) + +- **RHDH-4-16-US-EAST-2** + - Usage: OCP v4.16 nightly jobs + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-16-0-amd64-aws-us-east-2_clusterpool.yaml) + +**Note:** This is subject to change. Use `.ibm/pipelines/README.md` as a source of truth. + +### CI Job Types + +#### Pull Request Tests +- **Trigger**: Automatic for code changes, manual with `/ok-to-test` +- **Environment**: Ephemeral OpenShift cluster +- **Scope**: Both RBAC and non-RBAC namespaces +- **Artifacts**: 6-month retention period + +#### Nightly Tests +- **Schedule**: Automated nightly runs +- **Environments**: Multiple OCP versions, AKS, GKE +- **Reporting**: Slack notifications to `#rhdh-e2e-test-alerts` + +### Test Execution Environment + +#### Local Development +Tests are run directly using Playwright Test with Node.js 22 and Yarn 3.8.7 as specified in the technology stack above. + +#### CI/CD Pipeline Execution +For CI/CD pipeline execution, tests run in a containerized environment using the image `.ibm/images/Dockerfile`. This image is based on `mcr.microsoft.com/playwright` and uses Ubuntu as the base operating system. + +**Note**: Any additional system dependencies required for testing must be installed in this Docker image to ensure CI/CD pipeline compatibility. + +#### Alternative Execution Methods +**Podman Usage**: If you need to prepare the environment or run tests close to how CI/CD pipeline runs them, you can use Podman to run the `.ibm/pipelines/openshift-ci-tests.sh` script inside the Docker image. + +**RHEL/Fedora Systems**: On Playwright unsupported systems such as RHEL or Fedora, running tests inside the containerized environment using Podman is the recommended approach to avoid compatibility issues. + +### Key CI Scripts + +#### Main Orchestration +- **`.ibm/pipelines/openshift-ci-tests.sh`**: Main test orchestration script +- **`.ibm/pipelines/utils.sh`**: Utility functions +- **`.ibm/pipelines/reporting.sh`**: Reporting and notifications +- **`.ibm/pipelines/env_variables.sh`**: Environment variable management + +#### CI Infrastructure Package Configuration + +The `.ibm/package.json` file defines the CI infrastructure package configuration and development tools: + +**Available Scripts:** +```bash +# Code quality and linting +yarn shellcheck # Shell script linting with severity warnings +yarn prettier:check # Check formatting for shell, markdown, and YAML files +yarn prettier:fix # Fix formatting for shell, markdown, and YAML files +``` + +⚠️ **Important**: Before using any of these scripts, you must first run `yarn install` in the `.ibm` folder to install the required dependencies (prettier, prettier-plugin-sh, shellcheck). + +**Purpose**: This package provides essential tooling for maintaining code quality in the CI infrastructure, ensuring consistent formatting and shell script best practices across the pipeline scripts. + +#### Job Handlers +The main script handles different job types: +- `handle_aks_helm`: AKS Helm deployment +- `handle_eks_helm`: EKS Helm deployment +- `handle_gke_helm`: GKE Helm deployment +- `handle_ocp_operator`: OCP Operator deployment +- `handle_ocp_nightly`: OCP nightly tests +- `handle_ocp_pull`: OCP PR tests +- `handle_auth_providers`: Auth provider tests + +#### Special Case: showcase-auth-providers Deployment + +The `showcase-auth-providers` project has a unique deployment workflow that differs significantly from other showcase projects: + +**Handler**: `handle_auth_providers()` function in `.ibm/pipelines/jobs/auth-providers.sh` +**Configuration**: Uses dedicated values file `values_showcase-auth-providers.yaml` with auth provider-specific settings +**Test Execution**: Runs TypeScript-based tests from `e2e-tests/playwright/e2e/auth-providers/` directory + +### Access and Debugging + +#### Cluster Access +For cluster pool admins, use the login script: +```bash +.ibm/pipelines/ocp-cluster-claim-login.sh +``` + +#### Debugging Process +1. Run the login script +2. Provide Prow log URL when prompted +3. Script will forward cluster web console URL and credentials +4. Ephemeral clusters are deleted after CI job termination + +### CI Configuration Files + +- **Job Definitions**: [OpenShift Release Jobs](https://github.com/openshift/release/tree/master/ci-operator/jobs/redhat-developer/rhdh) +- **Configuration**: [OpenShift Release Config](https://github.com/openshift/release/tree/master/ci-operator/config/redhat-developer/rhdh) +- **Step Registry**: [OpenShift Release Steps](https://github.com/openshift/release/tree/master/ci-operator/step-registry/redhat-developer/rhdh) + +### Debugging + +#### Local Debugging +```bash +# Set local development flags +export ISRUNNINGLOCAL=true +export ISRUNNINGLOCALDEBUG=true + +# Run tests locally +npx playwright test --project showcase-auth-providers --workers 1 +``` + +#### CI Debugging +1. **Access Logs**: Check PR artifacts or CI logs +2. **Cluster Access**: Use cluster claim login script +3. **Environment Variables**: Verify required variables +4. **Test Failures**: Review test reports and screenshots + +#### Common Debugging Tools +- **Playwright Inspector**: `npx playwright test --debug` +- **Trace Viewer**: `npx playwright show-trace` +- **Screenshots**: Automatic on failure +- **Video Recording**: Available for all tests + +## Key Dependencies and Common Issues + +### System Dependencies + +#### macOS Requirements +**Important**: macOS users need to use GNU `grep` and GNU `sed` instead of the built-in BSD versions to avoid compatibility issues with scripts and CI/CD pipelines. + +Install using Homebrew: +```bash +brew install grep +brew install gnu-sed +``` + +**Important**: Make sure to set the GNU versions as default to ensure they are used instead of the built-in macOS versions. + +**Note**: The built-in macOS versions of these tools may cause issues when running scripts or tests that expect GNU-compatible behavior. + +### External Services + +#### Required Services +- **GitHub**: Authentication, repository access +- **Keycloak**: Default authentication provider +- **OpenShift**: Primary deployment platform +- **Advanced Cluster Management**: For OCM plugins + +### Internal Components + +#### Core Components +- **Backstage**: Main application framework +- **Dynamic Plugins**: Plugin management system +- **Catalog**: Entity management +- **Scaffolder**: Template system + +### Common Issues and Solutions + +#### Test Failures +1. **Environment Issues**: Verify environment variables +2. **Authentication Problems**: Check credentials and tokens +3. **Resource Constraints**: Check cluster resources + +#### CI Failures +1. **Cluster Issues**: Verify cluster availability +2. **Resource Limits**: Check resource quotas +3. **Network Problems**: Verify connectivity +4. **Configuration Errors**: Review job configuration + +#### Plugin Issues +1. **Loading Failures**: Check plugin configuration +2. **Dependency Conflicts**: Verify package versions +3. **Configuration Errors**: Review plugin config +4. **Build Issues**: Check build process + +## Documentation References + +### Core Documentation +- [E2E Testing CI Documentation](docs/e2e-tests/CI.md) +- [Dynamic Plugins Documentation](docs/dynamic-plugins/index.md) +- [Authentication Providers README](e2e-tests/playwright/e2e/auth-providers/README.md) +- [OpenShift CI Pipeline README](.ibm/pipelines/README.md) + +### Configuration Files +- [Playwright Configuration](e2e-tests/playwright.config.ts) +- [Package Configuration](e2e-tests/package.json) +- [Dynamic Plugins Config](dynamic-plugins/package.json) +- [CI Test Script](.ibm/pipelines/openshift-ci-tests.sh) + +### External Resources +- [OpenShift CI Documentation](https://docs.ci.openshift.org/) +- [Playwright Documentation](https://playwright.dev/) +- [Red Hat Developer Hub Documentation](https://redhat-developer.github.io/red-hat-developers-documentation-rhdh/main/) +- [Backstage Documentation](https://backstage.io/docs) +- [Dynamic Plugins Guide](https://github.com/backstage/backstage/tree/master/packages/backend-dynamic-feature-service) + +### Key Scripts and Tools +- [Cluster Login Script](.ibm/pipelines/ocp-cluster-claim-login.sh) +- [Test Reporting Script](.ibm/pipelines/reporting.sh) +- [Environment Variables](.ibm/pipelines/env_variables.sh) +- [Dynamic Plugin Installer](docker/install-dynamic-plugins.py) + +## Test Configuration Files (Config Maps) + +### Overview + +The RHDH e2e testing infrastructure uses two main configuration files located in `.ibm/pipelines/resources/config_map/`: + +1. **`app-config-rhdh.yaml`** - Non-RBAC configuration +2. **`app-config-rhdh-rbac.yaml`** - RBAC-enabled configuration + +### Config Map Usage Pattern + +The choice of config map depends on the **Playwright test project** being executed, as defined in `e2e-tests/playwright.config.ts`: + +#### **app-config-rhdh.yaml** (Non-RBAC Configuration) + +**Used for test projects that exclude RBAC testing:** + +- `smoke-test` - Basic smoke tests +- `showcase` - General functionality tests (explicitly excludes RBAC tests) +- `showcase-k8s` - Kubernetes integration tests (explicitly excludes RBAC tests) +- `showcase-operator` - Operator-based tests (explicitly excludes RBAC tests) +- `showcase-runtime` - Runtime environment tests +- `showcase-sanity-plugins` - Plugin sanity tests +- `showcase-upgrade` - Upgrade scenario tests +- `showcase-auth-providers` - Authentication provider tests (uses special deployment process) + +#### **app-config-rhdh-rbac.yaml** (RBAC Configuration) + +**Used for test projects that include RBAC testing:** + +- `showcase-rbac` - RBAC-specific tests +- `showcase-rbac-k8s` - Kubernetes + RBAC tests +- `showcase-operator-rbac` - Operator + RBAC tests + +### **CRITICAL RULE: Config Map Selection** + +**When adding new tests:** + +1. **Identify the test project scope:** + - Will the new test/plugin be tested with RBAC? → Use `app-config-rhdh-rbac.yaml` + - Will the new test/plugin be tested without RBAC? → Use `app-config-rhdh.yaml` + +2. **Check the Playwright project configuration:** + - Projects that exclude RBAC tests (using `testIgnore` for RBAC patterns) → Use `app-config-rhdh.yaml` + - Projects that include RBAC tests (using `testMatch` for RBAC patterns) → Use `app-config-rhdh-rbac.yaml` + +### **Special Cases** + +1. **showcase-auth-providers**: Although it uses the non-RBAC config pattern, it has its own specialized deployment process with dedicated values file (`values_showcase-auth-providers.yaml`) and TypeScript-based configuration management. + +### **Configuration Deployment Process** + +The config maps are deployed as Kubernetes ConfigMaps during CI/CD pipeline execution and are mounted into the RHDH pods to provide runtime configuration. The pipeline selects the appropriate config map based on the test project being executed. + +--- diff --git a/.dockerignore b/.dockerignore index becc48cdc0..5a96daab39 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,7 +4,6 @@ **/node_modules plugins !plugins/auth-backend-module-oidc-provider -!plugins/dynamic-plugins-info !plugins/dynamic-plugins-info-backend !plugins/licensed-users-info-backend !plugins/scalprum-backend @@ -15,3 +14,4 @@ examples .ibm/images/* !.ibm/images/Dockerfile !.yarnrc.yml +hermeto-cache \ No newline at end of file diff --git a/.github/actions/check-author/action.yaml b/.github/actions/check-author/action.yaml new file mode 100644 index 0000000000..9715940f82 --- /dev/null +++ b/.github/actions/check-author/action.yaml @@ -0,0 +1,53 @@ +name: "Check Author" +description: "Checks if the author is an active member of the specified team in the specified organization" + +inputs: + author: + description: "The author to check" + required: true + organization: + description: "The organization to check" + required: true + team: + description: "The team to check in the organization" + required: true + gh_token: + description: "GitHub token with permissions to read organization and team membership" + required: true + +outputs: + is_active_member: + description: "Whether the specified author is an active member of the specified team" + value: ${{ steps.check.outputs.is_active_member }} + +runs: + using: "composite" + steps: + + - name: Check if author is an active team member + id: check + shell: bash + env: + GH_TOKEN: ${{ inputs.gh_token }} + run: | + echo "Checking if ${{ inputs.author }} is an active member of ${{ inputs.team }} team in ${{ inputs.organization }}..." + + # Use the memberships endpoint to get specific membership info + if response=$(gh api "/orgs/${{ inputs.organization }}/teams/${{ inputs.team }}/memberships/${{ inputs.author }}" 2>/dev/null); then + state=$(echo "$response" | jq -r '.state') + + if [[ "$state" == "active" ]]; then + echo "✓ Author ${{ inputs.author }} is an active member of the ${{ inputs.team }} team" + echo "is_active_member=true" >> $GITHUB_OUTPUT + elif [[ "$state" == "pending" ]]; then + echo "⚠️ Author ${{ inputs.author }} has a pending invitation to the ${{ inputs.team }} team (not active)" + echo "is_active_member=false" >> $GITHUB_OUTPUT + else + echo "✗ Author ${{ inputs.author }} has unexpected membership state: $state" + echo "is_active_member=false" >> $GITHUB_OUTPUT + fi + else + # API call failed (user not in team) + echo "✗ Author ${{ inputs.author }} is not a member of the ${{ inputs.team }} team" + echo "is_active_member=false" >> $GITHUB_OUTPUT + fi diff --git a/.github/actions/docker-build/action.yaml b/.github/actions/docker-build/action.yaml index 4af8408a32..e798de413e 100644 --- a/.github/actions/docker-build/action.yaml +++ b/.github/actions/docker-build/action.yaml @@ -20,10 +20,10 @@ inputs: required: true password: description: The password to use for the registry - required: true + required: false username: description: The username to use for the registry - required: true + required: false imageName: description: The name of the image to build required: true @@ -34,18 +34,30 @@ inputs: description: The labels for the Docker image required: false push: - description: Whether to push the image + description: Whether to push the image (automatically ignored and assumed to be false if enableHermeticBuild is true) required: true platform: description: "Target given CPU platform architecture (default: linux/amd64)" required: false default: linux/amd64 + enableHermeticBuild: + description: Whether to enable hermetic builds using hermeto (currently only supported for linux/amd64) + required: false + default: 'false' + componentDirectory: + description: Path to the component directory for hermetic builds + required: false + default: '.' + dockerfilePath: + description: Path to the Dockerfile to use + required: false + default: 'docker/Dockerfile' outputs: digest: + description: The digest of the built Docker image value: ${{ steps.build.outputs.digest }} - runs: using: composite steps: @@ -63,18 +75,22 @@ runs: - name: Set up QEMU uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + # - name: Install qemu dependency + # shell: bash + # run: | + # set -ex + # sudo apt-get update + # sudo apt-get install -y qemu-user-static - - name: Log in to the Container registry - if: ${{ inputs.push }} + - name: Login to Registry + if: ${{ inputs.push == 'true' && inputs.enableHermeticBuild != 'true' }} uses: docker/login-action@v3 with: registry: ${{ inputs.registry }} username: ${{ inputs.username }} password: ${{ inputs.password }} - - name: Extract metadata (tags, labels) for Docker + - name: Extract metadata (tags, labels, annotations) for Docker id: meta uses: docker/metadata-action@v5 with: @@ -84,14 +100,152 @@ runs: labels: | ${{ inputs.imageLabels }} - - name: Build and push Docker image + # Hermetic Build Steps + - name: Set up hermetic build variables + if: ${{ inputs.enableHermeticBuild == 'true' }} + shell: bash + run: | + echo "HERMETO_IMAGE=quay.io/konflux-ci/hermeto:latest" >> $GITHUB_ENV + echo "LOCAL_CACHE_DIR=./hermeto-cache/$(basename ${{ inputs.componentDirectory }})" >> $GITHUB_ENV + echo "COMPONENT_ABS_DIR=${{ github.workspace }}/${{ inputs.componentDirectory }}" >> $GITHUB_ENV + + - name: Cache dependencies with hermeto + if: ${{ inputs.enableHermeticBuild == 'true' }} + shell: bash + run: | + set -ex + + echo "=== Creating local cache directory ===" + mkdir -p ${{ env.LOCAL_CACHE_DIR }} || echo "Failed to create local cache directory" + + echo "=== Fetching dependencies with hermeto ===" + # Build hermeto cache for rpm, yarn, and pip (currently does not support ARM64 due to quay.io/konflux-ci/hermeto:latest not having an arm64 image) + podman run --rm -v "$PWD:/source:z" -v "$LOCAL_CACHE_DIR:/cachi2:z" -w /source "$HERMETO_IMAGE" \ + --log-level DEBUG \ + fetch-deps --dev-package-managers \ + --source . \ + --output /cachi2/output \ + '[{"type": "rpm", "path": "."}, {"type": "yarn","path": "."}, {"type": "yarn","path": "./dynamic-plugins"}, {"type": "pip","path": "./python", "allow_binary": "false"}]' || echo "Fetch-deps failed" + + if [ -d ${{ env.LOCAL_CACHE_DIR }}/output ]; then + echo "=== Output directory exists, running generate-env ===" + + # Generate environment file + podman run --rm -v "$PWD:/source:z" -v "$LOCAL_CACHE_DIR:/cachi2:z" -w /source "$HERMETO_IMAGE" \ + --log-level DEBUG \ + generate-env --format env \ + --output /cachi2/cachi2.env /cachi2/output + + else + echo "No output directory found, skipping generate-env" + exit 1 + fi + + if [ -d ${{ env.LOCAL_CACHE_DIR }}/output ]; then + echo "=== Running inject-files ===" + + podman run --rm -v "$PWD:/source:z" -v "$LOCAL_CACHE_DIR:/cachi2:z" -w /source "$HERMETO_IMAGE" \ + --log-level DEBUG \ + inject-files /cachi2/output || echo "Inject-files failed" + + else + echo "No output directory found, skipping inject-files" + exit 1 + fi + + echo LOCAL_CACHE_DIR_REALPATH=$(realpath "${{ env.LOCAL_CACHE_DIR }}") >> $GITHUB_ENV + + - name: "Fix Cache Ownership for Non-Root Buildah" + if: ${{ inputs.enableHermeticBuild == 'true' }} + shell: bash + run: | + set -ex + echo "=== Before ownership fix ===" + ls -l ${{ env.LOCAL_CACHE_DIR_REALPATH }} + echo "=== Attempting to fix ownership to runner user ===" + sudo chown -R runner ${{ env.LOCAL_CACHE_DIR_REALPATH }} + echo "=== After ownership fix ===" + ls -l ${{ env.LOCAL_CACHE_DIR_REALPATH }} + + - name: Transform Containerfile for hermetic build + if: ${{ inputs.enableHermeticBuild == 'true' }} + shell: bash + run: | + set -x + + CONTAINERFILE_PATH="${{ inputs.dockerfilePath }}" + + TRANSFORMED_CONTAINERFILE="${CONTAINERFILE_PATH}.hermeto" + + # Copy original dockerfile for hermetic build modifications + cp "$CONTAINERFILE_PATH" "$TRANSFORMED_CONTAINERFILE" + + # Transform the dockerfile to simulate Konflux build + # Configure dnf to use the cachi2 repo + sed -i '/RUN *\(dnf\|microdnf\) install/i RUN rm -r /etc/yum.repos.d/* && cp /cachi2/output/deps/rpm/x86_64/repos.d/hermeto.repo /etc/yum.repos.d/' "$TRANSFORMED_CONTAINERFILE" + + # Inject the cachi2 env variables to every RUN command + sed -i 's/^\s*RUN /RUN . \/cachi2\/cachi2.env \&\& /' "$TRANSFORMED_CONTAINERFILE" + + echo "TRANSFORMED_CONTAINERFILE=$TRANSFORMED_CONTAINERFILE" >> $GITHUB_ENV + + - name: Build and push Docker image (Standard) + if: ${{ inputs.enableHermeticBuild != 'true' }} uses: docker/build-push-action@v6 id: build with: context: . - file: docker/Dockerfile + file: ${{ inputs.dockerfilePath }} push: ${{ inputs.push }} provenance: false tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + annotations: ${{ steps.meta.outputs.annotations }} platforms: ${{ inputs.platform }} + + - name: "Build Docker Image (Hermetic)" + id: hermetic-build + if: ${{ inputs.enableHermeticBuild == 'true' }} + uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2.13 + with: + containerfiles: ${{ inputs.dockerfilePath }}.hermeto + context: . + platform: ${{ inputs.platform }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + extra-args: | + --network=none + --volume ${{ env.LOCAL_CACHE_DIR_REALPATH }}:/cachi2:z + + - name: Set build output for hermetic builds + if: ${{ inputs.enableHermeticBuild == 'true' }} + shell: bash + run: | + echo "digest=${{ steps.hermetic-build.outputs.digest || 'no-digest-available' }}" >> $GITHUB_OUTPUT + + - name: Save image as artifact (Hermetic) + if: ${{ inputs.enableHermeticBuild == 'true' }} + shell: bash + run: | + mkdir -p ./rhdh-podman-artifacts + + # Extract the built image tags from the metadata + TAGS_LIST="${{ steps.meta.outputs.tags }}" + + # Save all the built images to tar (podman save can handle multiple tags) + echo "Saving images with tags:" + echo "$TAGS_LIST" + + podman save $TAGS_LIST -o ./rhdh-podman-artifacts/image.tar + + # Save metadata for the push workflow + echo "$TAGS_LIST" > ./rhdh-podman-artifacts/tags.txt + + - name: Upload image artifact + if: ${{ inputs.enableHermeticBuild == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: podman-image-${{ github.event.number || 'main' }}-${{ env.SHORT_SHA }} + path: ./rhdh-podman-artifacts/ + retention-days: 1 + if-no-files-found: error \ No newline at end of file diff --git a/.github/renovate.json b/.github/renovate.json index f919b104b7..581866e96d 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -21,6 +21,7 @@ "major": { "dependencyDashboardApproval": true }, + "reviewers": ["team:rhdh-security-new"], "packageRules": [ { "matchCategories": [ @@ -49,9 +50,13 @@ "patch", "minor" ], + "matchFileNames": [ + ".rhdh/docker/Dockerfile", + "docker/Dockerfile" + ], "additionalBranchPrefix": "dockerfile ", - "groupName": "Dockerfile images (non-major)", - "automerge": false + "groupName": "Dockerfile images (non-major) [skip-build]", + "automerge": true }, { "description": "Test Dockerfile non-major updates", diff --git a/.github/workflows/bash-e2e-lint.yaml b/.github/workflows/bash-e2e-lint.yaml new file mode 100644 index 0000000000..d50fc4133a --- /dev/null +++ b/.github/workflows/bash-e2e-lint.yaml @@ -0,0 +1,35 @@ +name: E2E Bash + +on: + pull_request: + branches: + - "main" + - "release-*" + paths: + - '.ibm/**' + +jobs: + lint: + name: ShellCheck and Prettier + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + + - name: Install dependencies + working-directory: ./.ibm + run: yarn install + + - name: Run ShellCheck check + working-directory: ./.ibm + run: yarn shellcheck + + - name: Run Prettier check + working-directory: ./.ibm + run: yarn prettier:check diff --git a/.github/workflows/e2e-tests-lint.yaml b/.github/workflows/e2e-tests-lint.yaml new file mode 100644 index 0000000000..7282fafa70 --- /dev/null +++ b/.github/workflows/e2e-tests-lint.yaml @@ -0,0 +1,46 @@ +name: E2E Tests + +on: + pull_request: + paths: + - 'e2e-tests/**' + push: + branches: + - "main" + - "release-*" + paths: + - 'e2e-tests/**' + +jobs: + lint: + name: TSC, ESLint and Prettier + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + + - name: Install dependencies root + working-directory: . + run: yarn install + + - name: Install dependencies e2e-tests + working-directory: ./e2e-tests + run: yarn install --mode=skip-build + + - name: Run TypeScript Compiler check + working-directory: ./e2e-tests + run: yarn tsc:check + + - name: Run ESLint check + working-directory: ./e2e-tests + run: yarn lint:check + + - name: Run Prettier check + working-directory: ./e2e-tests + run: yarn prettier:check diff --git a/.github/workflows/link-checker.yaml b/.github/workflows/link-checker.yaml index 35b346b7c0..2726677c44 100644 --- a/.github/workflows/link-checker.yaml +++ b/.github/workflows/link-checker.yaml @@ -14,14 +14,13 @@ jobs: - uses: actions/checkout@v2 - name: Check markdown links in docs - uses: gaurav-nelson/github-action-markdown-link-check@v1 + uses: tcort/github-action-markdown-link-check@v1 with: config-file: '.github/workflows/link-checker.config.json' folder-path: 'docs/' - ignore: "https://code.visualstudio.com/docs/nodejs/nodejs-debugging" # Ignores known false positives - name: Check markdown files in root - uses: gaurav-nelson/github-action-markdown-link-check@v1 + uses: tcort/github-action-markdown-link-check@v1 with: config-file: '.github/workflows/link-checker.config.json' # ignore subfolders we don't want to check everthing, there is a lot of files from plugins that we don't control diff --git a/.github/workflows/next-build-image.yaml b/.github/workflows/next-build-image.yaml index 59dfb8d574..1a9d363480 100644 --- a/.github/workflows/next-build-image.yaml +++ b/.github/workflows/next-build-image.yaml @@ -27,6 +27,8 @@ on: tags: - '[0-9]+.[0-9]+.[0-9]+' - '[0-9]+.[0-9]+' + branches: + - 'release-**' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -39,6 +41,8 @@ env: jobs: build-image: name: Build Image + env: + HAS_QUAY_AUTH: ${{ secrets.QUAY_USERNAME != '' && secrets.QUAY_TOKEN != '' }} strategy: fail-fast: false matrix: @@ -71,24 +75,54 @@ jobs: ref_name=${{ github.ref_name }} if [ "$ref_name" == "main" ]; then ref_name="next" + elif [[ "$ref_name" =~ ^release-([0-9]+)\.([0-9]+) ]]; then + # next-1.y + ref_name="next-${BASH_REMATCH[1]}.${BASH_REMATCH[2]}" fi - # from 1.6.1 => 1.6 - ref_name_short="${ref_name%.*}" - if [[ $ref_name_short == "1" ]]; then - ref_name_short="${ref_name}" + ref_name_short="${ref_name}" + + # for releases only + if [[ $ref_name != "next" ]] && [[ $ref_name != "next-"* ]]; then + # shorten from 1.6.1 => 1.6 + ref_name_short="${ref_name%.*}" + if [[ $ref_name_short == "1" ]]; then ref_name_short="${ref_name}"; fi fi + echo "REF_NAME=$ref_name" >> $GITHUB_ENV echo "REF_NAME_SHORT=${ref_name_short}" >> $GITHUB_ENV echo "PLATFORM=$platform" >> $GITHUB_ENV echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV echo "PLATFORM_ARCH=${platform#*/}" >> $GITHUB_ENV + # compute expiry once and reuse + if [[ "$ref_name_short" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then + expires_after="183d" # Long expiry for official releases (1.2, 1.2.3, etc.) + else + expires_after="14d" # Short expiry for next builds, feature branches, and other temporary builds + fi + echo "EXPIRES_AFTER=$expires_after" >> $GITHUB_ENV + + - name: Check Quay credentials + run: | + if [ "${{ env.HAS_QUAY_AUTH }}" != "true" ]; then + echo "::error::Missing QUAY_USERNAME or QUAY_TOKEN secrets" + exit 1 + fi + echo "✓ Quay credentials are available" + + - name: Login to Quay + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_TOKEN }} + - name: Get the last commit short SHA uses: ./.github/actions/get-sha - name: Build and Push with Buildx uses: ./.github/actions/docker-build - id: build + id: build-image with: registry: ${{ env.REGISTRY }} username: ${{ secrets.QUAY_USERNAME }} @@ -97,14 +131,17 @@ jobs: imageTags: | type=raw,value=${{ env.REF_NAME }}-${{ env.PLATFORM_ARCH }} type=raw,value=${{ env.REF_NAME }}-${{ env.SHORT_SHA }}-${{ env.PLATFORM_ARCH }} - imageLabels: quay.expires-after=14d + imageLabels: | + quay.expires-after=${{ env.EXPIRES_AFTER }} + org.opencontainers.image.expires=${{ env.EXPIRES_AFTER }} push: true platform: ${{ env.PLATFORM }} - name: Export digest + id: export-digest run: | mkdir -p /tmp/digests - digest="${{ steps.build.outputs.digest }}" + digest="${{ steps.build-image.outputs.digest }}" touch "/tmp/digests/${digest#sha256:}" - name: Upload digest @@ -119,21 +156,37 @@ jobs: runs-on: ubuntu-latest needs: - build-image + env: + HAS_QUAY_AUTH: ${{ secrets.QUAY_USERNAME != '' && secrets.QUAY_TOKEN != '' }} steps: - name: Prepare run: | ref_name=${{ github.ref_name }} if [ "$ref_name" == "main" ]; then ref_name="next" + elif [[ "$ref_name" =~ ^release-([0-9]+)\.([0-9]+) ]]; then + # next-1.y + ref_name="next-${BASH_REMATCH[1]}.${BASH_REMATCH[2]}" fi - # from 1.6.1 => 1.6 - ref_name_short="${ref_name%.*}" - if [[ $ref_name_short == "1" ]]; then - ref_name_short="${ref_name}" + ref_name_short="${ref_name}" + + # for releases only + if [[ $ref_name != "next" ]] && [[ $ref_name != "next-"* ]]; then + # shorten from 1.6.1 => 1.6 + ref_name_short="${ref_name%.*}" + if [[ $ref_name_short == "1" ]]; then ref_name_short="${ref_name}"; fi fi echo "REF_NAME=$ref_name" >> $GITHUB_ENV echo "REF_NAME_SHORT=${ref_name_short}" >> $GITHUB_ENV + # compute expiry once and reuse + if [[ "$ref_name_short" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then + expires_after="183d" # Long expiry for official releases (1.2, 1.2.3, etc.) + else + expires_after="14d" # Short expiry for next builds, feature branches, and other temporary builds + fi + echo "EXPIRES_AFTER=$expires_after" >> $GITHUB_ENV + - name: Checkout uses: actions/checkout@v4 with: @@ -152,19 +205,22 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Set container metadata (for :next builds) + - name: Set container metadata (for :next builds, 14d expiry) id: meta-next - if: ${{ env.REF_NAME_SHORT == 'next'}} + if: ${{ env.REF_NAME_SHORT == 'next' || startsWith(env.REF_NAME_SHORT,'next-') }} uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }} tags: | type=raw,value=${{ env.REF_NAME }} type=raw,value=${{ env.REF_NAME }}-${{ env.SHORT_SHA }} + labels: | + quay.expires-after=${{ env.EXPIRES_AFTER }} + org.opencontainers.image.expires=${{ env.EXPIRES_AFTER }} - - name: Set container metadata (for releases) + - name: Set container metadata (for releases, 183d expiry) id: meta-release - if: ${{ env.REF_NAME_SHORT != 'next' }} + if: ${{ env.REF_NAME_SHORT != 'next' && !startsWith(env.REF_NAME_SHORT,'next-') }} uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }} @@ -173,6 +229,9 @@ jobs: type=raw,value=${{ env.REF_NAME }}-${{ env.SHORT_SHA }} type=raw,value=${{ env.REF_NAME_SHORT }} type=raw,value=${{ env.REF_NAME_SHORT }}-${{ env.SHORT_SHA }} + labels: | + quay.expires-after=${{ env.EXPIRES_AFTER }} + org.opencontainers.image.expires=${{ env.EXPIRES_AFTER }} - name: Login to Docker Hub uses: docker/login-action@v3 @@ -184,17 +243,263 @@ jobs: - name: Create manifest list and push working-directory: /tmp/digests run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) + # Read tags from the metadata JSON of the step that ran + meta='${{ steps.meta-release.outputs.json }}' + if [ -z "$meta" ] || [ "$meta" = "null" ]; then + meta='${{ steps.meta-next.outputs.json }}' + fi + + # Create and annotate the manifest list for EACH tag to ensure Quay applies expiry per tag + echo "$meta" | jq -r '.tags | unique[]' | while IFS= read -r tag; do + [ -z "$tag" ] && continue + docker buildx imagetools create \ + --annotation "quay.expires-after=${EXPIRES_AFTER}" \ + -t "$tag" \ + $(printf '${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) + done - name: Inspect image (for :next builds) id: inspect-next - if: ${{ env.REF_NAME_SHORT == 'next'}} + if: ${{ env.REF_NAME_SHORT == 'next' || startsWith(env.REF_NAME_SHORT,'next-') }} run: | docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}:${{ steps.meta-next.outputs.version }} - name: Inspect image (for releases) id: inspect-release - if: ${{ env.REF_NAME_SHORT != 'next'}} + if: ${{ env.REF_NAME_SHORT != 'next' && !startsWith(env.REF_NAME_SHORT,'next-') }} run: | docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}:${{ steps.meta-release.outputs.version }} + + - name: Wait for manifest propagation + if: env.HAS_QUAY_AUTH == 'true' + run: | + echo "Waiting for Quay to propagate multi-arch manifests..." + + # Determine which metadata step ran to get the primary tag + if [ "${{ env.REF_NAME_SHORT }}" == "next" ] || [[ "${{ env.REF_NAME_SHORT }}" == "next-"* ]]; then + primary_tag="${{ env.REF_NAME }}" + else + primary_tag="${{ env.REF_NAME }}" + fi + + # Retry loop to check manifest availability + max_attempts=12 # 12 * 5s = 60s maximum wait + attempt=1 + + while [ $attempt -le $max_attempts ]; do + echo "Checking manifest availability (attempt $attempt/$max_attempts)..." + + if docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}:${primary_tag} >/dev/null 2>&1; then + echo "✓ Multi-arch manifest is available after $((($attempt - 1) * 5)) seconds" + break + fi + + if [ $attempt -eq $max_attempts ]; then + echo "::warning::Manifest still not available after 60 seconds, proceeding anyway" + break + fi + + echo "Manifest not ready yet, waiting 5 seconds..." + sleep 5 + attempt=$((attempt + 1)) + done + + echo "Propagation check completed" + + - name: Manage expiry and cleanup per-arch images + if: env.HAS_QUAY_AUTH == 'true' + env: + REGISTRY_IMAGE: ${{ env.REGISTRY_IMAGE }} + REF_NAME: ${{ env.REF_NAME }} + REF_NAME_SHORT: ${{ env.REF_NAME_SHORT }} + SHORT_SHA: ${{ env.SHORT_SHA }} + EXPIRES_AFTER: ${{ env.EXPIRES_AFTER }} + QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }} + QUAY_TOKEN: ${{ secrets.QUAY_TOKEN }} + QUAY_OAUTH_TOKEN: ${{ secrets.QUAY_OAUTH_TOKEN }} + run: | + set -e + echo "Set multi-arch image expiry and remove single-arch images..." + + # Sanitize REF_NAME for use in tags (replace '/' with '-') + SAFE_REF_TAG="${REF_NAME//\//-}" + + # Calculate expiry timestamp and days + expires="${EXPIRES_AFTER}" + days="${expires%d}" + if [[ "$expires" != *d ]] || ! [[ "$days" =~ ^[0-9]+$ ]]; then + echo "::warning::Unknown EXPIRES_AFTER format: $EXPIRES_AFTER; defaulting to 14d" + days=14 + fi + expiry_ts=$(date -d "+${days} days" +%s) + echo "Using expiry: ${days} days (timestamp: ${expiry_ts})" + + # Define our tags based on build type + multi_arch_tags=( + "${SAFE_REF_TAG}" + "${SAFE_REF_TAG}-${SHORT_SHA}" + ) + + # For releases, add the additional short tags + if [[ "${REF_NAME_SHORT}" != "next" ]] && [[ "${REF_NAME_SHORT}" != "next-"* ]]; then + SAFE_REF_TAG_SHORT="${REF_NAME_SHORT//\//-}" + multi_arch_tags+=( + "${SAFE_REF_TAG_SHORT}" + "${SAFE_REF_TAG_SHORT}-${SHORT_SHA}" + ) + fi + + per_arch_tags=( + "${SAFE_REF_TAG}-amd64" + "${SAFE_REF_TAG}-arm64" + "${SAFE_REF_TAG}-${SHORT_SHA}-amd64" + "${SAFE_REF_TAG}-${SHORT_SHA}-arm64" + ) + + # Check if OAuth token is available for API operations + if [ -n "${QUAY_OAUTH_TOKEN}" ]; then + echo "Using OAuth token for API-based expiry management and cleanup..." + + # Set environment variables for Python script BEFORE running it + export MULTI_ARCH_TAGS="${multi_arch_tags[*]}" + export PER_ARCH_TAGS="${per_arch_tags[*]}" + export days="${days}" + + # Install requests if not available + pip install requests > /dev/null 2>&1 || echo "requests already available" + + # Use Python script for API operations + python3 << 'EOF' + import requests + import os + import time + import sys + + def set_tag_expiry(base_url, namespace, repository, tag_name, expiry_days, oauth_token, max_retries=3): + """Set expiry on a tag using the Quay API with retry logic.""" + expiry_timestamp = int(time.time()) + (expiry_days * 24 * 60 * 60) + + url = f"{base_url}/repository/{namespace}/{repository}/tag/{tag_name}" + headers = {"Authorization": f"Bearer {oauth_token}", "Content-Type": "application/json"} + payload = {"expiration": expiry_timestamp} + + for attempt in range(max_retries): + try: + response = requests.put(url, headers=headers, json=payload) + + if response.status_code in [200, 201, 204]: + print(f"Set {expiry_days}-day expiry on {tag_name}") + return True + elif response.status_code == 400: + print(f"Tag {tag_name}: Bad request ({response.status_code}) - may already have expiry") + return False + elif response.status_code == 404 and attempt < max_retries - 1: + print(f"Tag {tag_name}: Not found yet (attempt {attempt + 1}/{max_retries}), retrying in 5s...") + time.sleep(5) + continue + else: + print(f"Tag {tag_name}: Expiry failed ({response.status_code}) - {response.text}") + return False + + except Exception as e: + if attempt < max_retries - 1: + print(f"Tag {tag_name}: Request failed (attempt {attempt + 1}/{max_retries}), retrying: {e}") + time.sleep(3) + continue + else: + print(f"Tag {tag_name}: Request failed after {max_retries} attempts - {e}") + return False + + return False + + def delete_tag(base_url, namespace, repository, tag_name, oauth_token): + """Delete a tag using the Quay API.""" + url = f"{base_url}/repository/{namespace}/{repository}/tag/{tag_name}" + headers = {"Authorization": f"Bearer {oauth_token}"} + + try: + response = requests.delete(url, headers=headers) + + if response.status_code == 204: + print(f"Deleted tag {tag_name}") + return True + elif response.status_code == 404: + print(f"Tag {tag_name}: Already deleted or doesn't exist") + return True + else: + print(f"Tag {tag_name}: Delete failed ({response.status_code}) - {response.text}") + return False + + except Exception as e: + print(f"Tag {tag_name}: Delete request failed - {e}") + return False + + def main(): + """Main function for expiry and cleanup.""" + + # Parse repository + repository = os.environ['REGISTRY_IMAGE'] + if '/' not in repository: + print(f"Error: Repository must be in format 'namespace/repository', got: {repository}") + sys.exit(1) + + namespace, repo_name = repository.split('/', 1) + base_url = "https://quay.io/api/v1" + oauth_token = os.environ['QUAY_OAUTH_TOKEN'] + expiry_days = int(os.environ.get('days', '14')) + + # Get tags from environment + multi_arch_tags = os.environ.get('MULTI_ARCH_TAGS', '').split() + per_arch_tags = os.environ.get('PER_ARCH_TAGS', '').split() + + print(f"Managing tags for {repository}") + print(f"Multi-arch tags: {multi_arch_tags}") + print(f"Per-arch tags to delete: {per_arch_tags}") + + # Step 1: Set expiry on multi-arch tags + print(f"\nSetting {expiry_days}-day expiry on multi-arch tags...") + for tag in multi_arch_tags: + if tag: # Skip empty strings + set_tag_expiry(base_url, namespace, repo_name, tag, expiry_days, oauth_token) + + # Step 2: Delete per-arch tags + print(f"\nDeleting per-arch tags...") + deleted_count = 0 + for tag in per_arch_tags: + if tag: # Skip empty strings + if delete_tag(base_url, namespace, repo_name, tag, oauth_token): + deleted_count += 1 + + print(f"\nSummary:") + print(f"Multi-arch tags with expiry: {len([t for t in multi_arch_tags if t])}") + print(f"Per-arch tags deleted: {deleted_count}/{len([t for t in per_arch_tags if t])}") + print(f"Lifecycle management completed using OAuth API") + + if __name__ == "__main__": + main() + EOF + + else + echo "No QUAY_OAUTH_TOKEN available - falling back to Docker BuildX annotations" + echo "Robot accounts cannot delete via API (Quay security limitation)" + + # Fallback: Use Docker BuildX for expiry annotations only + echo "Applying expiry annotations to multi-arch tags via Docker BuildX..." + for tag in "${multi_arch_tags[@]}"; do + echo "Re-annotating tag: ${tag}" + + if docker buildx imagetools create \ + --tag "${{ env.REGISTRY }}/${REGISTRY_IMAGE}:${tag}" \ + --annotation "quay.expires-after=${EXPIRES_AFTER}" \ + --annotation "org.opencontainers.image.expires=${EXPIRES_AFTER}" \ + "${{ env.REGISTRY }}/${REGISTRY_IMAGE}:${tag}"; then + echo "Expiry annotations applied to: ${tag}" + else + echo "::warning::Failed to re-annotate ${tag}" + fi + done + + echo "Per-arch images will be cleaned up via expiry (no immediate deletion possible with robot accounts)" + fi + + echo "Image lifecycle management completed" diff --git a/.github/workflows/pr-build-image.yaml b/.github/workflows/pr-build-image.yaml index d2fdd2025f..7e8c7edcd9 100644 --- a/.github/workflows/pr-build-image.yaml +++ b/.github/workflows/pr-build-image.yaml @@ -12,41 +12,45 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: PR Build Image +name: PR Build Image (Hermetic) on: - pull_request_target: - paths-ignore: - - 'docs/**' - + pull_request: concurrency: group: ${{ github.workflow }}-${{ github.event.number || github.event.pull_request.head.ref }} cancel-in-progress: true env: REGISTRY: quay.io + IMAGE_NAME: rhdh-community/rhdh jobs: build-image: name: Build Image runs-on: ubuntu-latest - permissions: - contents: read - packages: write - pull-requests: write steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Check Image and Relevant Changes id: check-image uses: ./.github/actions/check-image-and-changes + + - name: Store isSkipped status + run: | + mkdir -p ./rhdh-skip-artifacts + echo "${{ steps.check-image.outputs.is_skipped }}" > ./rhdh-skip-artifacts/isSkipped.txt + - name: Upload isSkipped status + uses: actions/upload-artifact@v4 + with: + name: pr-${{ github.event.number }}-${{ env.SHORT_SHA }}-isSkipped + path: ./rhdh-skip-artifacts/isSkipped.txt + retention-days: 1 + if-no-files-found: error - name: Debug outputs run: | echo "Image exists: ${{ steps.check-image.outputs.image_exists }}" @@ -65,30 +69,17 @@ jobs: echo "Updating PR with latest commits from ${{ github.event.pull_request.base.ref }} ..." git fetch base-origin ${{ github.event.pull_request.base.ref }} git merge --no-edit base-origin/${{ github.event.pull_request.base.ref }} - - - name: Build and Push with Buildx + - name: Build Image (Hermetic) if: ${{ steps.check-image.outputs.is_skipped != 'true' }} uses: ./.github/actions/docker-build with: registry: ${{ env.REGISTRY }} - username: ${{ secrets.QUAY_USERNAME }} - password: ${{ secrets.QUAY_TOKEN }} - imageName: rhdh-community/rhdh + imageName: ${{ env.IMAGE_NAME }} imageTags: | pr-${{ github.event.number }} pr-${{ github.event.number }}-${{ env.SHORT_SHA }} + enableHermeticBuild: true imageLabels: quay.expires-after=14d - push: true + push: false platform: linux/amd64 - - - name: Comment the image pull link - if: ${{ steps.check-image.outputs.is_skipped != 'true' }} - uses: actions/github-script@v7 - with: - script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: 'The image is available at:\n* [`quay.io/rhdh-community/rhdh:pr-${{ github.event.number }}`](https://quay.io/rhdh-community/rhdh:pr-${{ github.event.number }}) or\n* [`quay.io/rhdh-community/rhdh:pr-${{ github.event.number }}-${{ env.SHORT_SHA }}`](https://quay.io/rhdh-community/rhdh:pr-${{ github.event.number }}-${{ env.SHORT_SHA }})' - }) + dockerfilePath: .rhdh/docker/Dockerfile diff --git a/.github/workflows/pr-podman-push.yaml b/.github/workflows/pr-podman-push.yaml new file mode 100644 index 0000000000..64e72e56b1 --- /dev/null +++ b/.github/workflows/pr-podman-push.yaml @@ -0,0 +1,186 @@ +name: Podman PR Push + +on: + workflow_run: + workflows: + - 'PR Build Image (Hermetic)' + types: + - completed + +jobs: + podman-push: + name: Push Podman Image to Registry + runs-on: ubuntu-latest + if: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' }} + permissions: + contents: read + issues: write + pull-requests: write + + steps: + - name: Get PR number from workflow run + id: get-pr-info + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_TARGET_REPO: ${{ github.repository }} + # If the PR is from a fork, prefix it with `:`, otherwise only the PR branch name is relevant: + PR_BRANCH: |- + ${{ + (github.event.workflow_run.head_repository.owner.login != github.event.workflow_run.repository.owner.login) + && format('{0}:{1}', github.event.workflow_run.head_repository.owner.login, github.event.workflow_run.head_branch) + || github.event.workflow_run.head_branch + }} + + run: | + FULL_SHA="${{ github.event.workflow_run.head_sha }}" + SHORT_SHA=$(echo "$FULL_SHA" | cut -c1-8) + # Need to use gh cli instead of `events.workflow_run.pull_requests` because the latter doesn't work for PRs from forks + # Refer to https://github.com/orgs/community/discussions/25220 + PR_NUMBER=$(gh pr view --repo "${PR_TARGET_REPO}" "${PR_BRANCH}" --json number --jq '.number') + + if [ -n "$PR_NUMBER" ]; then + echo "Found PR number: $PR_NUMBER" + echo "PR branch: $PR_BRANCH" + echo "Artifact Name: container-image-pr-$PR_NUMBER-$SHORT_SHA" + + echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT + echo "short-sha=$SHORT_SHA" >> $GITHUB_OUTPUT + echo "artifact-name=container-image-pr-$PR_NUMBER-$SHORT_SHA" >> $GITHUB_OUTPUT + else + echo "Failed to determine PR number" + exit 1 + fi + - name: Determine artifact name + run: | + # For workflow_run, extract from the event context + BUILD_ID="${{ steps.get-pr-info.outputs.pr_number }}" + SHORT_SHA="${{ github.event.workflow_run.head_sha }}" + SHORT_SHA="${SHORT_SHA:0:8}" + + + echo "SHORT_SHA=$SHORT_SHA" >> $GITHUB_ENV + ARTIFACT_NAME="podman-image-${BUILD_ID}-${SHORT_SHA}" + echo "ARTIFACT_NAME=$ARTIFACT_NAME" >> $GITHUB_ENV + echo "SKIP_ARTIFACT_NAME=pr-${BUILD_ID}-${SHORT_SHA}-isSkipped" >> $GITHUB_ENV + echo "Using artifact name: $ARTIFACT_NAME" + echo "Using skip artifact name: $SKIP_ARTIFACT_NAME" + + - name: Download Skip Status Artifact + id: download-skip-status + uses: actions/download-artifact@v4 + with: + name: ${{ env.SKIP_ARTIFACT_NAME }} + path: ./rhdh-skip-artifacts + run-id: ${{ github.event.workflow_run.id || github.run_id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + continue-on-error: true + + - name: Check Skip Status + id: check-skip + run: | + if [ -f "./rhdh-skip-artifacts/isSkipped.txt" ]; then + IS_SKIPPED=$(cat ./rhdh-skip-artifacts/isSkipped.txt) + echo "Found skip status: $IS_SKIPPED" + echo "is_skipped=$IS_SKIPPED" >> $GITHUB_OUTPUT + else + echo "Skip status artifact not found, proceeding with push" + echo "is_skipped=false" >> $GITHUB_OUTPUT + fi + + - name: Download Image Artifacts + if: ${{ steps.check-skip.outputs.is_skipped != 'true' }} + uses: actions/download-artifact@v4 + with: + name: ${{ env.ARTIFACT_NAME }} + path: ./rhdh-podman-artifacts + run-id: ${{ github.event.workflow_run.id || github.run_id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Load and prepare image + if: ${{ steps.check-skip.outputs.is_skipped != 'true' }} + id: prepare + run: | + # Check if artifacts exist + if [ ! -f "./rhdh-podman-artifacts/image.tar" ]; then + echo "Error: image.tar not found in artifacts" + echo "This may make sense if the build was skipped" + exit 1 + fi + + # Load the image from tar file (contains all tags) + podman load -i ./rhdh-podman-artifacts/image.tar + + # Read metadata + TAGS_LIST=$(cat ./rhdh-podman-artifacts/tags.txt) + + echo "Loaded images:" + podman images + + echo "Full tags from metadata:" + echo "$TAGS_LIST" + + # Use a heredoc since TAGS_LIST contains newlines + echo "tags<> $GITHUB_OUTPUT + echo "$TAGS_LIST" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Push Images + if: ${{ steps.check-skip.outputs.is_skipped != 'true' }} + uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2.8 + with: + tags: ${{ steps.prepare.outputs.tags }} + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_TOKEN }} + + - name: Log skip status + if: ${{ steps.check-skip.outputs.is_skipped == 'true' }} + run: | + echo "🚫 Image Push Skipped" + echo "The container image push was skipped because the build was skipped" + echo "(either due to [skip-build] tag or no relevant changes with existing image)" + + - name: Comment the image pull link + if: ${{ steps.check-skip.outputs.is_skipped != 'true' }} + uses: actions/github-script@v7 + env: + PUSHED_TAGS: ${{ steps.prepare.outputs.tags }} + PR_NUMBER: ${{ steps.get-pr-info.outputs.pr_number }} + with: + script: | + const prNumber = process.env.PR_NUMBER; + const pushedTags = process.env.PUSHED_TAGS; + + if (!prNumber) { + console.log('No pull request number found'); + return; + } + + if (!pushedTags) { + console.log('No pushed tags found'); + return; + } + + const tags = pushedTags.trim().split('\n').filter(tag => tag.trim()); + + if (tags.length === 0) { + console.log('No valid tags found'); + return; + } + + console.log(`Found ${tags.length} tags:`, tags); + + const tagLinks = tags.map(fullTag => { + return `* [\`${fullTag}\`](https://${fullTag})`; + }).join('\n'); + + const body = `The image is available at:\n\n${tagLinks}\n\n`; + + console.log(`Creating comment for PR ${prNumber} with body:\n ${body}`); + + github.rest.issues.createComment({ + issue_number: parseInt(prNumber), + owner: context.repo.owner, + repo: context.repo.repo, + body: body + }) + diff --git a/.github/workflows/pr-semantic.yaml b/.github/workflows/pr-semantic.yaml index b9b88dcf4c..116f215b60 100644 --- a/.github/workflows/pr-semantic.yaml +++ b/.github/workflows/pr-semantic.yaml @@ -14,7 +14,7 @@ jobs: name: Conventional Commits runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5 + - uses: amannn/action-semantic-pull-request@e32d7e603df1aa1ba07e981f2a23455dee596825 # v5 id: lint_pr_title env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -49,7 +49,7 @@ jobs: # Note that a second check will be reported if this is enabled. wip: true - - uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2 + - uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2 # When the previous steps fails, the workflow would stop. By adding this # condition you can continue the execution with the populated error message. if: always() && (steps.lint_pr_title.outputs.error_message != null) @@ -68,7 +68,7 @@ jobs: # Delete a previous comment when the issue has been resolved - if: ${{ steps.lint_pr_title.outputs.error_message == null }} - uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2 + uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2 with: header: pr-title-lint-error delete: true diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index da344046f0..56f1ffc7a9 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -15,26 +15,80 @@ name: PR on: - pull_request: + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review] + branches: + - main + - release-1.[0-9]+ env: TURBO_SCM_BASE: ${{ github.event.pull_request.base.sha }} TURBO_SCM_HEAD: ${{ github.sha }} concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.event.number || github.event.pull_request.head.ref }} cancel-in-progress: true jobs: + check-commit-author: + # This job is used to check if the commit author is an active member of the rhdh team. + # It is used to determine if the PR should be run with the internal or external environment. + # The job is run on the main branch to ensure that the action is not tampered with. + runs-on: ubuntu-latest + outputs: + is_active_team_member: ${{ steps.team-check.outputs.is_active_member }} + steps: + - name: Generate GitHub App Token + id: app-token + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + with: + app-id: ${{ secrets.RHDH_GITHUB_APP_ID }} + private-key: ${{ secrets.RHDH_GITHUB_APP_PRIVATE_KEY }} + - name: Checkout main branch for secure version of check-author action + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 + with: + fetch-depth: 1 + ref: main # Always use main branch for security-critical action + persist-credentials: false + - name: Check if commit author is an active member of the team + id: team-check + uses: ./.github/actions/check-author + with: + author: ${{ github.actor }} + organization: redhat-developer + team: rhdh + gh_token: ${{ steps.app-token.outputs.token }} + + authorize: + # The 'external' environment is configured with the maintainers team as required reviewers. + # All the subsequent jobs in this workflow 'need' this job, which will require manual approval for PRs coming from external forks. + # Use 'internal' environment if the author is in the team OR if it's an internal PR (not from a fork) + # see list of approvers in OWNERS file + environment: + ${{ (needs.check-commit-author.outputs.is_active_team_member == 'true' || github.event.pull_request.head.repo.full_name == github.repository) && 'internal' || 'external' }} + runs-on: ubuntu-latest + needs: check-commit-author + steps: + - name: Check if internal PR + id: check + run: | + if [[ "${{ needs.check-commit-author.outputs.is_active_team_member }}" == "true" ]]; then + echo "✓ Commit author is in rhdh team - using internal environment" + elif [[ "${{ github.event.pull_request.head.repo.full_name }}" == "${{ github.repository }}" ]]; then + echo "✓ Internal PR (not from fork) - using internal environment" + else + echo "✓ External PR from fork from non-rhdh team member - using external environment for security" + fi build: name: Build with Node.js ${{ matrix.node-version }} runs-on: ubuntu-latest strategy: matrix: node-version: [22] + needs: authorize steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} @@ -74,9 +128,10 @@ jobs: strategy: matrix: node-version: [22] + needs: authorize steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} @@ -129,10 +184,18 @@ jobs: if: ${{ steps.check-image.outputs.is_skipped != 'true' }} run: yarn run test --continue --affected + - name: Change directory to dynamic-plugins + if: ${{ steps.check-image.outputs.is_skipped != 'true' }} + run: cd ./dynamic-plugins + - name: Install dynamic plugin dependencies if: ${{ steps.check-image.outputs.is_skipped != 'true' }} - run: cd ./dynamic-plugins && yarn install && cd .. + run: yarn install + + - name: Test the dynamic plugin wrappers + if: ${{ steps.check-image.outputs.is_skipped != 'true' }} + run: yarn test --continue --affected - - name: Verify dynamic plugin wrappers + - name: Export the dynamic plugin wrappers if: ${{ steps.check-image.outputs.is_skipped != 'true' }} - run: cd ./dynamic-plugins && yarn test && cd .. + run: yarn export-dynamic --continue --affected diff --git a/.github/workflows/renovate-checks.yaml b/.github/workflows/renovate-checks.yaml index 3c8a843876..8079103b63 100644 --- a/.github/workflows/renovate-checks.yaml +++ b/.github/workflows/renovate-checks.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest name: Renovate Config Validator steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - name: Validate config # See https://docs.renovatebot.com/config-validation/ run: | diff --git a/.github/workflows/toml-checks.yaml b/.github/workflows/toml-checks.yaml new file mode 100644 index 0000000000..047a979d9f --- /dev/null +++ b/.github/workflows/toml-checks.yaml @@ -0,0 +1,18 @@ +name: PR TOML Validator + +on: + push: + paths: + - '**.toml' + pull_request: + paths: + - '**.toml' + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: tombi-toml/setup-tombi@v1 + - name: Validate TOML files + run: tombi lint \ No newline at end of file diff --git a/.github/workflows/update-backstage.yaml b/.github/workflows/update-backstage.yaml index 72fe2748e7..5af297e144 100644 --- a/.github/workflows/update-backstage.yaml +++ b/.github/workflows/update-backstage.yaml @@ -50,7 +50,7 @@ jobs: private-key: ${{ secrets.RHDH_GITHUB_APP_PRIVATE_KEY }} - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: token: ${{ steps.generate-token.outputs.token }} diff --git a/.github/workflows/update-rpm-lockfile.yaml b/.github/workflows/update-rpm-lockfile.yaml new file mode 100644 index 0000000000..305adb5201 --- /dev/null +++ b/.github/workflows/update-rpm-lockfile.yaml @@ -0,0 +1,107 @@ +name: Update RPM Lockfile + +on: + workflow_dispatch: + schedule: + # Run at 3AM UTC every Monday + - cron: '0 3 * * 1' + push: + branches: + - main + - release-1.** + paths: + - 'rpms.in.yaml' + - '.rhdh/docker/Dockerfile' +permissions: + contents: write + pull-requests: write + +env: + DOCKERFILE_PATH: .rhdh/docker/Dockerfile +jobs: + update-lockfile: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # 4.3.0 + with: + fetch-depth: 0 + + - name: Check if hermetic Dockerfile exists + run: | + if [ ! -f "${{ env.DOCKERFILE_PATH }}" ]; then + echo "Error: ${{ env.DOCKERFILE_PATH }} not found!" + exit 1 + fi + - name: Configure Git + run: | + git config --global user.name "rhdh-bot" + git config --global user.email "rhdh-bot@redhat.com" + + - name: Install rpm-lockfile-prototype + run: | + if [[ ! -x "${HOME}/.local/bin/rpm-lockfile-prototype" ]]; then + echo "Installing rpm-lockfile-prototype ..." + + sudo apt-get update + sudo apt-get install -y python3 python3-pip python3-dev build-essential + sudo apt-get install -y podman skopeo rpm + sudo apt-get install -y dnf python3-dnf + + mkdir -p "${HOME}/.local/bin/" + python3 -m pip install --user https://github.com/konflux-ci/rpm-lockfile-prototype/archive/refs/heads/main.zip + + # Update PATH + export PATH=${PATH%":${HOME}/.local/bin"}:${HOME}/.local/bin + echo "${HOME}/.local/bin" >> $GITHUB_PATH + else + echo "rpm-lockfile-prototype already installed" + fi + - name: Run rpm-lockfile-prototype + run: | + echo "Running '${HOME}/.local/bin/rpm-lockfile-prototype -f ${{ env.DOCKERFILE_PATH }} rpms.in.yaml' in $(pwd)" + + ${HOME}/.local/bin/rpm-lockfile-prototype -f ${{ env.DOCKERFILE_PATH }} rpms.in.yaml + + - name: Check for lockfile changes + id: check-lockfile-changes + run: | + if git diff --quiet rpms.lock.yaml; then + echo "No changes to rpms.lock.yaml detected, skipping PR creation" + echo "changes=false" >> $GITHUB_OUTPUT + else + echo "Changes detected in rpms.lock.yaml, creating PR" + echo "changes=true" >> $GITHUB_OUTPUT + fi + + - name: Create Pull Request + id: create-pull-request + if: steps.check-lockfile-changes.outputs.changes == 'true' + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore: update rpms.lock.yaml" + title: "chore: update RPM lockfile" + body: | + ## Description + + This PR updates the `rpms.lock.yaml` file with the latest package versions based on current `rpms.in.yaml` configuration using `${{ env.DOCKERFILE_PATH }}` as the base container context + + This PR was automatically created by the [Update RPM Lockfile GitHub Action](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}). + branch: update-rpm-lockfile + delete-branch: true + draft: false + sign-commits: true + labels: | + lgtm + approved + add-paths: | + rpms.lock.yaml + + - name: Summary + run: | + if [ "${{ steps.check-lockfile-changes.outputs.changes }}" == "true" ]; then + echo "✅ RPM lockfile updated and created PR: ${{ steps.create-pull-request.outputs.pull-request-url }}" + else + echo "🚫 No changes detected in RPM lockfile" + fi diff --git a/.gitignore b/.gitignore index e079204493..08241712a3 100644 --- a/.gitignore +++ b/.gitignore @@ -49,7 +49,8 @@ site # vscode database functionality support files *.session.sql -.vscode +.vscode/* +!.vscode/extensions.json .turbo # Dynamic plugins root content @@ -63,3 +64,11 @@ dynamic-plugins-root/* # Private Keys *.pem + +# Local Cursor rules context +.cursor/rules/*.local.mdc + +# CI/Pipeline local overrides +.ibm/pipelines/shared_dir/* +.ibm/pipelines/artifact_dir/* +.ibm/pipelines/env_override.local.sh diff --git a/.ibm/.lintstagedrc.json b/.ibm/.lintstagedrc.json new file mode 100644 index 0000000000..de2b80b2a3 --- /dev/null +++ b/.ibm/.lintstagedrc.json @@ -0,0 +1,4 @@ +{ + "**/*.sh": ["shellcheck --severity=warning --color=always"], + "**/*.{sh,md,yaml,yml}": ["prettier --write"] +} diff --git a/.ibm/.prettierrc.js b/.ibm/.prettierrc.js new file mode 100644 index 0000000000..734e1db0c7 --- /dev/null +++ b/.ibm/.prettierrc.js @@ -0,0 +1,49 @@ +// @ts-check + +/** @type {import("prettier").Config} */ +module.exports = { + plugins: ['prettier-plugin-sh'], + overrides: [ + { + files: '*.sh', + options: { + parser: 'sh', + // Shell script specific formatting options + keepComments: true, + indent: 2, + endOfLine: 'lf', + }, + }, + { + files: '*.md', + options: { + parser: 'markdown', + // Markdown specific formatting options + tabWidth: 2, + useTabs: false, + proseWrap: 'always', + endOfLine: 'lf', + }, + }, + { + files: '*.{yaml,yml}', + options: { + parser: 'yaml', + // YAML specific formatting options + tabWidth: 2, + useTabs: false, + endOfLine: 'lf', + }, + }, + ], + // General Prettier options + printWidth: 100, + tabWidth: 2, + useTabs: false, + semi: true, + trailingComma: 'es5', + bracketSpacing: true, + bracketSameLine: false, + arrowParens: 'avoid', + endOfLine: 'lf', +}; diff --git a/.ibm/images/Dockerfile b/.ibm/images/Dockerfile index e2ce39d242..de9f2ed071 100644 --- a/.ibm/images/Dockerfile +++ b/.ibm/images/Dockerfile @@ -1,6 +1,6 @@ # Base image from Microsoft Playwright # Must stay pinned to a version which includes Nodejs 22 -FROM mcr.microsoft.com/playwright:v1.53.1-jammy +FROM mcr.microsoft.com/playwright:v1.56.0-jammy # Set environment variables for the container ENV CI=1 \ @@ -8,7 +8,7 @@ ENV CI=1 \ _X11_NO_MITSHM=1 \ _MITSHM=0 \ NODE_PATH=/usr/local/lib/node_modules \ - HELM_VERSION="v3.12.3" \ + HELM_VERSION="v3.17.2" \ OC_VERSION="4.14.3" \ OCM_VERSION="0.1.76" \ GO_VERSION="1.19" \ @@ -38,7 +38,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ openssl libssl-dev ca-certificates \ apache2-utils \ gettext \ - curl wget jq colorized-logs && \ + curl wget jq colorized-logs \ + unzip dnsutils && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ echo "Node: $(node -v)\nNPM: $(npm -v)\nYarn: $(yarn -v)\nTypeScript: $(tsc -v)" @@ -73,6 +74,11 @@ RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages. apt-get install google-cloud-cli google-cloud-sdk-gke-gcloud-auth-plugin -y && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +# Install AWS CLI +RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \ + unzip awscliv2.zip && \ + ./aws/install + # Install skopeo RUN apt-get update -y && \ apt-get install -y skopeo diff --git a/.ibm/manual-tests/postgres/README.md b/.ibm/manual-tests/postgres/README.md index 1725ec1323..ca0d231ab8 100644 --- a/.ibm/manual-tests/postgres/README.md +++ b/.ibm/manual-tests/postgres/README.md @@ -2,12 +2,15 @@ ## Reference Document -Please refer to the [project documentation](https://docs.google.com/document/d/1OUA5uhsZN0KhUSAln_ohvBRg3hyVx3wyYyddUB-fjlQ/edit#heading=h.hg9hpw7e08uo) and -[documentation link](https://github.com/janus-idp/operator/pull/368) for detailed information and guidelines. +Please refer to the +[project documentation](https://docs.google.com/document/d/1OUA5uhsZN0KhUSAln_ohvBRg3hyVx3wyYyddUB-fjlQ/edit#heading=h.hg9hpw7e08uo) +and [documentation link](https://github.com/janus-idp/operator/pull/368) for detailed information +and guidelines. ## Database Setup -You can use either Azure Database for PostgreSQL - Flexible Server or Amazon RDS for PostgreSQL for this project. Please follow the respective setup guides: +You can use either Azure Database for PostgreSQL - Flexible Server or Amazon RDS for PostgreSQL for +this project. Please follow the respective setup guides: - [Azure Database for PostgreSQL - Flexible Server](https://learn.microsoft.com/en-gb/azure/postgresql/flexible-server/overview) - [Amazon RDS for PostgreSQL](https://aws.amazon.com/rds/postgresql/) @@ -16,7 +19,8 @@ You can use either Azure Database for PostgreSQL - Flexible Server or Amazon RDS ### Database Connection -Define the values for the database connection in the `postgress-cred-secret.yaml` file. Here is a template: +Define the values for the database connection in the `postgress-cred-secret.yaml` file. Here is a +template: ```yaml apiVersion: v1 @@ -25,13 +29,14 @@ metadata: name: postgress-cred-secret type: Opaque data: - POSTGRES_PASSWORD: '' - POSTGRES_PORT: '' - POSTGRES_USER: '' - POSTGRES_HOST: '' + POSTGRES_PASSWORD: "" + POSTGRES_PORT: "" + POSTGRES_USER: "" + POSTGRES_HOST: "" ``` -Fill in the values for **POSTGRES_PASSWORD**, **POSTGRES_PORT**, **POSTGRES_USER**, and **POSTGRES_HOST** with the appropriate credentials and connection details. +Fill in the values for **POSTGRES_PASSWORD**, **POSTGRES_PORT**, **POSTGRES_USER**, and +**POSTGRES_HOST** with the appropriate credentials and connection details. ### Cluster Configuration diff --git a/.ibm/manual-tests/postgres/install.sh b/.ibm/manual-tests/postgres/install.sh index d602f172b2..ba1d477dc8 100755 --- a/.ibm/manual-tests/postgres/install.sh +++ b/.ibm/manual-tests/postgres/install.sh @@ -5,6 +5,7 @@ set -x HELM_IMAGE_NAME=backstage HELM_REPO_NAME=rhdh-chart +# shellcheck disable=SC2034 HELM_REPO_URL="https://redhat-developer.github.io/rhdh-chart" K8S_CLUSTER_URL= RELEASE_NAME=rhdh diff --git a/.ibm/manual-tests/postgres/values.yaml b/.ibm/manual-tests/postgres/values.yaml index 2ca256d316..3e691db07a 100644 --- a/.ibm/manual-tests/postgres/values.yaml +++ b/.ibm/manual-tests/postgres/values.yaml @@ -1,13 +1,13 @@ upstream: postgresql: - enabled: false # disable PostgreSQL instance creation + enabled: false # disable PostgreSQL instance creation auth: existingSecret: postgres-cred backstage: appConfig: backend: database: - connection: # configure Backstage DB connection parameters + connection: # configure Backstage DB connection parameters host: ${POSTGRES_HOST} port: ${POSTGRES_PORT} user: ${POSTGRES_USER} diff --git a/.ibm/package.json b/.ibm/package.json new file mode 100644 index 0000000000..21e4c13454 --- /dev/null +++ b/.ibm/package.json @@ -0,0 +1,19 @@ +{ + "name": ".ibm", + "version": "1.8.0", + "private": true, + "engines": { + "node": "22" + }, + "scripts": { + "shellcheck": "shellcheck --severity=warning --color=always **/*.sh", + "prettier:check": "npx prettier --check **/*.{sh,md,yaml,yml}", + "prettier:fix": "npx prettier --write **/*.{sh,md,yaml,yml}" + }, + "devDependencies": { + "prettier": "3.6.2", + "prettier-plugin-sh": "^0.18.0", + "shellcheck": "^4.1.0" + }, + "packageManager": "yarn@3.8.7" +} diff --git a/.ibm/pipelines/README.md b/.ibm/pipelines/README.md index ac546162fd..658f7de756 100644 --- a/.ibm/pipelines/README.md +++ b/.ibm/pipelines/README.md @@ -2,22 +2,27 @@ ## Overview -The RHDH deployment for end-to-end (e2e) tests in CI has been updated to use **ephemeral clusters** on OpenShift Container Platform (OCP) instead of persistent clusters. +The RHDH deployment for end-to-end (e2e) tests in CI has been updated to use **ephemeral clusters** +on OpenShift Container Platform (OCP) instead of persistent clusters. ### Key Updates + - Starting from version **1.5**, ephemeral clusters are used for: - - OCP nightly jobs (v4.17, v4.16, and v4.14). - - PR checks on the main branch. -- Previously, RHDH PR checks utilized persistent clusters created on IBM Cloud. -- Now, ephemeral clusters are provisioned using the **OpenShift CI cluster claim** on AWS via the RHDH-QE account in the `us-east-2` region. + - OCP nightly jobs (v4.17, v4.16, and v4.14). + - PR checks on the main branch. +- Previously, RHDH PR checks utilized persistent clusters created on IBM Cloud. +- Now, ephemeral clusters are provisioned using the **OpenShift CI cluster claim** on AWS via the + RHDH-QE account in the `us-east-2` region. --- ## Access Requirements -To access ephemeral clusters, you must: -1. Be a **Cluster Pool Admin**. -2. Join the **Rover Group**: [rhdh-pool-admins](https://rover.redhat.com/groups/group/rhdh-pool-admins). +To access ephemeral clusters, you must: + +1. Be a **Cluster Pool Admin**. +2. Join the **Rover Group**: + [rhdh-pool-admins](https://rover.redhat.com/groups/group/rhdh-pool-admins). --- @@ -25,23 +30,28 @@ To access ephemeral clusters, you must: The following cluster pools are available for different OCP versions: +- **RHDH-4-19-US-EAST-2** + - Usage: OCP v4.19 nightly jobs. + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-19-0-amd64-aws-us-east-2_clusterpool.yaml). + +- **RHDH-4-18-US-EAST-2** + - Usage: OCP v4.18 nightly jobs. + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-18-0-amd64-aws-us-east-2_clusterpool.yaml). + - **RHDH-4-17-US-EAST-2** - - Usage: PR checks on the main branch and OCP v4.17 nightly jobs. - - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-17-0-amd64-aws-us-east-2_clusterpool.yaml). + - Usage: PR checks on the main branch and OCP v4.17 nightly jobs. + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-17-0-amd64-aws-us-east-2_clusterpool.yaml). - **RHDH-4-16-US-EAST-2** - - Usage: OCP v4.16 nightly jobs. - - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-16-0-amd64-aws-us-east-2_clusterpool.yaml). - -- **RHDH-4-15-US-EAST-2** - - Usage: OCP v4.15 nightly jobs. - - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-15-0-amd64-aws-us-east-2_clusterpool.yaml). + - Usage: OCP v4.16 nightly jobs. + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-16-0-amd64-aws-us-east-2_clusterpool.yaml). --- ## Using Cluster Claims in OpenShift CI Jobs -Ephemeral clusters can be utilized in CI jobs by defining a `cluster_claim` stanza with values matching the labels on the pool. +Ephemeral clusters can be utilized in CI jobs by defining a `cluster_claim` stanza with values +matching the labels on the pool. Additionally, include the workflow: `generic-claim` for setup and cleanup. ### Example Configuration @@ -60,57 +70,66 @@ Additionally, include the workflow: `generic-claim` for setup and cleanup. cron: 0 7 * * * steps: test: - - ref: janus-idp-backstage-showcase-nightly + - ref: janus-idp-backstage-showcase-nightly workflow: generic-claim ``` - - ## Debugging -If you are a member of the ```rhdh-pool-admins``` group, you can use the [.ibm/pipelines/ocp-cluster-claim-login.sh](ocp-cluster-claim-login.sh) script to log in and retrieve ephemeral environment credentials. +If you are a member of the `rhdh-pool-admins` group, you can use the +[.ibm/pipelines/ocp-cluster-claim-login.sh](ocp-cluster-claim-login.sh) script to log in and +retrieve ephemeral environment credentials. ### Steps: -1. Run the script: - ```bash - .ibm/pipelines/ocp-cluster-claim-login.sh - ``` -2. Provide the Prow log URL when prompted, for example: ```https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/janus-idp_backstage-showcase/2089/pull-ci-janus-idp-backstage-showcase-main-e2e-tests/1866766753132974080 ``` +1. Run the script: + ```bash + .ibm/pipelines/ocp-cluster-claim-login.sh + ``` +2. Provide the Prow log URL when prompted, for example: + `https://prow.ci.openshift.org/view/gs/test-platform-results/pr-logs/pull/janus-idp_backstage-showcase/2089/pull-ci-janus-idp-backstage-showcase-main-e2e-tests/1866766753132974080 ` 3. The script will: - - Log in to the hosted-mgmt cluster, which manages ephemeral cluster creation. - - Retrieve admin credentials and log in to the ephemeral cluster. - - Prompt to open the OCP web console directly in the browser. + - Log in to the hosted-mgmt cluster, which manages ephemeral cluster creation. + - Retrieve admin credentials and log in to the ephemeral cluster. + - Prompt to open the OCP web console directly in the browser. 4. Note: - - The ephemeral cluster is deleted as soon as the CI job terminates. - - To retain the cluster for a longer duration, add a sleep command in the [openshift-ci-tests.sh](openshift-ci-tests.sh) script, e.g.: - ```bash - ... - echo "Main script completed with result: ${OVERALL_RESULT}" - sleep 60*60 - exit "${OVERALL_RESULT}" - ... - ``` + - The ephemeral cluster is deleted as soon as the CI job terminates. + - To retain the cluster for a longer duration, add a sleep command in the + [openshift-ci-tests.sh](openshift-ci-tests.sh) script, e.g.: + ```bash + ... + echo "Main script completed with result: ${OVERALL_RESULT}" + sleep 60*60 + exit "${OVERALL_RESULT}" + ... + ``` ### For detailed documentation, refer to: [Openshift-ci cluster claim docs](https://docs.ci.openshift.org/docs/how-tos/cluster-claim/) - ## Keycloak Authentication for Tests + - All tests on the main branch use Keycloak as the default authentication provider. - Keycloak is deployed on the pr-os cluster. + ### Keycloak Instance Details: -- URL: [Keycloak Admin Console](https://keycloak-rhsso.rhdh-pr-os-a9805650830b22c3aee243e51d79565d-0000.us-east.containers.appdomain.cloud/auth/admin/master/console/#/realms/rhdh-login-test) + +- URL: + [Keycloak Admin Console](https://keycloak-rhsso.rhdh-pr-os-a9805650830b22c3aee243e51d79565d-0000.us-east.containers.appdomain.cloud/auth/admin/master/console/#/realms/rhdh-login-test) - Credentials: These can be found in the RHDH-QE Vault under the following keys: - - ```KEYCLOAK_AUTH_BASE_URL``` - - ```KEYCLOAK_AUTH_CLIENTID``` - - ```KEYCLOAK_AUTH_CLIENT_SECRET``` - - ```KEYCLOAK_AUTH_LOGIN_REALM``` - - ```KEYCLOAK_AUTH_REALM``` + - `KEYCLOAK_AUTH_BASE_URL` + - `KEYCLOAK_AUTH_CLIENTID` + - `KEYCLOAK_AUTH_CLIENT_SECRET` + - `KEYCLOAK_AUTH_LOGIN_REALM` + - `KEYCLOAK_AUTH_REALM` # Installation Instructions for Tests -For tests dependent on `backstage-community-plugin-ocm-backend-dynamic` and `backstage-community-plugin-ocm`, it's necessary to install **Advanced Cluster Management for Kubernetes "MultiClusterHub"**. +For tests dependent on `backstage-community-plugin-ocm-backend-dynamic` and +`backstage-community-plugin-ocm`, it's necessary to install **Advanced Cluster Management for +Kubernetes "MultiClusterHub"**. Please follow these steps for installation: -1. Visit [Installing Advanced Cluster Management for Kubernetes "MultiClusterHub"](https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.10/html/install/installing#installing-from-the-operatorhub) for detailed instructions on installing from the OperatorHub. +1. Visit + [Installing Advanced Cluster Management for Kubernetes "MultiClusterHub"](https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.10/html/install/installing#installing-from-the-operatorhub) + for detailed instructions on installing from the OperatorHub. diff --git a/.ibm/pipelines/auth/secrets-rhdh-secrets.yaml b/.ibm/pipelines/auth/secrets-rhdh-secrets.yaml index 388b262e05..cde703b1fd 100644 --- a/.ibm/pipelines/auth/secrets-rhdh-secrets.yaml +++ b/.ibm/pipelines/auth/secrets-rhdh-secrets.yaml @@ -43,4 +43,5 @@ data: REDIS_USERNAME: $REDIS_USERNAME_ENCODED GITHUB_OAUTH_APP_ID: $GITHUB_OAUTH_APP_ID_ENCODED GITHUB_OAUTH_APP_SECRET: $GITHUB_OAUTH_APP_SECRET_ENCODED + BACKEND_SECRET: $BACKEND_SECRET type: Opaque diff --git a/.ibm/pipelines/cleanup.sh b/.ibm/pipelines/cleanup.sh new file mode 100755 index 0000000000..7b54cc576b --- /dev/null +++ b/.ibm/pipelines/cleanup.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# shellcheck source=.ibm/pipelines/reporting.sh +source "$DIR"/reporting.sh +# shellcheck source=.ibm/pipelines/cluster/gke/gcloud.sh +source "$DIR"/cluster/gke/gcloud.sh + +cleanup() { + if [[ $? -ne 0 ]]; then + + echo "Exited with an error, setting OVERALL_RESULT to 1" + save_overall_result 1 + fi + if [[ "${OPENSHIFT_CI}" == "true" ]]; then + echo "Cleaning up before exiting" + case "$JOB_NAME" in + *gke*) + echo "Calling cleanup_gke" + cleanup_gke + ;; + esac + fi + rm -rf ~/tmpbin +} diff --git a/.ibm/pipelines/clear-database.sh b/.ibm/pipelines/clear-database.sh index c597dfd9ea..d9802a6d45 100644 --- a/.ibm/pipelines/clear-database.sh +++ b/.ibm/pipelines/clear-database.sh @@ -1,16 +1,17 @@ #!/bin/bash clear_database() { - export POSTGRES_USER="$(echo -n "$RDS_USER" | base64 --decode)" + POSTGRES_USER="$(echo -n "$RDS_USER" | base64 --decode)" + export POSTGRES_USER export PGPASSWORD=$RDS_PASSWORD export POSTGRES_HOST=$RDS_1_HOST echo "Starting database cleanup process..." - + # Get list of databases, handle potential connection errors DATABASES=$(psql -h "$POSTGRES_HOST" -U "$POSTGRES_USER" -p "5432" -d postgres -Atc \ - "SELECT datname FROM pg_database WHERE datistemplate = false AND datname NOT IN ('postgres', 'rdsadmin');" 2>/dev/null) - + "SELECT datname FROM pg_database WHERE datistemplate = false AND datname NOT IN ('postgres', 'rdsadmin');" 2> /dev/null) + if [ $? -ne 0 ]; then echo "Warning: Failed to connect to database or retrieve database list" return 1 @@ -25,7 +26,7 @@ clear_database() { for db in $DATABASES; do echo "Attempting to drop database: $db" - + # Use IF EXISTS to avoid errors if database doesn't exist # Capture both stdout and stderr, but don't let errors stop the script if psql -h "$POSTGRES_HOST" -U "$POSTGRES_USER" -p "5432" -d postgres -c "DROP DATABASE IF EXISTS \"$db\";" 2>&1; then @@ -34,6 +35,6 @@ clear_database() { echo "Warning: Failed to drop database $db, but continuing with cleanup" fi done - + echo "Database cleanup process completed" -} \ No newline at end of file +} diff --git a/.ibm/pipelines/cluster/aks/aks-helm-deployment.sh b/.ibm/pipelines/cluster/aks/aks-helm-deployment.sh index 9fc767e740..fa1dd5e91a 100644 --- a/.ibm/pipelines/cluster/aks/aks-helm-deployment.sh +++ b/.ibm/pipelines/cluster/aks/aks-helm-deployment.sh @@ -2,19 +2,27 @@ # shellcheck source=.ibm/pipelines/utils.sh source "$DIR"/utils.sh +# shellcheck source=.ibm/pipelines/cluster/k8s/k8s-utils.sh +source "$DIR"/cluster/k8s/k8s-utils.sh initiate_aks_helm_deployment() { delete_namespace "${NAME_SPACE_RBAC}" configure_namespace "${NAME_SPACE}" + deploy_redis_cache "${NAME_SPACE}" patch_and_restart "$NAME_SPACE" "deployment" "redis" "${DIR}/cluster/aks/patch/aks-spot-patch.yaml" # Patch Redis deployment to run on spot cluster + uninstall_helmchart "${NAME_SPACE}" "${RELEASE_NAME}" + cd "${DIR}" || exit local rhdh_base_url="https://${K8S_CLUSTER_ROUTER_BASE}" apply_yaml_files "${DIR}" "${NAME_SPACE}" "${rhdh_base_url}" yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_VALUE_FILE_NAME}" "${DIR}/value_files/${HELM_CHART_AKS_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" mkdir -p "${ARTIFACT_DIR}/${NAME_SPACE}" cp -a "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" "${ARTIFACT_DIR}/${NAME_SPACE}/" # Save the final value-file into the artifacts directory. + + setup_image_pull_secret "${NAME_SPACE}" "rh-pull-secret" "${REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON}" + echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE}" helm upgrade -i "${RELEASE_NAME}" -n "${NAME_SPACE}" \ "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ @@ -27,16 +35,21 @@ initiate_aks_helm_deployment() { initiate_rbac_aks_helm_deployment() { delete_namespace "${NAME_SPACE}" configure_namespace "${NAME_SPACE_RBAC}" + uninstall_helmchart "${NAME_SPACE_RBAC}" "${RELEASE_NAME_RBAC}" + cd "${DIR}" || exit local rbac_rhdh_base_url="https://${K8S_CLUSTER_ROUTER_BASE}" apply_yaml_files "${DIR}" "${NAME_SPACE_RBAC}" "${rbac_rhdh_base_url}" yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_RBAC_VALUE_FILE_NAME}" "${DIR}/value_files/${HELM_CHART_RBAC_AKS_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" mkdir -p "${ARTIFACT_DIR}/${NAME_SPACE_RBAC}" cp -a "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" "${ARTIFACT_DIR}/${NAME_SPACE_RBAC}/" # Save the final value-file into the artifacts directory. + + setup_image_pull_secret "${NAME_SPACE_RBAC}" "rh-pull-secret" "${REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON}" + echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE_RBAC}" helm upgrade -i "${RELEASE_NAME_RBAC}" -n "${NAME_SPACE_RBAC}" \ - "${HELM_REPO_NAME}/${HELM_IMAGE_NAME}" --version "${CHART_VERSION}" \ + "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ -f "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" \ --set global.host="${K8S_CLUSTER_ROUTER_BASE}" \ --set upstream.backstage.image.repository="${QUAY_REPO}" \ diff --git a/.ibm/pipelines/cluster/aks/aks-operator-deployment.sh b/.ibm/pipelines/cluster/aks/aks-operator-deployment.sh index 2d0b680b37..bf1b03ca05 100644 --- a/.ibm/pipelines/cluster/aks/aks-operator-deployment.sh +++ b/.ibm/pipelines/cluster/aks/aks-operator-deployment.sh @@ -4,6 +4,8 @@ source "$DIR"/utils.sh # shellcheck source=.ibm/pipelines/install-methods/operator.sh source "$DIR"/install-methods/operator.sh +# shellcheck source=.ibm/pipelines/cluster/k8s/k8s-utils.sh +source "$DIR"/cluster/k8s/k8s-utils.sh initiate_aks_operator_deployment() { local namespace=$1 @@ -58,36 +60,6 @@ initiate_rbac_aks_operator_deployment() { apply_aks_operator_ingress "$namespace" "backstage-$RELEASE_NAME_RBAC" } -patch_and_restart() { - local namespace=$1 - local resource_type=$2 - local resource_name=$3 - local patch_file=$4 - - echo "Waiting for $resource_type/$resource_name to be present..." - kubectl wait --for=jsonpath='{.metadata.name}'="$resource_name" "$resource_type/$resource_name" -n "$namespace" --timeout=60s - - echo "Patching $resource_type/$resource_name in namespace $namespace with file $patch_file" - kubectl patch "$resource_type" "$resource_name" -n "$namespace" --type=merge --patch-file "$patch_file" - - echo "Scaling down $resource_type/$resource_name to 0 replicas" - kubectl scale "$resource_type" "$resource_name" --replicas=0 -n "$namespace" - - echo "Waiting for pods to terminate gracefully (timeout: 60s)..." - if ! kubectl wait --for=delete pods -l app="$resource_name" -n "$namespace" --timeout=60s; then - echo "Warning: Pods did not terminate gracefully within 60s" - echo "Attempting force deletion of pods..." - kubectl delete pods -l app="$resource_name" -n "$namespace" --force --grace-period=0 - # Wait a bit to ensure pods are actually gone - sleep 5 - fi - - echo "Scaling up $resource_type/$resource_name to 1 replica" - kubectl scale "$resource_type" "$resource_name" --replicas=1 -n "$namespace" - - echo "Patch and restart completed for $resource_type/$resource_name" -} - patch_and_restart_aks_spot() { local namespace=$1 local release_name=$2 @@ -106,12 +78,12 @@ patch_and_restart_aks_spot_rbac() { apply_aks_operator_ingress() { local namespace=$1 local service_name=$2 - cat "$DIR/cluster/aks/manifest/aks-operator-ingress.yaml" | \ - yq ".spec.rules[0].http.paths[0].backend.service.name = \"$service_name\"" - | \ - kubectl apply --namespace="${namespace}" -f - + cat "$DIR/cluster/aks/manifest/aks-operator-ingress.yaml" \ + | yq ".spec.rules[0].http.paths[0].backend.service.name = \"$service_name\"" - \ + | kubectl apply --namespace="${namespace}" -f - } cleanup_aks_deployment() { local namespace=$1 delete_namespace "$namespace" -} \ No newline at end of file +} diff --git a/.ibm/pipelines/cluster/aks/auto-label/create-azure-tag-policy.sh b/.ibm/pipelines/cluster/aks/auto-label/create-azure-tag-policy.sh index 534d76259f..c40f9b89d5 100755 --- a/.ibm/pipelines/cluster/aks/auto-label/create-azure-tag-policy.sh +++ b/.ibm/pipelines/cluster/aks/auto-label/create-azure-tag-policy.sh @@ -23,7 +23,7 @@ if az policy definition show --name "require-tags-rhdh" --subscription "$ARM_SUB fi # Create the policy rules JSON file -cat > azure-policy-rules.json < azure-policy-rules.json << EOF { "if": { "anyOf": [ diff --git a/.ibm/pipelines/cluster/aks/az.sh b/.ibm/pipelines/cluster/aks/az.sh index b91ac40f21..1b5235611b 100644 --- a/.ibm/pipelines/cluster/aks/az.sh +++ b/.ibm/pipelines/cluster/aks/az.sh @@ -54,4 +54,4 @@ az_aks_get_credentials() { local name=$1 local resource_group=$2 az aks get-credentials --name="${name}" --resource-group="${resource_group}" --overwrite-existing -} \ No newline at end of file +} diff --git a/.ibm/pipelines/cluster/aks/patch/aks-spot-patch.yaml b/.ibm/pipelines/cluster/aks/patch/aks-spot-patch.yaml index 356bd23dc3..49e0799410 100644 --- a/.ibm/pipelines/cluster/aks/patch/aks-spot-patch.yaml +++ b/.ibm/pipelines/cluster/aks/patch/aks-spot-patch.yaml @@ -9,10 +9,10 @@ spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - - weight: 1 - preference: - matchExpressions: - - key: "kubernetes.azure.com/scalesetpriority" - operator: In - values: - - "spot" + - weight: 1 + preference: + matchExpressions: + - key: "kubernetes.azure.com/scalesetpriority" + operator: In + values: + - "spot" diff --git a/.ibm/pipelines/cluster/eks/aws.sh b/.ibm/pipelines/cluster/eks/aws.sh new file mode 100644 index 0000000000..c9e35657cc --- /dev/null +++ b/.ibm/pipelines/cluster/eks/aws.sh @@ -0,0 +1,882 @@ +#!/bin/bash + +# These functions provide AWS utilities for EKS deployments. +# The cluster is pre-configured with required addons and load balancer. +# KUBECONFIG is provided by the test environment. + +# Masking helper to avoid leaking sensitive values in logs +mask_value() { + local value="$1" + local visible_prefix="${2:-14}" + local visible_suffix="${3:-0}" + + # Empty or short values -> redact fully + if [[ -z "$value" ]]; then + echo "***REDACTED***" + return + fi + + local length=${#value} + if ((length <= visible_prefix + visible_suffix + 3)); then + echo "***REDACTED***" + else + echo "${value:0:visible_prefix}...${value:length-visible_suffix:visible_suffix}" + fi +} + +# AWS configuration for deployments that need AWS services +aws_configure() { + local cluster_region + if [[ -n "${AWS_ACCESS_KEY_ID}" && -n "${AWS_SECRET_ACCESS_KEY}" ]]; then + aws configure set aws_access_key_id "${AWS_ACCESS_KEY_ID}" + aws configure set aws_secret_access_key "${AWS_SECRET_ACCESS_KEY}" + cluster_region=$(get_cluster_aws_region) + aws configure set default.region "${cluster_region}" + export AWS_DEFAULT_REGION="${cluster_region}" + export AWS_REGION="${cluster_region}" + echo "AWS CLI configured for default region: ${cluster_region}" + else + echo "AWS credentials not provided, skipping AWS CLI configuration" + fi +} + +# Get load balancer hostname from EKS cluster +aws_eks_get_load_balancer_hostname() { + local namespace=$1 + local service_name=$2 + + # Try to get the ALB hostname from the ingress + local alb_hostname + alb_hostname=$(kubectl get ingress -n "${namespace}" -o jsonpath='{.items[0].status.loadBalancer.ingress[0].hostname}' 2> /dev/null) + + if [[ -n "${alb_hostname}" ]]; then + echo "${alb_hostname}" + else + # Fallback to service load balancer + kubectl get svc "${service_name}" -n "${namespace}" -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' 2> /dev/null + fi +} + +# Verify EKS cluster connectivity +aws_eks_verify_cluster() { + echo "Verifying EKS cluster connectivity..." + + if ! kubectl cluster-info > /dev/null 2>&1; then + echo "Error: Cannot connect to EKS cluster. Please check KUBECONFIG." + return 1 + fi + + echo "Successfully connected to EKS cluster" + kubectl get nodes --no-headers | wc -l | xargs echo "Number of nodes:" +} + +# Get EKS cluster information +aws_eks_get_cluster_info() { + echo "EKS Cluster Information:" + echo "========================" + + # Get cluster version + kubectl version --short 2> /dev/null | grep "Server Version" || echo "Server Version: Unable to determine" + + # Get node information + echo "Node Information:" + kubectl get nodes -o custom-columns="NAME:.metadata.name,STATUS:.status.conditions[?(@.type=='Ready')].status,ROLES:.metadata.labels.node\.kubernetes\.io/role,SPOT:.metadata.labels.kubernetes\.aws\.com/spot" 2> /dev/null || echo "Unable to get node information" + + # Get installed addons + echo "Installed Addons:" + kubectl get pods -A -l app.kubernetes.io/name=aws-load-balancer-controller 2> /dev/null | grep -q aws-load-balancer-controller && echo "- AWS Load Balancer Controller" || echo "- AWS Load Balancer Controller: Not found" + kubectl get pods -A -l app.kubernetes.io/name=aws-ebs-csi-driver 2> /dev/null | grep -q ebs-csi && echo "- AWS EBS CSI Driver" || echo "- AWS EBS CSI Driver: Not found" +} + +# Function to setup EKS ingress hosts configuration +configure_eks_ingress_and_dns() { + local namespace=$1 + local ingress_name=$2 + + echo "Setting up EKS ingress hosts configuration..." + + # Wait for ingress to be available + echo "Waiting for ingress ${ingress_name} to be available in namespace ${namespace}..." + local max_attempts=30 + local wait_seconds=10 + local ingress_address="" + + for ((i = 1; i <= max_attempts; i++)); do + echo "Attempt ${i} of ${max_attempts} to get ingress address..." + + # Get the ingress address dynamically + ingress_address=$(kubectl get ingress "${ingress_name}" -n "${namespace}" -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' 2> /dev/null) + + if [[ -n "${ingress_address}" ]]; then + echo "Successfully retrieved ingress address" + break + else + echo "Ingress address not available yet, waiting ${wait_seconds} seconds..." + sleep "${wait_seconds}" + fi + done + + if [[ -z "${ingress_address}" ]]; then + echo "Error: Failed to get ingress address after ${max_attempts} attempts" + return 1 + fi + + export EKS_INGRESS_HOSTNAME="${ingress_address}" + + echo "EKS ingress hosts configuration completed successfully" + + # Update DNS record in Route53 if domain name is configured + if [[ -n "${EKS_INSTANCE_DOMAIN_NAME}" ]]; then + local masked_domain + local masked_target + masked_domain=$(mask_value "${EKS_INSTANCE_DOMAIN_NAME}") + masked_target=$(mask_value "${ingress_address}") + echo "Updating DNS record for domain ${masked_domain} -> target ${masked_target}" + + if update_route53_dns_record "${EKS_INSTANCE_DOMAIN_NAME}" "${ingress_address}"; then + echo "✅ DNS record updated successfully" + + # Verify DNS resolution + if verify_dns_resolution "${EKS_INSTANCE_DOMAIN_NAME}" "${ingress_address}" 30 15; then + echo "✅ DNS resolution verified successfully" + else + echo "⚠️ DNS resolution verification failed, but record was updated" + fi + else + echo "⚠️ Failed to update DNS record, but ingress is still functional" + fi + else + echo "No domain name configured, skipping DNS update" + fi +} + +# Function to get EKS certificate using AWS CLI +get_eks_certificate() { + local domain_name=$1 + + echo "Retrieving certificate for configured domain" + + # Check if AWS CLI is available + if ! command -v aws &> /dev/null; then + echo "Error: AWS CLI is not installed or not in PATH" + return 1 + fi + + # Check if AWS credentials are configured + if ! aws sts get-caller-identity &> /dev/null; then + echo "Error: AWS credentials are not configured or invalid" + return 1 + fi + + # Get the cluster region + local region + region=$(get_cluster_aws_region) + if [[ $? -ne 0 ]]; then + echo "Error: Failed to get cluster AWS region" + return 1 + fi + echo "Using region: ${region}" + + # List certificates and find the one for our domain + echo "Searching for certificate in AWS Certificate Manager..." + local certificate_arn + certificate_arn=$(aws acm list-certificates --region "${region}" --query "CertificateSummaryList[].{DomainName:DomainName,Status:Status,CertificateArn:CertificateArn}" --output json | jq -r ".[] | select(.DomainName == \"${domain_name}\") | .CertificateArn") + + if [[ -z "${certificate_arn}" ]]; then + echo "No existing certificate found for domain" + echo "Creating new certificate..." + + # Create a new certificate + local new_certificate_arn + new_certificate_arn=$(aws acm request-certificate \ + --region "${region}" \ + --domain-name "${domain_name}" \ + --validation-method DNS \ + --query 'CertificateArn' \ + --output text 2> /dev/null) + + if [[ $? -ne 0 || -z "${new_certificate_arn}" ]]; then + echo "Error: Failed to create new certificate for domain: ${domain_name}" + return 1 + fi + + echo "✅ New certificate created successfully" + certificate_arn="${new_certificate_arn}" + + # Get validation records that need to be created + echo "Getting DNS validation records..." + local validation_records + validation_records=$(aws acm describe-certificate --region "${region}" --certificate-arn "${certificate_arn}" --query 'Certificate.DomainValidationOptions[0].ResourceRecord' --output json 2> /dev/null) + + if [[ $? -eq 0 && "${validation_records}" != "null" && "${validation_records}" != "[]" ]]; then + local validation_name + local validation_value + validation_name=$(echo "${validation_records}" | jq -r '.Name') + validation_value=$(echo "${validation_records}" | jq -r '.Value') + + # Check if we got valid values + if [[ -n "${validation_name}" && "${validation_name}" != "null" && -n "${validation_value}" && "${validation_value}" != "null" ]]; then + echo "DNS validation record needed." + + # Create the validation DNS record + echo "Creating DNS validation record..." + if update_route53_dns_record "${validation_name}" "${validation_value}"; then + echo "✅ DNS validation record created successfully" + else + echo "⚠️ Failed to create DNS validation record automatically" + fi + else + echo "ℹ️ No valid DNS validation records found (certificate may already be validated or use different validation method)" + fi + else + echo "ℹ️ No DNS validation records found (certificate may already be validated or use different validation method)" + fi + + # Wait for certificate to be issued (this can take several minutes) + echo "Waiting for certificate to be issued..." + local max_attempts=60 + local wait_seconds=30 + + for ((i = 1; i <= max_attempts; i++)); do + echo "Checking certificate status (attempt ${i}/${max_attempts})..." + + local cert_status + cert_status=$(aws acm describe-certificate --region "${region}" --certificate-arn "${certificate_arn}" --query 'Certificate.Status' --output text 2> /dev/null) + + if [[ "${cert_status}" == "ISSUED" ]]; then + echo "✅ Certificate has been issued successfully" + break + elif [[ "${cert_status}" == "FAILED" ]]; then + echo "❌ Certificate validation failed" + echo "Check the certificate details for validation errors:" + aws acm describe-certificate --region "${region}" --certificate-arn "${certificate_arn}" --query 'Certificate.DomainValidationOptions[0].ValidationStatus' --output text 2> /dev/null + return 1 + elif [[ "${cert_status}" == "PENDING_VALIDATION" ]]; then + echo "⏳ Certificate is pending validation (attempt ${i}/${max_attempts})" + + # Check validation method and status + local validation_method + local validation_status + validation_method=$(aws acm describe-certificate --region "${region}" --certificate-arn "${certificate_arn}" --query 'Certificate.DomainValidationOptions[0].ValidationMethod' --output text 2> /dev/null) + validation_status=$(aws acm describe-certificate --region "${region}" --certificate-arn "${certificate_arn}" --query 'Certificate.DomainValidationOptions[0].ValidationStatus' --output text 2> /dev/null) + + echo " Validation method: ${validation_method}" + echo " Validation status: ${validation_status}" + + if [[ "${validation_method}" == "DNS" && "${validation_status}" == "PENDING_VALIDATION" ]]; then + # Check if DNS validation records are available + local validation_records + validation_records=$(aws acm describe-certificate --region "${region}" --certificate-arn "${certificate_arn}" --query 'Certificate.DomainValidationOptions[0].ResourceRecord' --output json 2> /dev/null) + + if [[ "${validation_records}" != "null" && "${validation_records}" != "[]" ]]; then + local validation_name + local validation_value + validation_name=$(echo "${validation_records}" | jq -r '.Name') + validation_value=$(echo "${validation_records}" | jq -r '.Value') + + if [[ -n "${validation_name}" && "${validation_name}" != "null" && -n "${validation_value}" && "${validation_value}" != "null" ]]; then + echo " DNS validation record needed." + # Create the validation DNS record + echo " Creating DNS validation record..." + if update_route53_dns_record "${validation_name}" "${validation_value}"; then + echo " ✅ DNS validation record created successfully" + else + echo " ⚠️ Failed to create DNS validation record automatically" + fi + fi + fi + fi + + if [[ $i -lt $max_attempts ]]; then + sleep "${wait_seconds}" + fi + else + echo "ℹ️ Certificate status: ${cert_status}" + if [[ $i -lt $max_attempts ]]; then + sleep "${wait_seconds}" + fi + fi + done + + # Final status check + local final_status + final_status=$(aws acm describe-certificate --region "${region}" --certificate-arn "${certificate_arn}" --query 'Certificate.Status' --output text 2> /dev/null) + + if [[ "${final_status}" != "ISSUED" ]]; then + echo "❌ Certificate was not issued within the expected time. Current status: ${final_status}" + echo "You may need to manually validate the certificate or check DNS records." + return 1 + fi + fi + + echo "Found certificate ARN" + + # Get certificate details + echo "Retrieving certificate details..." + local certificate_details + certificate_details=$(aws acm describe-certificate --region "${region}" --certificate-arn "${certificate_arn}" 2> /dev/null) + + if [[ $? -ne 0 ]]; then + echo "Error: Failed to retrieve certificate details" + return 1 + fi + + # Check if certificate is valid + local status + status=$(echo "${certificate_details}" | jq -r '.Certificate.Status' 2> /dev/null) + + if [[ "${status}" == "ISSUED" ]]; then + echo "✅ Certificate is valid and issued" + + # Additional validation checks + local not_after + not_after=$(echo "${certificate_details}" | jq -r '.Certificate.NotAfter' 2> /dev/null) + if [[ -n "${not_after}" ]]; then + echo "✅ Certificate expiry retrieved" + fi + + local domain_names + domain_names=$(echo "${certificate_details}" | jq -r '.Certificate.SubjectAlternativeNames[]' 2> /dev/null) + if [[ -n "${domain_names}" ]]; then + echo "✅ Certificate SANs retrieved" + fi + else + echo "⚠️ Certificate status: ${status}" + return 1 + fi + + # Export certificate ARN as environment variable for use in other scripts + export EKS_DOMAIN_NAME_CERTIFICATE_ARN="${certificate_arn}" + echo "Certificate ARN exported as EKS_DOMAIN_NAME_CERTIFICATE_ARN" + + echo "EKS certificate retrieval completed successfully" +} + +# Function to get AWS region from EKS cluster +get_cluster_aws_region() { + # Get region from EKS cluster ARN + local cluster_arn + cluster_arn=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' 2> /dev/null) + + # Extract region from EKS cluster URL + if [[ "${cluster_arn}" =~ \.([a-z0-9-]+)\.eks\.amazonaws\.com ]]; then + local region="${BASH_REMATCH[1]}" + echo "Region of the EKS cluster found: ${region}" >&2 + echo "${region}" + return 0 + else + echo "Region of the EKS cluster not found" >&2 + return 1 + fi + +} + +# Function to find available domain number +find_available_domain_number() { + local region=$1 + local max_attempts=50 + + # Use global parent domain from secret + if [[ -z "${AWS_EKS_PARENT_DOMAIN}" ]]; then + echo "Error: AWS_EKS_PARENT_DOMAIN environment variable is not set" >&2 + return 1 + fi + + echo "Finding available domain number for region: ${region}" >&2 + echo "Using parent domain from AWS_EKS_PARENT_DOMAIN " >&2 + + # Get the parent domain hosted zone ID directly + echo "Searching for Route53 hosted zone for configured parent domain" >&2 + + local hosted_zone_id + hosted_zone_id=$(aws route53 list-hosted-zones --query "HostedZones[?Name == '${AWS_EKS_PARENT_DOMAIN}.' || Name == '${AWS_EKS_PARENT_DOMAIN}'].Id" --output text 2> /dev/null) + + if [[ -z "${hosted_zone_id}" ]]; then + echo "Error: No hosted zone found for configured parent domain" >&2 + return 1 + fi + + # Remove the '/hostedzone/' prefix + hosted_zone_id="${hosted_zone_id#/hostedzone/}" + echo "Found hosted zone for configured parent domain" >&2 + + # Check existing DNS records to find used numbers + echo "Checking existing DNS records in hosted zone..." >&2 + echo "Looking for records containing 'eks-ci-' in configured parent domain" >&2 + + local existing_records + existing_records=$(aws route53 list-resource-record-sets \ + --hosted-zone-id "${hosted_zone_id}" \ + --query "ResourceRecordSets[?contains(Name, 'eks-ci-')].Name" \ + --output json 2> /dev/null) + + # Extract used numbers from existing records + local used_numbers=() + local seen_numbers=() + if [[ -n "${existing_records}" ]]; then + # Parse JSON array and process each record + while IFS= read -r record; do + # Remove quotes and trailing comma from JSON array elements + record=$(echo "${record}" | sed 's/^"//; s/"$//; s/,$//') + # More robust regex to match eks-ci-[number].[region].[parent-domain] + if [[ "${record}" =~ eks-ci-([0-9]+)\.${region}\.${AWS_EKS_PARENT_DOMAIN} ]]; then + local number="${BASH_REMATCH[1]}" + # Check if we've already seen this number to avoid duplicates + local already_seen=false + for seen_num in "${seen_numbers[@]}"; do + if [[ "${seen_num}" == "${number}" ]]; then + already_seen=true + break + fi + done + if [[ "${already_seen}" == false ]]; then + used_numbers+=("${number}") + seen_numbers+=("${number}") + echo "Detected used domain slot: ${number}" >&2 + fi + fi + done < <(echo "${existing_records}" | jq -r '.[]' 2> /dev/null || echo "${existing_records}" | grep -o '"[^"]*"' | sed 's/"//g') + else + echo "No existing records found with 'eks-ci-' pattern, will start with number 1" >&2 + fi + + # Fallback: if no records found, try getting all records and filtering locally + if [[ ${#used_numbers[@]} -eq 0 ]]; then + echo "Trying fallback approach - getting all records and filtering locally..." >&2 + local all_records + all_records=$(aws route53 list-resource-record-sets \ + --hosted-zone-id "${hosted_zone_id}" \ + --query "ResourceRecordSets[].Name" \ + --output json 2> /dev/null) + + # Parse JSON array and process each record + while IFS= read -r record; do + # Remove quotes and trailing comma from JSON array elements + record=$(echo "${record}" | sed 's/^"//; s/"$//; s/,$//') + if [[ "${record}" =~ eks-ci-([0-9]+)\.${region}\.${AWS_EKS_PARENT_DOMAIN} ]]; then + local number="${BASH_REMATCH[1]}" + # Check if we've already seen this number to avoid duplicates + local already_seen=false + for seen_num in "${seen_numbers[@]}"; do + if [[ "${seen_num}" == "${number}" ]]; then + already_seen=true + break + fi + done + if [[ "${already_seen}" == false ]]; then + used_numbers+=("${number}") + seen_numbers+=("${number}") + echo "Detected used domain slot (fallback): ${number}" >&2 + fi + fi + done < <(echo "${all_records}" | jq -r '.[]' 2> /dev/null || echo "${all_records}" | grep -o '"[^"]*"' | sed 's/"//g') + fi + + echo "Found ${#used_numbers[@]} existing domains" >&2 + + # Check each potential domain to find the first one that's actually not in use + local number=1 + for ((i = 1; i <= max_attempts; i++)); do + local test_domain="eks-ci-${number}.${region}.${AWS_EKS_PARENT_DOMAIN}" + echo "Testing domain availability" >&2 + # Check if this specific domain exists in Route53 (any record type) + local domain_exists + domain_exists=$(aws route53 list-resource-record-sets \ + --hosted-zone-id "${hosted_zone_id}" \ + --query "ResourceRecordSets[?Name == '${test_domain}.'].{Name:Name,Type:Type}" \ + --output json 2> /dev/null) + + # If the query returns an empty array or null, the domain is available + if [[ -z "${domain_exists}" ]] || [[ "${domain_exists}" == "[]" ]] || [[ "${domain_exists}" == "null" ]]; then + echo "✅ Found available domain (not found in Route53)" >&2 + echo "${number}" + return 0 + else + echo "Domain is in use in Route53, trying next number..." >&2 + fi + + ((number++)) + done + + echo "Error: Could not find available domain number after ${max_attempts} attempts" >&2 + return 1 +} + +# Function to generate dynamic domain name +generate_dynamic_domain_name() { + echo "Generating dynamic domain name..." >&2 + + # Get AWS region + local region + region=$(get_cluster_aws_region) + + if [[ $? -ne 0 ]]; then + echo "Error: Could not determine AWS region" >&2 + return 1 + fi + + # Find available domain number + local number + number=$(find_available_domain_number "${region}") + + if [[ $? -ne 0 ]]; then + echo "Error: Could not find available domain number" >&2 + return 1 + fi + + # Generate the domain name + local domain_name="eks-ci-${number}.${region}.${AWS_EKS_PARENT_DOMAIN}" + local domain_prefix="eks-ci-${number}.${region}" + echo "Generated dynamic domain name: ${domain_prefix}" >&2 + + # Reserve the domain number by creating a placeholder DNS record + echo "Reserving domain number ${number} by creating placeholder DNS record..." >&2 + if ! create_placeholder_dns_record "${domain_name}"; then + echo "Error: Failed to create placeholder DNS record for domain: ${domain_prefix}" >&2 + return 1 + fi + + echo "✅ Successfully reserved domain number ${number} with placeholder record" >&2 + echo "${domain_name}" +} + +# Function to create a placeholder DNS record for reserving a domain number +create_placeholder_dns_record() { + local domain_name=$1 + + # Extract the domain prefix for logging (without parent domain) + local domain_prefix + if [[ "${domain_name}" =~ ^(eks-ci-[0-9]+\.[a-z0-9-]+)\. ]]; then + domain_prefix="${BASH_REMATCH[1]}" + else + domain_prefix="${domain_name}" + fi + + echo "Creating placeholder DNS record to reserve domain: ${domain_prefix}" >&2 + + # Use global parent domain from secret + if [[ -z "${AWS_EKS_PARENT_DOMAIN}" ]]; then + echo "Error: AWS_EKS_PARENT_DOMAIN environment variable is not set" >&2 + return 1 + fi + + # Get the hosted zone ID for the parent domain + local hosted_zone_id + hosted_zone_id=$(aws route53 list-hosted-zones --query "HostedZones[?Name == '${AWS_EKS_PARENT_DOMAIN}.' || Name == '${AWS_EKS_PARENT_DOMAIN}'].Id" --output text 2> /dev/null) + + if [[ -z "${hosted_zone_id}" ]]; then + echo "Error: No hosted zone found for configured parent domain" >&2 + return 1 + fi + + # Remove the '/hostedzone/' prefix + hosted_zone_id="${hosted_zone_id#/hostedzone/}" + echo "Found hosted zone for configured parent domain" >&2 + + # Create the change batch JSON for placeholder record + cat > /tmp/placeholder-dns-change.json << EOF +{ + "Changes": [ + { + "Action": "UPSERT", + "ResourceRecordSet": { + "Name": "${domain_name}", + "Type": "CNAME", + "TTL": 300, + "ResourceRecords": [ + { + "Value": "localhost" + } + ] + } + } + ] +} +EOF + + # Apply the DNS change + echo "Applying placeholder DNS change..." >&2 + local change_id + change_id=$(aws route53 change-resource-record-sets \ + --hosted-zone-id "${hosted_zone_id}" \ + --change-batch file:///tmp/placeholder-dns-change.json \ + --query 'ChangeInfo.Id' \ + --output text 2> /dev/null) + + if [[ $? -eq 0 && -n "${change_id}" ]]; then + echo "✅ Placeholder DNS record created successfully" >&2 + + # Wait for the change to be propagated + echo "Waiting for placeholder DNS change to be propagated..." >&2 + aws route53 wait resource-record-sets-changed --id "${change_id}" + + if [[ $? -eq 0 ]]; then + echo "✅ Placeholder DNS change has been propagated" >&2 + else + echo "⚠️ Placeholder DNS change may still be propagating" >&2 + fi + + # Clean up temporary file + rm -f /tmp/placeholder-dns-change.json + return 0 + else + echo "❌ Failed to create placeholder DNS record" >&2 + # Clean up temporary file + rm -f /tmp/placeholder-dns-change.json + return 1 + fi +} + +# Function to create/update DNS record in Route53 +update_route53_dns_record() { + local domain_name=$1 + local target_value=$2 + + local masked_domain + local masked_target + masked_domain=$(mask_value "${domain_name}") + masked_target=$(mask_value "${target_value}") + echo "Updating DNS record for domain ${masked_domain} -> target ${masked_target}" + + # Use global parent domain from secret + if [[ -z "${AWS_EKS_PARENT_DOMAIN}" ]]; then + echo "Error: AWS_EKS_PARENT_DOMAIN environment variable is not set" + return 1 + fi + + echo "Using configured parent domain" + + # Get the hosted zone ID for the parent domain + local hosted_zone_id + hosted_zone_id=$(aws route53 list-hosted-zones --query "HostedZones[?Name == '${AWS_EKS_PARENT_DOMAIN}.' || Name == '${AWS_EKS_PARENT_DOMAIN}'].Id" --output text 2> /dev/null) + + if [[ -z "${hosted_zone_id}" ]]; then + echo "Error: No hosted zone found for configured parent domain" + return 1 + fi + + # Remove the '/hostedzone/' prefix + hosted_zone_id="${hosted_zone_id#/hostedzone/}" + echo "Found hosted zone for configured parent domain" + + # Create the change batch JSON + cat > /tmp/dns-change.json << EOF +{ + "Changes": [ + { + "Action": "UPSERT", + "ResourceRecordSet": { + "Name": "${domain_name}", + "Type": "CNAME", + "TTL": 300, + "ResourceRecords": [ + { + "Value": "${target_value}" + } + ] + } + } + ] +} +EOF + + # Apply the DNS change + echo "Applying DNS change..." + local change_id + change_id=$(aws route53 change-resource-record-sets \ + --hosted-zone-id "${hosted_zone_id}" \ + --change-batch file:///tmp/dns-change.json \ + --query 'ChangeInfo.Id' \ + --output text 2> /dev/null) + + if [[ $? -eq 0 && -n "${change_id}" ]]; then + echo "✅ DNS change submitted successfully" + + # Wait for the change to be propagated + echo "Waiting for DNS change to be propagated..." + aws route53 wait resource-record-sets-changed --id "${change_id}" + + if [[ $? -eq 0 ]]; then + echo "✅ DNS change has been propagated" + else + echo "⚠️ DNS change may still be propagating" + fi + else + echo "❌ Failed to apply DNS change" + return 1 + fi + + # Clean up temporary file + rm -f /tmp/dns-change.json +} + +# Function to verify DNS resolution +verify_dns_resolution() { + local domain_name=$1 + local expected_target=$2 + local max_attempts=${3:-30} + local wait_seconds=${4:-10} + + echo "Verifying DNS resolution for configured domain" + + for ((i = 1; i <= max_attempts; i++)); do + echo "Checking DNS resolution (attempt ${i}/${max_attempts})..." + + # Use nslookup to check DNS resolution + local resolved_target + resolved_target=$(nslookup "${domain_name}" 2> /dev/null | grep -A1 "Name:" | tail -1 | awk '{print $2}') + + if [[ -n "${resolved_target}" && "${resolved_target}" != "NXDOMAIN" ]]; then + echo "✅ DNS record found" + + # If we have an expected target, verify it matches + if [[ -n "${expected_target}" ]]; then + # For CNAME records, the resolved target will be an IP address, not the hostname + # So we just check that it's a valid IP address (contains dots and numbers) + if [[ "${resolved_target}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "✅ DNS record is resolving to a valid IP address" + return 0 + else + echo "⚠️ DNS record target doesn't look like a valid IP address" + fi + else + echo "✅ DNS record is resolving" + return 0 + fi + else + echo "⏳ DNS record not found yet (attempt ${i}/${max_attempts})" + fi + + if [[ $i -lt $max_attempts ]]; then + echo "Waiting ${wait_seconds} seconds before next attempt..." + sleep "${wait_seconds}" + fi + done + + echo "❌ DNS resolution verification failed after ${max_attempts} attempts" + return 1 +} + +# Function to cleanup EKS DNS records +cleanup_eks_dns_record() { + local domain_name=$1 + + echo "Cleaning up EKS DNS record" + + # Use global parent domain from secret + if [[ -z "${AWS_EKS_PARENT_DOMAIN}" ]]; then + echo "Error: AWS_EKS_PARENT_DOMAIN environment variable is not set" >&2 + return 1 + fi + + echo "Using configured parent domain" + + # Get the hosted zone ID for the parent domain + local hosted_zone_id + hosted_zone_id=$(aws route53 list-hosted-zones --query "HostedZones[?Name == '${AWS_EKS_PARENT_DOMAIN}.' || Name == '${AWS_EKS_PARENT_DOMAIN}'].Id" --output text 2> /dev/null) + + if [[ -z "${hosted_zone_id}" ]]; then + echo "Error: No hosted zone found for parent domain: ${AWS_EKS_PARENT_DOMAIN}" >&2 + return 1 + fi + + # Remove the '/hostedzone/' prefix + hosted_zone_id="${hosted_zone_id#/hostedzone/}" + echo "Found hosted zone for configured parent domain" + + # Check if the DNS record exists before attempting to delete it + echo "Checking if DNS record exists" + local existing_record + existing_record=$(aws route53 list-resource-record-sets \ + --hosted-zone-id "${hosted_zone_id}" \ + --query "ResourceRecordSets[?Name == '${domain_name}.'].{Name:Name,Type:Type,TTL:TTL,ResourceRecords:ResourceRecords}" \ + --output json 2> /dev/null) + + if [[ -z "${existing_record}" ]] || [[ "${existing_record}" == "[]" ]] || [[ "${existing_record}" == "null" ]]; then + echo "✅ DNS record does not exist, nothing to clean up" + return 0 + fi + + echo "Found existing DNS record" + + # Extract the record details for deletion + local record_name + local record_type + local record_ttl + local record_values + + record_name=$(echo "${existing_record}" | jq -r '.[0].Name' 2> /dev/null) + record_type=$(echo "${existing_record}" | jq -r '.[0].Type' 2> /dev/null) + record_ttl=$(echo "${existing_record}" | jq -r '.[0].TTL' 2> /dev/null) + record_values=$(echo "${existing_record}" | jq -r '.[0].ResourceRecords[].Value' 2> /dev/null) + + if [[ -z "${record_name}" ]] || [[ "${record_name}" == "null" ]]; then + echo "Error: Could not extract record details from existing record" >&2 + return 1 + fi + + echo "Record details retrieved (type and TTL)" + + # Create the change batch JSON for deletion + cat > /tmp/dns-delete.json << EOF +{ + "Changes": [ + { + "Action": "DELETE", + "ResourceRecordSet": { + "Name": "${record_name}", + "Type": "${record_type}", + "TTL": ${record_ttl}, + "ResourceRecords": [ +EOF + + # Add the resource records + while IFS= read -r value; do + if [[ -n "${value}" ]] && [[ "${value}" != "null" ]]; then + echo " {" >> /tmp/dns-delete.json + echo " \"Value\": \"${value}\"" >> /tmp/dns-delete.json + echo " }," >> /tmp/dns-delete.json + fi + done <<< "${record_values}" + + # Remove the trailing comma and close the JSON + sed -i '$ s/,$//' /tmp/dns-delete.json + cat >> /tmp/dns-delete.json << EOF + ] + } + } + ] +} +EOF + + # Apply the DNS deletion + echo "Deleting DNS record..." + local change_id + change_id=$(aws route53 change-resource-record-sets \ + --hosted-zone-id "${hosted_zone_id}" \ + --change-batch file:///tmp/dns-delete.json \ + --query 'ChangeInfo.Id' \ + --output text 2> /dev/null) + + if [[ $? -eq 0 && -n "${change_id}" ]]; then + echo "✅ DNS record deletion submitted successfully" + + # Wait for the change to be propagated + echo "Waiting for DNS record deletion to be propagated..." + aws route53 wait resource-record-sets-changed --id "${change_id}" + + if [[ $? -eq 0 ]]; then + echo "✅ DNS record deletion has been propagated" + else + echo "⚠️ DNS record deletion may still be propagating" + fi + else + echo "❌ Failed to delete DNS record" + return 1 + fi + + # Clean up temporary file + rm -f /tmp/dns-delete.json + + return 0 +} diff --git a/.ibm/pipelines/cluster/eks/eks-helm-deployment.sh b/.ibm/pipelines/cluster/eks/eks-helm-deployment.sh new file mode 100644 index 0000000000..09f77d1a6d --- /dev/null +++ b/.ibm/pipelines/cluster/eks/eks-helm-deployment.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# shellcheck source=.ibm/pipelines/utils.sh +source "$DIR"/utils.sh + +initiate_eks_helm_deployment() { + echo "Initiating EKS Helm deployment" + + delete_namespace "${NAME_SPACE_RBAC}" + configure_namespace "${NAME_SPACE}" + deploy_redis_cache "${NAME_SPACE}" + + uninstall_helmchart "${NAME_SPACE}" "${RELEASE_NAME}" + + cd "${DIR}" || exit + + setup_image_pull_secret "${NAME_SPACE}" "rh-pull-secret" "${REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON}" + + local rhdh_base_url="https://${K8S_CLUSTER_ROUTER_BASE}" + apply_yaml_files "${DIR}" "${NAME_SPACE}" "${rhdh_base_url}" + envsubst < "${DIR}/value_files/${HELM_CHART_EKS_DIFF_VALUE_FILE_NAME}" > "/tmp/${HELM_CHART_EKS_DIFF_VALUE_FILE_NAME}" + yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_EKS_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" + mkdir -p "${ARTIFACT_DIR}/${NAME_SPACE}" + cp -a "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" "${ARTIFACT_DIR}/${NAME_SPACE}/" # Save the final value-file into the artifacts directory. + echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE}" + helm upgrade -i "${RELEASE_NAME}" -n "${NAME_SPACE}" \ + "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ + -f "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" \ + --set global.host="${K8S_CLUSTER_ROUTER_BASE}" \ + --set upstream.backstage.image.repository="${QUAY_REPO}" \ + --set upstream.backstage.image.tag="${TAG_NAME}" +} + +initiate_rbac_eks_helm_deployment() { + echo "Initiating EKS RBAC Helm deployment" + + delete_namespace "${NAME_SPACE}" + configure_namespace "${NAME_SPACE_RBAC}" + + uninstall_helmchart "${NAME_SPACE_RBAC}" "${RELEASE_NAME_RBAC}" + + cd "${DIR}" || exit + + setup_image_pull_secret "${NAME_SPACE_RBAC}" "rh-pull-secret" "${REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON}" + + local rbac_rhdh_base_url="https://${K8S_CLUSTER_ROUTER_BASE}" + apply_yaml_files "${DIR}" "${NAME_SPACE_RBAC}" "${rbac_rhdh_base_url}" + envsubst < "${DIR}/value_files/${HELM_CHART_RBAC_EKS_DIFF_VALUE_FILE_NAME}" > "/tmp/${HELM_CHART_RBAC_EKS_DIFF_VALUE_FILE_NAME}" + yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_RBAC_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_RBAC_EKS_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" + mkdir -p "${ARTIFACT_DIR}/${NAME_SPACE_RBAC}" + cp -a "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" "${ARTIFACT_DIR}/${NAME_SPACE_RBAC}/" # Save the final value-file into the artifacts directory. + echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE_RBAC}" + helm upgrade -i "${RELEASE_NAME_RBAC}" -n "${NAME_SPACE_RBAC}" \ + "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ + -f "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" \ + --set global.host="${K8S_CLUSTER_ROUTER_BASE}" \ + --set upstream.backstage.image.repository="${QUAY_REPO}" \ + --set upstream.backstage.image.tag="${TAG_NAME}" +} diff --git a/.ibm/pipelines/cluster/eks/eks-operator-deployment.sh b/.ibm/pipelines/cluster/eks/eks-operator-deployment.sh new file mode 100644 index 0000000000..6fd17890b9 --- /dev/null +++ b/.ibm/pipelines/cluster/eks/eks-operator-deployment.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# shellcheck source=.ibm/pipelines/utils.sh +source "$DIR"/utils.sh +# shellcheck source=.ibm/pipelines/install-methods/operator.sh +source "$DIR"/install-methods/operator.sh + +initiate_eks_operator_deployment() { + local namespace=$1 + local rhdh_base_url=$2 + + echo "Initiating Operator-backed non-RBAC deployment on EKS" + + configure_namespace "${namespace}" + deploy_redis_cache "${namespace}" + # deploy_test_backstage_customization_provider "${namespace}" # Doesn't work on K8s + apply_yaml_files "${DIR}" "${namespace}" "${rhdh_base_url}" + + echo "Creating and applying ConfigMap for dynamic plugins" + yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_VALUE_FILE_NAME}" "${DIR}/value_files/${HELM_CHART_EKS_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" + create_dynamic_plugins_config "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" "/tmp/configmap-dynamic-plugins.yaml" + mkdir -p "${ARTIFACT_DIR}/${namespace}" + cp -a "/tmp/configmap-dynamic-plugins.yaml" "${ARTIFACT_DIR}/${namespace}/" # Save the final value-file into the artifacts directory. + kubectl apply -f /tmp/configmap-dynamic-plugins.yaml -n "${namespace}" + + setup_image_pull_secret "${namespace}" "rh-pull-secret" "${REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON}" + + deploy_rhdh_operator "${namespace}" "${DIR}/resources/rhdh-operator/rhdh-start_K8s.yaml" + + apply_eks_operator_ingress "$namespace" "backstage-$RELEASE_NAME" +} + +initiate_rbac_eks_operator_deployment() { + local namespace=$1 + local rhdh_base_url=$2 + + echo "Initiating Operator-backed RBAC deployment on EKS" + + configure_namespace "${namespace}" + # deploy_test_backstage_customization_provider "${namespace}" # Doesn't work on K8s + create_conditional_policies_operator /tmp/conditional-policies.yaml + prepare_operator_app_config "${DIR}/resources/config_map/app-config-rhdh-rbac.yaml" + apply_yaml_files "${DIR}" "${namespace}" "${rhdh_base_url}" + + echo "Creating and applying ConfigMap for dynamic plugins" + yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_RBAC_VALUE_FILE_NAME}" "${DIR}/value_files/${HELM_CHART_RBAC_EKS_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" + create_dynamic_plugins_config "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" "/tmp/configmap-dynamic-plugins-rbac.yaml" + mkdir -p "${ARTIFACT_DIR}/${namespace}" + cp -a "/tmp/configmap-dynamic-plugins-rbac.yaml" "${ARTIFACT_DIR}/${namespace}/" # Save the final value-file into the artifacts directory. + kubectl apply -f /tmp/configmap-dynamic-plugins-rbac.yaml -n "${namespace}" + + setup_image_pull_secret "${namespace}" "rh-pull-secret" "${REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON}" + + deploy_rhdh_operator "${namespace}" "${DIR}/resources/rhdh-operator/rhdh-start-rbac_K8s.yaml" + + apply_eks_operator_ingress "$namespace" "backstage-$RELEASE_NAME_RBAC" +} + +apply_eks_operator_ingress() { + local namespace=$1 + local service_name=$2 + envsubst < "$DIR/cluster/eks/manifest/eks-operator-ingress.yaml" \ + | yq ".spec.rules[0].http.paths[0].backend.service.name = \"$service_name\"" - \ + | kubectl apply --namespace="${namespace}" -f - +} + +cleanup_eks_deployment() { + local namespace=$1 + delete_namespace "$namespace" +} diff --git a/.ibm/pipelines/cluster/eks/manifest/eks-operator-ingress.yaml b/.ibm/pipelines/cluster/eks/manifest/eks-operator-ingress.yaml new file mode 100644 index 0000000000..c97b653f30 --- /dev/null +++ b/.ibm/pipelines/cluster/eks/manifest/eks-operator-ingress.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: dh-ingress + annotations: + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/target-type: ip + alb.ingress.kubernetes.io/certificate-arn: $EKS_DOMAIN_NAME_CERTIFICATE_ARN + alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' + alb.ingress.kubernetes.io/ssl-redirect: "443" + external-dns.alpha.kubernetes.io/hostname: $EKS_INSTANCE_DOMAIN_NAME +spec: + ingressClassName: alb + rules: + - host: $EKS_INSTANCE_DOMAIN_NAME + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: developer-hub-dh-ingress + port: + name: http-backend diff --git a/.ibm/pipelines/cluster/gke/auto-label/README.md b/.ibm/pipelines/cluster/gke/auto-label/README.md index 5c497818d8..eeefef4397 100644 --- a/.ibm/pipelines/cluster/gke/auto-label/README.md +++ b/.ibm/pipelines/cluster/gke/auto-label/README.md @@ -1,6 +1,8 @@ # 🏷️ GKE Cluster Auto-Labeler -This project automatically applies standardized labels to new Google Kubernetes Engine (GKE) clusters in the `rhdh-qe` GCP project. The system uses Cloud Functions triggered by EventArc to monitor cluster creation events and apply labels immediately. +This project automatically applies standardized labels to new Google Kubernetes Engine (GKE) +clusters in the `rhdh-qe` GCP project. The system uses Cloud Functions triggered by EventArc to +monitor cluster creation events and apply labels immediately. ## Overview diff --git a/.ibm/pipelines/cluster/gke/auto-label/apply-labels-manual.sh b/.ibm/pipelines/cluster/gke/auto-label/apply-labels-manual.sh index 5d6ee65e54..d44f994dc1 100755 --- a/.ibm/pipelines/cluster/gke/auto-label/apply-labels-manual.sh +++ b/.ibm/pipelines/cluster/gke/auto-label/apply-labels-manual.sh @@ -12,7 +12,7 @@ readonly PROJECT_ID="rhdh-qe" # === FUNCTIONS === show_usage() { - cat << EOF + cat << EOF Usage: $0 [CLUSTER_NAME] [LOCATION] This script applies the following standard labels to GKE clusters: @@ -36,79 +36,79 @@ EOF } list_clusters() { - echo ">>> Listing available clusters in project $PROJECT_ID..." - gcloud container clusters list \ - --project="$PROJECT_ID" \ - --format="table(name,location,status)" \ - --quiet + echo ">>> Listing available clusters in project $PROJECT_ID..." + gcloud container clusters list \ + --project="$PROJECT_ID" \ + --format="table(name,location,status)" \ + --quiet } apply_cluster_labels() { - local cluster_name="$1" - local location="$2" - - echo ">>> Applying labels to cluster: $cluster_name" - echo ">>> Location: $location" - echo ">>> Labels: $LABELS" - - # Determine if it's a zone or region - if [[ "$location" =~ ^[a-z]+-[a-z]+[0-9]+$ ]]; then - location_flag="--region" - else - location_flag="--zone" - fi - - # Apply the labels - gcloud container clusters update "$cluster_name" \ - "$location_flag" "$location" \ - --update-labels "$LABELS" \ - --project="$PROJECT_ID" \ - --quiet - - echo "✅ Labels successfully applied to cluster $cluster_name!" - - # Verify applied labels - echo ">>> Verifying applied labels..." - gcloud container clusters describe "$cluster_name" \ - "$location_flag" "$location" \ - --project="$PROJECT_ID" \ - --format="value(resourceLabels)" \ - --quiet + local cluster_name="$1" + local location="$2" + + echo ">>> Applying labels to cluster: $cluster_name" + echo ">>> Location: $location" + echo ">>> Labels: $LABELS" + + # Determine if it's a zone or region + if [[ "$location" =~ ^[a-z]+-[a-z]+[0-9]+$ ]]; then + location_flag="--region" + else + location_flag="--zone" + fi + + # Apply the labels + gcloud container clusters update "$cluster_name" \ + "$location_flag" "$location" \ + --update-labels "$LABELS" \ + --project="$PROJECT_ID" \ + --quiet + + echo "✅ Labels successfully applied to cluster $cluster_name!" + + # Verify applied labels + echo ">>> Verifying applied labels..." + gcloud container clusters describe "$cluster_name" \ + "$location_flag" "$location" \ + --project="$PROJECT_ID" \ + --format="value(resourceLabels)" \ + --quiet } interactive_cluster_selection() { - # List clusters - list_clusters - - echo "" - read -p "Enter cluster name: " cluster_name - read -p "Enter location (zone or region): " location - - if [[ -z "$cluster_name" || -z "$location" ]]; then - echo "❌ Error: Cluster name and location are required" - exit 1 - fi - - apply_cluster_labels "$cluster_name" "$location" + # List clusters + list_clusters + + echo "" + read -p "Enter cluster name: " cluster_name + read -p "Enter location (zone or region): " location + + if [[ -z "$cluster_name" || -z "$location" ]]; then + echo "❌ Error: Cluster name and location are required" + exit 1 + fi + + apply_cluster_labels "$cluster_name" "$location" } apply_all_clusters() { - echo ">>> Applying labels to ALL clusters in project $PROJECT_ID..." - - # Get cluster list in JSON format - local clusters_json - clusters_json=$(gcloud container clusters list \ - --project="$PROJECT_ID" \ - --format="json" \ - --quiet) - - if [[ "$clusters_json" == "[]" ]]; then - echo "❌ No clusters found in project $PROJECT_ID" - exit 1 - fi - - # Process each cluster - echo "$clusters_json" | python3 -c " + echo ">>> Applying labels to ALL clusters in project $PROJECT_ID..." + + # Get cluster list in JSON format + local clusters_json + clusters_json=$(gcloud container clusters list \ + --project="$PROJECT_ID" \ + --format="json" \ + --quiet) + + if [[ "$clusters_json" == "[]" ]]; then + echo "❌ No clusters found in project $PROJECT_ID" + exit 1 + fi + + # Process each cluster + echo "$clusters_json" | python3 -c " import json import sys import subprocess @@ -142,36 +142,36 @@ for cluster in clusters: except subprocess.CalledProcessError as e: print(f'❌ Error applying labels to cluster {name}: {e}') " - - echo ">>> Complete! Verifying all clusters..." - gcloud container clusters list \ - --project="$PROJECT_ID" \ - --format="table(name,location,resourceLabels)" \ - --quiet + + echo ">>> Complete! Verifying all clusters..." + gcloud container clusters list \ + --project="$PROJECT_ID" \ + --format="table(name,location,resourceLabels)" \ + --quiet } # === MAIN SCRIPT === case "${1:-}" in - -h|--help) - show_usage - exit 0 - ;; - --all) - apply_all_clusters - exit 0 - ;; - "") - # Interactive mode - interactive_cluster_selection - ;; - *) - # Arguments provided - if [[ -z "${2:-}" ]]; then - echo "❌ Error: Location is required when cluster name is provided" - show_usage - exit 1 - fi - apply_cluster_labels "$1" "$2" - ;; -esac \ No newline at end of file + -h | --help) + show_usage + exit 0 + ;; + --all) + apply_all_clusters + exit 0 + ;; + "") + # Interactive mode + interactive_cluster_selection + ;; + *) + # Arguments provided + if [[ -z "${2:-}" ]]; then + echo "❌ Error: Location is required when cluster name is provided" + show_usage + exit 1 + fi + apply_cluster_labels "$1" "$2" + ;; +esac diff --git a/.ibm/pipelines/cluster/gke/auto-label/deploy-auto-labeler.sh b/.ibm/pipelines/cluster/gke/auto-label/deploy-auto-labeler.sh index b60775cb42..bab75e9e15 100755 --- a/.ibm/pipelines/cluster/gke/auto-label/deploy-auto-labeler.sh +++ b/.ibm/pipelines/cluster/gke/auto-label/deploy-auto-labeler.sh @@ -24,14 +24,14 @@ gcloud services enable \ --quiet echo ">>> Creating GCS bucket (if not exists)..." -if ! gsutil ls -b "gs://${BUCKET_NAME}" >/dev/null 2>&1; then +if ! gsutil ls -b "gs://${BUCKET_NAME}" > /dev/null 2>&1; then gsutil mb -p "$PROJECT_ID" -l "$REGION" "gs://${BUCKET_NAME}" else echo "Bucket already exists." fi echo ">>> Creating service account (if not exists)..." -if ! gcloud iam service-accounts describe "$SERVICE_ACCOUNT_EMAIL" --quiet >/dev/null 2>&1; then +if ! gcloud iam service-accounts describe "$SERVICE_ACCOUNT_EMAIL" --quiet > /dev/null 2>&1; then gcloud iam service-accounts create "$SERVICE_ACCOUNT_NAME" \ --description="Service Account to label clusters" \ --display-name="Cluster Labeler" \ diff --git a/.ibm/pipelines/cluster/gke/gcloud.sh b/.ibm/pipelines/cluster/gke/gcloud.sh index aa2ad140c5..694660afff 100755 --- a/.ibm/pipelines/cluster/gke/gcloud.sh +++ b/.ibm/pipelines/cluster/gke/gcloud.sh @@ -23,16 +23,11 @@ gcloud_ssl_cert_create() { local domain=$2 local project=$3 - # Capture both stdout and stderr - set +e local output - output=$(gcloud compute ssl-certificates create "${cert_name}" --domains="${domain}" --project="${project}" --global 2>&1) - set -e + output=$(gcloud compute ssl-certificates create "${cert_name}" --domains="${domain}" --project="${project}" --global 2>&1) || true - # Check the return status - if [ $? -eq 0 ]; then - echo "Certificate '${cert_name}' created successfully.\nThe test might fail if the certificate is not obtained from the certificate authority in time." - else + # Check if the output contains ERROR + if echo "$output" | grep -q "ERROR"; then # Check if the error is due to certificate already existing if echo "$output" | grep -q "already exists"; then echo "Certificate '${cert_name}' already exists, continuing..." @@ -41,6 +36,9 @@ gcloud_ssl_cert_create() { echo "$output" exit 1 fi + else + echo "Certificate '${cert_name}' created successfully." + echo "The test might fail if the certificate is not obtained from the certificate authority in time." fi } diff --git a/.ibm/pipelines/cluster/gke/gke-helm-deployment.sh b/.ibm/pipelines/cluster/gke/gke-helm-deployment.sh index 3ddf356352..55face23e0 100644 --- a/.ibm/pipelines/cluster/gke/gke-helm-deployment.sh +++ b/.ibm/pipelines/cluster/gke/gke-helm-deployment.sh @@ -10,8 +10,11 @@ source "$DIR"/cluster/gke/manifest.sh initiate_gke_helm_deployment() { delete_namespace "${NAME_SPACE_RBAC}" configure_namespace "${NAME_SPACE}" - deploy_redis_cache "${namespace}" + + deploy_redis_cache "${NAME_SPACE}" + uninstall_helmchart "${NAME_SPACE}" "${RELEASE_NAME}" + cd "${DIR}" || exit local rhdh_base_url="https://${K8S_CLUSTER_ROUTER_BASE}" apply_yaml_files "${DIR}" "${NAME_SPACE}" "${rhdh_base_url}" @@ -19,6 +22,9 @@ initiate_gke_helm_deployment() { yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_VALUE_FILE_NAME}" "${DIR}/value_files/${HELM_CHART_GKE_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" mkdir -p "${ARTIFACT_DIR}/${NAME_SPACE}" cp -a "/tmp/${HELM_CHART_K8S_MERGED_VALUE_FILE_NAME}" "${ARTIFACT_DIR}/${NAME_SPACE}/" # Save the final value-file into the artifacts directory. + + setup_image_pull_secret "${NAME_SPACE}" "rh-pull-secret" "${REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON}" + echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE}" helm upgrade -i "${RELEASE_NAME}" -n "${NAME_SPACE}" \ "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ @@ -32,17 +38,21 @@ initiate_gke_helm_deployment() { initiate_rbac_gke_helm_deployment() { delete_namespace "${NAME_SPACE}" configure_namespace "${NAME_SPACE_RBAC}" + uninstall_helmchart "${NAME_SPACE_RBAC}" "${RELEASE_NAME_RBAC}" + cd "${DIR}" || exit local rbac_rhdh_base_url="https://${K8S_CLUSTER_ROUTER_BASE}" - apply_yaml_files "${DIR}" "${NAME_SPACE_RBAC}" "${rbac_rhdh_base_url}" + apply_yaml_files "${DIR}" "${NAME_SPACE_RBAC}" "${rbac_rhdh_base_url}" apply_gke_frontend_config "${NAME_SPACE_RBAC}" yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_RBAC_VALUE_FILE_NAME}" "${DIR}/value_files/${HELM_CHART_RBAC_GKE_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" mkdir -p "${ARTIFACT_DIR}/${NAME_SPACE_RBAC}" cp -a "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" "${ARTIFACT_DIR}/${NAME_SPACE_RBAC}/" # Save the final value-file into the artifacts directory. + + setup_image_pull_secret "${NAME_SPACE_RBAC}" "rh-pull-secret" "${REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON}" echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE_RBAC}" helm upgrade -i "${RELEASE_NAME_RBAC}" -n "${NAME_SPACE_RBAC}" \ - "${HELM_REPO_NAME}/${HELM_IMAGE_NAME}" --version "${CHART_VERSION}" \ + "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ -f "/tmp/${HELM_CHART_RBAC_K8S_MERGED_VALUE_FILE_NAME}" \ --set global.host="${K8S_CLUSTER_ROUTER_BASE}" \ --set upstream.backstage.image.repository="${QUAY_REPO}" \ diff --git a/.ibm/pipelines/cluster/gke/manifest.sh b/.ibm/pipelines/cluster/gke/manifest.sh index 2f897bb6cb..3f845c0087 100644 --- a/.ibm/pipelines/cluster/gke/manifest.sh +++ b/.ibm/pipelines/cluster/gke/manifest.sh @@ -12,4 +12,4 @@ apply_gke_operator_ingress() { echo "Applying GKE Ingress" export SERVICE_NAME=$service_name envsubst < "${DIR}/cluster/gke/manifest/gke-operator-ingress.yaml" | kubectl apply --namespace="${namespace}" -f - -} \ No newline at end of file +} diff --git a/.ibm/pipelines/cluster/gke/manifest/gke-operator-ingress.yaml b/.ibm/pipelines/cluster/gke/manifest/gke-operator-ingress.yaml index e12c89b6ad..8a351b2eaa 100644 --- a/.ibm/pipelines/cluster/gke/manifest/gke-operator-ingress.yaml +++ b/.ibm/pipelines/cluster/gke/manifest/gke-operator-ingress.yaml @@ -14,10 +14,10 @@ spec: - host: $K8S_CLUSTER_ROUTER_BASE http: paths: - - path: / - pathType: Prefix - backend: - service: - name: $SERVICE_NAME - port: - name: http-backend + - path: / + pathType: Prefix + backend: + service: + name: $SERVICE_NAME + port: + name: http-backend diff --git a/.ibm/pipelines/cluster/ibm/create-openshift-cluster.sh b/.ibm/pipelines/cluster/ibm/create-openshift-cluster.sh index ef81992d02..ff1be6f040 100755 --- a/.ibm/pipelines/cluster/ibm/create-openshift-cluster.sh +++ b/.ibm/pipelines/cluster/ibm/create-openshift-cluster.sh @@ -15,12 +15,12 @@ show_menu() { done read -p "Select an option [1-${#options[@]}]: " choice - if ! [[ "$choice" =~ ^[0-9]+$ ]] || (( choice < 1 || choice > ${#options[@]} )); then + if ! [[ "$choice" =~ ^[0-9]+$ ]] || ((choice < 1 || choice > ${#options[@]})); then echo "❌ Invalid choice" exit 1 fi - echo "${options[$((choice-1))]}" + echo "${options[$((choice - 1))]}" } # Login to IBM Cloud diff --git a/.ibm/pipelines/cluster/k8s/k8s-utils.sh b/.ibm/pipelines/cluster/k8s/k8s-utils.sh index 15d5e11183..c8a500997b 100644 --- a/.ibm/pipelines/cluster/k8s/k8s-utils.sh +++ b/.ibm/pipelines/cluster/k8s/k8s-utils.sh @@ -6,7 +6,7 @@ re_create_k8s_service_account_and_get_token() { local sa_binding_name="${sa_name}-binding" local sa_secret_name="${sa_name}-secret" local token - if token="$(kubectl get secret ${sa_secret_name} -n ${sa_namespace} -o jsonpath='{.data.token}' 2>/dev/null)"; then + if token="$(kubectl get secret ${sa_secret_name} -n ${sa_namespace} -o jsonpath='{.data.token}' 2> /dev/null)"; then K8S_CLUSTER_TOKEN=$(echo "${token}" | base64 --decode) echo "Acquired existing token for the service account into K8S_CLUSTER_TOKEN" else @@ -16,14 +16,14 @@ re_create_k8s_service_account_and_get_token() { kubectl create serviceaccount ${sa_name} -n ${sa_namespace} echo "Creating cluster role binding..." kubectl create clusterrolebinding ${sa_binding_name} \ - --clusterrole=cluster-admin \ - --serviceaccount=${sa_namespace}:${sa_name} + --clusterrole=cluster-admin \ + --serviceaccount=${sa_namespace}:${sa_name} echo "Service account and binding created successfully" else echo "Service account ${sa_name} already exists in namespace ${sa_namespace}" fi echo "Creating secret for service account" - kubectl apply --namespace="${sa_namespace}" -f - < Automated scripts for managing OpenShift Dedicated clusters on Google Cloud Platform using OCM CLI. +> Automated scripts for managing OpenShift Dedicated clusters on Google Cloud Platform using OCM +> CLI. ## 🔧 Prerequisites @@ -14,22 +15,25 @@ Before you begin, ensure you have: ### Setting Up Service Accounts #### 1. GCP Service Account -- Obtain the GCP service account JSON from [here](https://vault.ci.openshift.org/ui/vault/secrets/kv/kv/selfservice%2Frhdh-qe%2Fosd-gcp) + +- Obtain the GCP service account JSON from + [here](https://vault.ci.openshift.org/ui/vault/secrets/kv/kv/selfservice%2Frhdh-qe%2Fosd-gcp) - Look for the `gcp_service_account_json` secret - Save this JSON file as your service account file - Reference this file in the `--service-account-file` parameter in create-osd.sh #### 2. OCM Service Account + 1. Visit [Red Hat Console IAM Service Accounts](https://console.redhat.com/iam/service-accounts) 2. Click "Create service account" 3. Fill in the required information 4. Save the generated CLIENT_ID and CLIENT_SECRET 5. Use these credentials in your environment variables - ## ⚙️ Configuration Make scripts executable: + ```bash chmod +x create-osd.sh destroy-osd.sh ``` @@ -57,6 +61,7 @@ export CLUSTER_NAME="your-cluster-name" ``` This will: + 1. Create a new OSD cluster on GCP 2. Set up HTPasswd authentication 3. Configure admin user @@ -76,6 +81,7 @@ This will remove all clusters matching the specified name pattern. ### `create-osd.sh` Creates an OpenShift Dedicated cluster with the following specifications: + - OSD Version: 4.16.16 - Region: us-east1 - Provider: GCP @@ -83,24 +89,26 @@ Creates an OpenShift Dedicated cluster with the following specifications: #### Output Files -| File | Description | -|------|-------------| -| `cluster-info.name` | Cluster name | -| `cluster-info.id` | Cluster ID | +| File | Description | +| --------------------- | ------------------------------ | +| `cluster-info.name` | Cluster name | +| `cluster-info.id` | Cluster ID | | `cluster-config.yaml` | Access details and credentials | -| `kubeconfig` | Kubernetes configuration | -| `cluster-info.yaml` | Detailed cluster information | +| `kubeconfig` | Kubernetes configuration | +| `cluster-info.yaml` | Detailed cluster information | ### `destroy-osd.sh` Handles cluster cleanup: + - Identifies clusters by name pattern - Initiates deletion process - Monitors uninstallation progress ### ⚠️ GitHub Authentication Limitation -> **Important**: Due to GitHub App limitations, GitHub login functionality will not work in ephemeral environments. +> **Important**: Due to GitHub App limitations, GitHub login functionality will not work in +> ephemeral environments. ### 🧪 Running Tests on OSD Cluster @@ -112,6 +120,7 @@ To run existing tests on an OSD cluster: - `RHDH_OSD_GCP_CLUSTER_TOKEN`: Your cluster's access token 2. Modify your `openshift-ci-tests.sh` to use OSD cluster: + ```bash # Add these lines to set_cluster_info function export K8S_CLUSTER_URL=$(cat /tmp/secrets/RHDH_OSD_GCP_CLUSTER_URL) @@ -126,4 +135,3 @@ export K8S_CLUSTER_TOKEN=$(cat /tmp/secrets/RHDH_OSD_GCP_CLUSTER_TOKEN) - Creation time: ~30-45 minutes - Deletion time: ~15-30 minutes - Uses latest OpenShift client binaries - diff --git a/.ibm/pipelines/cluster/osd-gcp/create-osd.sh b/.ibm/pipelines/cluster/osd-gcp/create-osd.sh index 477803d3df..0472fa8422 100755 --- a/.ibm/pipelines/cluster/osd-gcp/create-osd.sh +++ b/.ibm/pipelines/cluster/osd-gcp/create-osd.sh @@ -11,14 +11,14 @@ SERVICE_ACCOUNT_FILE="${SERVICE_ACCOUNT_FILE:-$(cat /tmp/osdsecrets/SERVICE_ACCO OSD_VERSION="${OSD_VERSION:-4.17.12}" if [ -n "$CLUSTER_NAME" ]; then - echo $CLUSTER_NAME > $WORKSPACE/cluster-info.name + echo $CLUSTER_NAME > $WORKSPACE/cluster-info.name fi if [ -f $WORKSPACE/cluster-info.name ]; then - CLUSTER_NAME="$(cat $WORKSPACE/cluster-info.name)" + CLUSTER_NAME="$(cat $WORKSPACE/cluster-info.name)" else - CLUSTER_NAME="osdgcp-$(date +%m%d)" - echo $CLUSTER_NAME > $WORKSPACE/cluster-info.name + CLUSTER_NAME="osdgcp-$(date +%m%d)" + echo $CLUSTER_NAME > $WORKSPACE/cluster-info.name fi echo "Working with cluster '$CLUSTER_NAME'" @@ -33,22 +33,21 @@ SERVICE_ACCOUNT_FILE=$WORKSPACE/gcp_service_account_json.json # OSD_VERSION=${OSD_VERSION:-$(ocm list versions | tail -n1)} echo "creating OSD_VERSION : $OSD_VERSION" - -ocm create cluster --ccs --provider gcp --region us-west1 --service-account-file $SERVICE_ACCOUNT_FILE --subscription-type marketplace-gcp --marketplace-gcp-terms --version "$OSD_VERSION" "$CLUSTER_NAME" -CLUSTER_ID=$(ocm list clusters --columns "id,name" | grep $CLUSTER_NAME| cut -d " " -f1) +ocm create cluster --ccs --provider gcp --region us-west1 --service-account-file $SERVICE_ACCOUNT_FILE --subscription-type marketplace-gcp --marketplace-gcp-terms --version "$OSD_VERSION" "$CLUSTER_NAME" +CLUSTER_ID=$(ocm list clusters --columns "id,name" | grep $CLUSTER_NAME | cut -d " " -f1) echo "CLUSTER_ID : $CLUSTER_ID" echo $CLUSTER_ID > $WORKSPACE/cluster-info.id if [[ -z "$CLUSTER_ID" ]]; then - echo "Cluster $CLUSTER_NAME not found..."; - exit 0; + echo "Cluster $CLUSTER_NAME not found..." + exit 0 fi while [[ -z $(ocm cluster status $CLUSTER_ID | grep "State:.*ready") ]]; do - echo "Waiting for cluster $CLUSTER_ID to get ready..."; - sleep 30; + echo "Waiting for cluster $CLUSTER_ID to get ready..." + sleep 30 done echo "Creating kubeadmin user" @@ -68,15 +67,15 @@ export KUBECONFIG=$WORKSPACE/kubeconfig rm -rvf $KUBECONFIG CLUSTER_API_URL=$(ocm describe cluster $CLUSTER_ID --json | jq -rc '.api.url') for i in {1..50}; do - echo "Attempt $i: Logging in..." - if oc login "$CLUSTER_API_URL" --username "$KUBEADMIN_USER" --password "$KUBEADMIN_PASSWORD" --insecure-skip-tls-verify=true; then - echo "Login successful!" - ocm describe cluster $CLUSTER_ID > $WORKSPACE/cluster-info.yaml - exit 0 - fi - echo "Login failed. Retrying in 30 seconds..." - sleep 30 + echo "Attempt $i: Logging in..." + if oc login "$CLUSTER_API_URL" --username "$KUBEADMIN_USER" --password "$KUBEADMIN_PASSWORD" --insecure-skip-tls-verify=true; then + echo "Login successful!" + ocm describe cluster $CLUSTER_ID > $WORKSPACE/cluster-info.yaml + exit 0 + fi + echo "Login failed. Retrying in 30 seconds..." + sleep 30 done echo "Exceeded maximum retries. Login failed." -exit 1 \ No newline at end of file +exit 1 diff --git a/.ibm/pipelines/cluster/osd-gcp/destroy-osd.sh b/.ibm/pipelines/cluster/osd-gcp/destroy-osd.sh index 1de8c095a6..7622fb78cc 100755 --- a/.ibm/pipelines/cluster/osd-gcp/destroy-osd.sh +++ b/.ibm/pipelines/cluster/osd-gcp/destroy-osd.sh @@ -17,4 +17,4 @@ ocm delete /api/clusters_mgmt/v1/clusters/$CLUSTER_ID # while [[ -z $(ocm cluster status $CLUSTER_ID 2>&1 | grep "not found") ]]; do # echo "Waiting for cluster $CLUSTER_ID to be completely uninstalled..."; # sleep 30; -# done \ No newline at end of file +# done diff --git a/.ibm/pipelines/env_variables.sh b/.ibm/pipelines/env_variables.sh index 757742a26e..2d8e2a73ef 100755 --- a/.ibm/pipelines/env_variables.sh +++ b/.ibm/pipelines/env_variables.sh @@ -1,5 +1,29 @@ #!/bin/bash -set -a # Automatically export all variables +# shellcheck disable=SC2034 +set -a # Automatically export all variables + +# Define log file names and directories. +LOGFILE="test-log" + +# Populated by OpenShift CI or the initial CI scripts +# Addition to JOB_NAME, TAG_NAME, SHARED_DIR, ARTIFACT_DIR +# This prevents nounset errors when running locally +# https://docs.ci.openshift.org/docs/architecture/step-registry/#available-environment-variables +# https://docs.prow.k8s.io/docs/jobs/#job-environment-variables +JOB_NAME="${JOB_NAME:-unknown-job}" +TAG_NAME="${TAG_NAME:-}" +OPENSHIFT_CI="${OPENSHIFT_CI:-false}" +REPO_OWNER="${REPO_OWNER:-redhat-developer}" +REPO_NAME="${REPO_NAME:-rhdh}" +PULL_NUMBER="${PULL_NUMBER:-}" +BUILD_ID="${BUILD_ID:-unknown-build}" +RELEASE_BRANCH_NAME="${RELEASE_BRANCH_NAME:-main}" +K8S_CLUSTER_TOKEN="${K8S_CLUSTER_TOKEN:-}" +K8S_CLUSTER_URL="${K8S_CLUSTER_URL:-}" +SHARED_DIR="${SHARED_DIR:-$DIR/shared_dir}" +ARTIFACT_DIR="${ARTIFACT_DIR:-$DIR/artifact_dir}" +mkdir -p "${SHARED_DIR}" +mkdir -p "${ARTIFACT_DIR}" #ENVS and Vault Secrets HELM_CHART_VALUE_FILE_NAME="values_showcase.yaml" @@ -10,6 +34,8 @@ HELM_CHART_AKS_DIFF_VALUE_FILE_NAME="diff-values_showcase_AKS.yaml" HELM_CHART_RBAC_AKS_DIFF_VALUE_FILE_NAME="diff-values_showcase-rbac_AKS.yaml" HELM_CHART_GKE_DIFF_VALUE_FILE_NAME="diff-values_showcase_GKE.yaml" HELM_CHART_RBAC_GKE_DIFF_VALUE_FILE_NAME="diff-values_showcase-rbac_GKE.yaml" +HELM_CHART_EKS_DIFF_VALUE_FILE_NAME="diff-values_showcase_EKS.yaml" +HELM_CHART_RBAC_EKS_DIFF_VALUE_FILE_NAME="diff-values_showcase-rbac_EKS.yaml" HELM_CHART_SANITY_PLUGINS_DIFF_VALUE_FILE_NAME="diff-values_showcase-sanity-plugins.yaml" HELM_CHART_SANITY_PLUGINS_MERGED_VALUE_FILE_NAME="merged-values_showcase-sanity-plugins.yaml" @@ -31,8 +57,7 @@ NAME_SPACE_RUNTIME="${NAME_SPACE_RUNTIME:-showcase-runtime}" NAME_SPACE_POSTGRES_DB="${NAME_SPACE_POSTGRES_DB:-postgress-external-db}" NAME_SPACE_SANITY_PLUGINS_CHECK="showcase-sanity-plugins" OPERATOR_MANAGER='rhdh-operator' -CHART_MAJOR_VERSION=1.7 -CHART_VERSION_BASE="1.5.2" +CHART_MAJOR_VERSION="1.8" GITHUB_APP_APP_ID=$(cat /tmp/secrets/GITHUB_APP_3_APP_ID) GITHUB_APP_CLIENT_ID=$(cat /tmp/secrets/GITHUB_APP_3_CLIENT_ID) GITHUB_APP_PRIVATE_KEY=$(cat /tmp/secrets/GITHUB_APP_3_PRIVATE_KEY) @@ -97,20 +122,14 @@ RDS_2_HOST=$(cat /tmp/secrets/RDS_2_HOST) RDS_3_HOST=$(cat /tmp/secrets/RDS_3_HOST) JUNIT_RESULTS="junit-results.xml" -DATA_ROUTER_URL=$(cat /tmp/secrets/DATA_ROUTER_URL) -DATA_ROUTER_USERNAME=$(cat /tmp/secrets/DATA_ROUTER_USERNAME) -DATA_ROUTER_PASSWORD=$(cat /tmp/secrets/DATA_ROUTER_PASSWORD) -DATA_ROUTER_PROJECT="main" -DATA_ROUTER_AUTO_FINALIZATION_TRESHOLD=$(cat /tmp/secrets/DATA_ROUTER_AUTO_FINALIZATION_TRESHOLD) -DATA_ROUTER_NEXUS_HOSTNAME=$(cat /tmp/secrets/DATA_ROUTER_NEXUS_HOSTNAME) -REPORTPORTAL_HOSTNAME=$(cat /tmp/secrets/REPORTPORTAL_HOSTNAME) + SLACK_DATA_ROUTER_WEBHOOK_URL=$(cat /tmp/secrets/SLACK_DATA_ROUTER_WEBHOOK_URL) -SLACK_NIGHTLY_WEBHOOK_URL=$(cat /tmp/secrets/SLACK_NIGHTLY_WEBHOOK_URL) REDIS_USERNAME=temp REDIS_USERNAME_ENCODED=$(printf "%s" $REDIS_USERNAME | base64 | tr -d '\n') REDIS_PASSWORD=test123 REDIS_PASSWORD_ENCODED=$(printf "%s" $REDIS_PASSWORD | base64 | tr -d '\n') +# GKE variables GKE_CLUSTER_NAME=$(cat /tmp/secrets/GKE_CLUSTER_NAME) GKE_CLUSTER_REGION=$(cat /tmp/secrets/GKE_CLUSTER_REGION) GKE_INSTANCE_DOMAIN_NAME=$(cat /tmp/secrets/GKE_INSTANCE_DOMAIN_NAME) @@ -118,8 +137,13 @@ GKE_SERVICE_ACCOUNT_NAME=$(cat /tmp/secrets/GKE_SERVICE_ACCOUNT_NAME) GKE_CERT_NAME=$(cat /tmp/secrets/GKE_CERT_NAME) GOOGLE_CLOUD_PROJECT=$(cat /tmp/secrets/GOOGLE_CLOUD_PROJECT) -# authentication providers variables +# EKS variables +AWS_ACCESS_KEY_ID=$(cat /tmp/secrets/AWS_ACCESS_KEY_ID) +AWS_SECRET_ACCESS_KEY=$(cat /tmp/secrets/AWS_SECRET_ACCESS_KEY) +AWS_DEFAULT_REGION=$(cat /tmp/secrets/AWS_DEFAULT_REGION) +AWS_EKS_PARENT_DOMAIN=$(cat /tmp/secrets/AWS_EKS_PARENT_DOMAIN) +# authentication providers variables RHBK_BASE_URL=$(cat /tmp/secrets/AUTH_PROVIDERS_RHBK_BASE_URL) RHBK_CLIENT_SECRET=$(cat /tmp/secrets/AUTH_PROVIDERS_RHBK_CLIENT_SECRET) RHBK_CLIENT_ID=$(cat /tmp/secrets/AUTH_PROVIDERS_RHBK_CLIENT_ID) @@ -161,10 +185,14 @@ KEYCLOAK_AUTH_REALM=$(cat /tmp/secrets/KEYCLOAK_AUTH_REALM) REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON=$(cat /tmp/secrets/REGISTRY_REDHAT_IO_SERVICE_ACCOUNT_DOCKERCONFIGJSON) IS_OPENSHIFT="" +CONTAINER_PLATFORM="" +CONTAINER_PLATFORM_VERSION="" GITHUB_OAUTH_APP_ID=$(cat /tmp/secrets/GITHUB_OAUTH_APP_ID) GITHUB_OAUTH_APP_SECRET=$(cat /tmp/secrets/GITHUB_OAUTH_APP_SECRET) GITHUB_OAUTH_APP_ID_ENCODED=$(printf "%s" $GITHUB_OAUTH_APP_ID | base64 | tr -d '\n') GITHUB_OAUTH_APP_SECRET_ENCODED=$(printf "%s" $GITHUB_OAUTH_APP_SECRET | base64 | tr -d '\n') -set +a # Stop automatically exporting variables +BACKEND_SECRET=$(printf temp | base64 | tr -d '\n') + +set +a # Stop automatically exporting variables diff --git a/.ibm/pipelines/install-methods/operator.sh b/.ibm/pipelines/install-methods/operator.sh index d2d73e8ed0..4e0585599e 100755 --- a/.ibm/pipelines/install-methods/operator.sh +++ b/.ibm/pipelines/install-methods/operator.sh @@ -4,9 +4,8 @@ source "$DIR"/utils.sh install_rhdh_operator() { - local dir=$1 - local namespace=$2 - local max_attempts=$3 + local namespace=$1 + local max_attempts=$2 configure_namespace "$namespace" @@ -35,6 +34,10 @@ install_rhdh_operator() { done else local operator_version="${RELEASE_BRANCH_NAME#release-}" + if [[ -z "$operator_version" ]]; then + echo "Error: Failed to extract operator version from RELEASE_BRANCH_NAME: '$RELEASE_BRANCH_NAME'" + return 1 + fi echo "Installing RHDH operator with '-v $operator_version' flag" for ((i = 1; i <= max_attempts; i++)); do if output=$(bash -x /tmp/install-rhdh-catalog-source.sh -v "$operator_version" --install-operator rhdh); then @@ -53,7 +56,7 @@ install_rhdh_operator() { prepare_operator() { local retry_operator_installation="${1:-1}" configure_namespace "${OPERATOR_MANAGER}" - install_rhdh_operator "${DIR}" "${OPERATOR_MANAGER}" "$retry_operator_installation" + install_rhdh_operator "${OPERATOR_MANAGER}" "$retry_operator_installation" } wait_for_backstage_crd() { diff --git a/.ibm/pipelines/jobs/auth-providers.sh b/.ibm/pipelines/jobs/auth-providers.sh index b7132cbf2d..fcd9e24e3c 100644 --- a/.ibm/pipelines/jobs/auth-providers.sh +++ b/.ibm/pipelines/jobs/auth-providers.sh @@ -2,20 +2,23 @@ # shellcheck source=.ibm/pipelines/utils.sh source "$DIR"/utils.sh +# shellcheck source=.ibm/pipelines/install-methods/operator.sh source "$DIR"/install-methods/operator.sh handle_auth_providers() { local retry_operator_installation="${1:-1}" oc_login configure_namespace "${OPERATOR_MANAGER}" - install_rhdh_operator "${DIR}" "${OPERATOR_MANAGER}" "$retry_operator_installation" + install_rhdh_operator "${OPERATOR_MANAGER}" "$retry_operator_installation" wait_for_backstage_crd "default" - export K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') + K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') + export K8S_CLUSTER_ROUTER_BASE export AUTH_PROVIDERS_RELEASE="rhdh-auth-providers" export AUTH_PROVIDERS_NAMESPACE="showcase-auth-providers" - export LOGS_FOLDER="$(pwd)/e2e-tests/auth-providers-logs" + LOGS_FOLDER="$(pwd)/e2e-tests/auth-providers-logs" + export LOGS_FOLDER echo "Running tests ${AUTH_PROVIDERS_RELEASE} in ${AUTH_PROVIDERS_NAMESPACE}" run_tests "${AUTH_PROVIDERS_RELEASE}" "${AUTH_PROVIDERS_NAMESPACE}" diff --git a/.ibm/pipelines/jobs/eks-helm.sh b/.ibm/pipelines/jobs/eks-helm.sh new file mode 100644 index 0000000000..d64a6a47b4 --- /dev/null +++ b/.ibm/pipelines/jobs/eks-helm.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# shellcheck source=.ibm/pipelines/utils.sh +source "$DIR"/utils.sh +# shellcheck source=.ibm/pipelines/cluster/eks/eks-helm-deployment.sh +source "$DIR"/cluster/eks/eks-helm-deployment.sh +# shellcheck source=.ibm/pipelines/cluster/eks/aws.sh +source "$DIR"/cluster/eks/aws.sh +# shellcheck source=.ibm/pipelines/cluster/k8s/k8s-utils.sh +source "$DIR"/cluster/k8s/k8s-utils.sh + +handle_eks_helm() { + echo "Starting EKS Helm deployment" + + # Verify EKS cluster connectivity + aws_eks_verify_cluster + + # Get cluster information + aws_eks_get_cluster_info + + NAME_SPACE="showcase-k8s-ci-nightly" + NAME_SPACE_RBAC="showcase-rbac-k8s-ci-nightly" + export NAME_SPACE NAME_SPACE_RBAC + + K8S_CLUSTER_URL=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') + K8S_CLUSTER_API_SERVER_URL=$(printf "%s" "$K8S_CLUSTER_URL" | base64 | tr -d '\n') + OCM_CLUSTER_URL=$(printf "%s" "$K8S_CLUSTER_URL" | base64 | tr -d '\n') + export K8S_CLUSTER_URL K8S_CLUSTER_API_SERVER_URL OCM_CLUSTER_URL + + re_create_k8s_service_account_and_get_token + + cluster_setup_k8s_helm + + EKS_INSTANCE_DOMAIN_NAME=$(generate_dynamic_domain_name) + K8S_CLUSTER_ROUTER_BASE=$EKS_INSTANCE_DOMAIN_NAME + export K8S_CLUSTER_ROUTER_BASE EKS_INSTANCE_DOMAIN_NAME + get_eks_certificate "${EKS_INSTANCE_DOMAIN_NAME}" + + initiate_eks_helm_deployment + configure_eks_ingress_and_dns "${NAME_SPACE}" "${RELEASE_NAME}-developer-hub" + check_and_test "${RELEASE_NAME}" "${NAME_SPACE}" "https://${K8S_CLUSTER_ROUTER_BASE}" 50 30 + cleanup_eks_dns_record "${EKS_INSTANCE_DOMAIN_NAME}" + delete_namespace "${NAME_SPACE}" + + EKS_INSTANCE_DOMAIN_NAME=$(generate_dynamic_domain_name) + K8S_CLUSTER_ROUTER_BASE=$EKS_INSTANCE_DOMAIN_NAME + export K8S_CLUSTER_ROUTER_BASE EKS_INSTANCE_DOMAIN_NAME + get_eks_certificate "${EKS_INSTANCE_DOMAIN_NAME}" + + initiate_rbac_eks_helm_deployment + configure_eks_ingress_and_dns "${NAME_SPACE_RBAC}" "${RELEASE_NAME_RBAC}-developer-hub" + check_and_test "${RELEASE_NAME_RBAC}" "${NAME_SPACE_RBAC}" "https://${K8S_CLUSTER_ROUTER_BASE}" 50 30 + cleanup_eks_dns_record "${EKS_INSTANCE_DOMAIN_NAME}" + delete_namespace "${NAME_SPACE_RBAC}" +} diff --git a/.ibm/pipelines/jobs/eks-operator.sh b/.ibm/pipelines/jobs/eks-operator.sh new file mode 100644 index 0000000000..89bb3798f6 --- /dev/null +++ b/.ibm/pipelines/jobs/eks-operator.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# shellcheck source=.ibm/pipelines/install-methods/operator.sh +source "$DIR"/install-methods/operator.sh +# shellcheck source=.ibm/pipelines/cluster/eks/eks-operator-deployment.sh +source "$DIR"/cluster/eks/eks-operator-deployment.sh +# shellcheck source=.ibm/pipelines/cluster/k8s/k8s-utils.sh +source "$DIR"/cluster/k8s/k8s-utils.sh +# shellcheck source=.ibm/pipelines/cluster/eks/aws.sh +source "$DIR"/cluster/eks/aws.sh + +handle_eks_operator() { + echo "Starting EKS Operator deployment" + + # Verify EKS cluster connectivity + aws_eks_verify_cluster + + # Get cluster information + aws_eks_get_cluster_info + + NAME_SPACE="showcase-k8s-ci-nightly" + NAME_SPACE_RBAC="showcase-rbac-k8s-ci-nightly" + export NAME_SPACE NAME_SPACE_RBAC + + K8S_CLUSTER_URL=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') + K8S_CLUSTER_API_SERVER_URL=$(printf "%s" "$K8S_CLUSTER_URL" | base64 | tr -d '\n') + OCM_CLUSTER_URL=$(printf "%s" "$K8S_CLUSTER_URL" | base64 | tr -d '\n') + export K8S_CLUSTER_URL K8S_CLUSTER_API_SERVER_URL OCM_CLUSTER_URL + + re_create_k8s_service_account_and_get_token + + cluster_setup_k8s_operator + + prepare_operator "3" + + EKS_INSTANCE_DOMAIN_NAME=$(generate_dynamic_domain_name) + K8S_CLUSTER_ROUTER_BASE=$EKS_INSTANCE_DOMAIN_NAME + export K8S_CLUSTER_ROUTER_BASE EKS_INSTANCE_DOMAIN_NAME + get_eks_certificate "${EKS_INSTANCE_DOMAIN_NAME}" + + initiate_eks_operator_deployment "${NAME_SPACE}" "https://${K8S_CLUSTER_ROUTER_BASE}" + configure_eks_ingress_and_dns "${NAME_SPACE}" "dh-ingress" + check_and_test "${RELEASE_NAME}" "${NAME_SPACE}" "https://${K8S_CLUSTER_ROUTER_BASE}" 50 30 + cleanup_eks_dns_record "${EKS_INSTANCE_DOMAIN_NAME}" + cleanup_eks_deployment "${NAME_SPACE}" + + EKS_INSTANCE_DOMAIN_NAME=$(generate_dynamic_domain_name) + K8S_CLUSTER_ROUTER_BASE=$EKS_INSTANCE_DOMAIN_NAME + export K8S_CLUSTER_ROUTER_BASE EKS_INSTANCE_DOMAIN_NAME + get_eks_certificate "${EKS_INSTANCE_DOMAIN_NAME}" + + initiate_rbac_eks_operator_deployment "${NAME_SPACE_RBAC}" "https://${K8S_CLUSTER_ROUTER_BASE}" + configure_eks_ingress_and_dns "${NAME_SPACE_RBAC}" "dh-ingress" + check_and_test "${RELEASE_NAME}" "${NAME_SPACE_RBAC}" "https://${K8S_CLUSTER_ROUTER_BASE}" 50 30 + cleanup_eks_dns_record "${EKS_INSTANCE_DOMAIN_NAME}" + cleanup_eks_deployment "${NAME_SPACE_RBAC}" +} diff --git a/.ibm/pipelines/jobs/gke-helm.sh b/.ibm/pipelines/jobs/gke-helm.sh index 6b66379532..040cb102bb 100644 --- a/.ibm/pipelines/jobs/gke-helm.sh +++ b/.ibm/pipelines/jobs/gke-helm.sh @@ -13,6 +13,7 @@ handle_gke_helm() { echo "Starting GKE Helm deployment" IS_OPENSHIFT=false + export IS_OPENSHIFT K8S_CLUSTER_ROUTER_BASE=$GKE_INSTANCE_DOMAIN_NAME NAME_SPACE="showcase-k8s-ci-nightly" @@ -21,7 +22,7 @@ handle_gke_helm() { gcloud_auth "${GKE_SERVICE_ACCOUNT_NAME}" "/tmp/secrets/GKE_SERVICE_ACCOUNT_KEY" gcloud_gke_get_credentials "${GKE_CLUSTER_NAME}" "${GKE_CLUSTER_REGION}" "${GOOGLE_CLOUD_PROJECT}" - gcloud_ssl_cert_create $GKE_CERT_NAME $GKE_INSTANCE_DOMAIN_NAME $GOOGLE_CLOUD_PROJECT + gcloud_ssl_cert_create "$GKE_CERT_NAME" "$GKE_INSTANCE_DOMAIN_NAME" "$GOOGLE_CLOUD_PROJECT" K8S_CLUSTER_URL=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}') K8S_CLUSTER_API_SERVER_URL=$(printf "%s" "$K8S_CLUSTER_URL" | base64 | tr -d '\n') diff --git a/.ibm/pipelines/jobs/gke-operator.sh b/.ibm/pipelines/jobs/gke-operator.sh index 3f9b6d4e1b..783eeec27b 100644 --- a/.ibm/pipelines/jobs/gke-operator.sh +++ b/.ibm/pipelines/jobs/gke-operator.sh @@ -15,6 +15,7 @@ handle_gke_operator() { echo "Starting GKE Operator deployment" IS_OPENSHIFT=false + export IS_OPENSHIFT K8S_CLUSTER_ROUTER_BASE=$GKE_INSTANCE_DOMAIN_NAME export K8S_CLUSTER_ROUTER_BASE diff --git a/.ibm/pipelines/jobs/ocp-nightly.sh b/.ibm/pipelines/jobs/ocp-nightly.sh index 75dd9ab214..d839d9d226 100644 --- a/.ibm/pipelines/jobs/ocp-nightly.sh +++ b/.ibm/pipelines/jobs/ocp-nightly.sh @@ -1,5 +1,8 @@ #!/bin/bash +# shellcheck source=.ibm/pipelines/utils.sh +source "$DIR"/utils.sh + handle_ocp_nightly() { export NAME_SPACE="showcase-ci-nightly" export NAME_SPACE_RBAC="showcase-rbac-nightly" @@ -7,9 +10,10 @@ handle_ocp_nightly() { oc_login - export K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') + K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') + export K8S_CLUSTER_ROUTER_BASE - cluster_setup + cluster_setup_ocp_helm clear_database initiate_deployments deploy_test_backstage_customization_provider "${NAME_SPACE}" @@ -35,7 +39,7 @@ run_runtime_config_change_tests() { } run_sanity_plugins_check() { - initiate_sanity_plugin_checks_deployment "${RELEASE_NAME}" "${NAME_SPACE_SANITY_PLUGINS_CHECK}" local sanity_plugins_url="https://${RELEASE_NAME}-developer-hub-${NAME_SPACE_SANITY_PLUGINS_CHECK}.${K8S_CLUSTER_ROUTER_BASE}" + initiate_sanity_plugin_checks_deployment "${RELEASE_NAME}" "${NAME_SPACE_SANITY_PLUGINS_CHECK}" "${sanity_plugins_url}" check_and_test "${RELEASE_NAME}" "${NAME_SPACE_SANITY_PLUGINS_CHECK}" "${sanity_plugins_url}" } diff --git a/.ibm/pipelines/jobs/ocp-operator.sh b/.ibm/pipelines/jobs/ocp-operator.sh index 819e47aea6..8c82a9baa2 100644 --- a/.ibm/pipelines/jobs/ocp-operator.sh +++ b/.ibm/pipelines/jobs/ocp-operator.sh @@ -18,6 +18,8 @@ initiate_operator_deployments() { oc apply -f /tmp/configmap-dynamic-plugins.yaml -n "${NAME_SPACE}" deploy_redis_cache "${NAME_SPACE}" deploy_rhdh_operator "${NAME_SPACE}" "${DIR}/resources/rhdh-operator/rhdh-start.yaml" + enable_orchestrator_plugins_op "${NAME_SPACE}" + deploy_orchestrator_workflows_operator "${NAME_SPACE}" configure_namespace "${NAME_SPACE_RBAC}" create_conditional_policies_operator /tmp/conditional-policies.yaml @@ -27,6 +29,8 @@ initiate_operator_deployments() { create_dynamic_plugins_config "${DIR}/value_files/${HELM_CHART_RBAC_VALUE_FILE_NAME}" "/tmp/configmap-dynamic-plugins-rbac.yaml" oc apply -f /tmp/configmap-dynamic-plugins-rbac.yaml -n "${NAME_SPACE_RBAC}" deploy_rhdh_operator "${NAME_SPACE_RBAC}" "${DIR}/resources/rhdh-operator/rhdh-start-rbac.yaml" + enable_orchestrator_plugins_op "${NAME_SPACE_RBAC}" + deploy_orchestrator_workflows_operator "${NAME_SPACE_RBAC}" } run_operator_runtime_config_change_tests() { @@ -34,9 +38,9 @@ run_operator_runtime_config_change_tests() { configure_namespace "${NAME_SPACE_RUNTIME}" local runtime_url="https://backstage-${RELEASE_NAME}-${NAME_SPACE_RUNTIME}.${K8S_CLUSTER_ROUTER_BASE}" sed -i "s|POSTGRES_USER:.*|POSTGRES_USER: $RDS_USER|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" - sed -i "s|POSTGRES_PASSWORD:.*|POSTGRES_PASSWORD: $(echo -n $RDS_PASSWORD | base64 -w 0)|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" - sed -i "s|POSTGRES_HOST:.*|POSTGRES_HOST: $(echo -n $RDS_1_HOST | base64 -w 0)|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" - sed -i "s|RHDH_RUNTIME_URL:.*|RHDH_RUNTIME_URL: $(echo -n $runtime_url | base64 -w 0)|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" + sed -i "s|POSTGRES_PASSWORD:.*|POSTGRES_PASSWORD: $(echo -n "$RDS_PASSWORD" | base64 -w 0)|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" + sed -i "s|POSTGRES_HOST:.*|POSTGRES_HOST: $(echo -n "$RDS_1_HOST" | base64 -w 0)|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" + sed -i "s|RHDH_RUNTIME_URL:.*|RHDH_RUNTIME_URL: $(echo -n "$runtime_url" | base64 -w 0)|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" oc apply -f "$DIR/resources/postgres-db/postgres-crt-rds.yaml" -n "${NAME_SPACE_RUNTIME}" oc apply -f "$DIR/resources/postgres-db/postgres-cred.yaml" -n "${NAME_SPACE_RUNTIME}" oc apply -f "$DIR/resources/postgres-db/dynamic-plugins-root-PVC.yaml" -n "${NAME_SPACE_RUNTIME}" @@ -49,7 +53,8 @@ run_operator_runtime_config_change_tests() { handle_ocp_operator() { oc_login - export K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') + K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') + export K8S_CLUSTER_ROUTER_BASE local url="https://backstage-${RELEASE_NAME}-${NAME_SPACE}.${K8S_CLUSTER_ROUTER_BASE}" local rbac_url="https://backstage-${RELEASE_NAME_RBAC}-${NAME_SPACE_RBAC}.${K8S_CLUSTER_ROUTER_BASE}" diff --git a/.ibm/pipelines/jobs/ocp-pull.sh b/.ibm/pipelines/jobs/ocp-pull.sh index 55c6924019..a6129aa127 100644 --- a/.ibm/pipelines/jobs/ocp-pull.sh +++ b/.ibm/pipelines/jobs/ocp-pull.sh @@ -5,8 +5,9 @@ handle_ocp_pull() { oc_login echo "OCP version: $(oc version)" - export K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') - cluster_setup + K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') + export K8S_CLUSTER_ROUTER_BASE + cluster_setup_ocp_helm initiate_deployments deploy_test_backstage_customization_provider "${NAME_SPACE}" local url="https://${RELEASE_NAME}-developer-hub-${NAME_SPACE}.${K8S_CLUSTER_ROUTER_BASE}" diff --git a/.ibm/pipelines/jobs/upgrade.sh b/.ibm/pipelines/jobs/upgrade.sh index f1ff3a89d2..b8d3bdab54 100644 --- a/.ibm/pipelines/jobs/upgrade.sh +++ b/.ibm/pipelines/jobs/upgrade.sh @@ -1,22 +1,42 @@ #!/bin/bash -handle_ocp_helm_upgrade() { +# shellcheck source=.ibm/pipelines/utils.sh +source "$DIR"/utils.sh + +handle_ocp_helm_upgrade() { export NAME_SPACE="showcase-upgrade-nightly" export NAME_SPACE_POSTGRES_DB="${NAME_SPACE}-postgres-external-db" - export DEPLOYMENT_NAME="rhdh-backstage" + export DEPLOYMENT_NAME="${RELEASE_NAME}-developer-hub" export QUAY_REPO_BASE="rhdh/rhdh-hub-rhel9" - export TAG_NAME_BASE="1.5" - export HELM_CHART_VALUE_FILE_NAME_BASE="values_showcase_${TAG_NAME_BASE}.yaml" - + + # Dynamically determine the previous release version and chart version + previous_release_version=$(get_previous_release_version "$CHART_MAJOR_VERSION") + if [[ -z "$previous_release_version" ]]; then + echo "Failed to determine latest release version. Exiting." + save_overall_result 1 + exit 1 + fi + CHART_VERSION_BASE=$(get_chart_version "$previous_release_version") + if [[ -z "$CHART_VERSION_BASE" ]]; then + echo "Failed to determine correct chart version for $previous_release_version. Exiting." + save_overall_result 1 + exit 1 + fi + export CHART_VERSION_BASE + echo "Using previous release version: ${previous_release_version} and chart version: ${CHART_VERSION_BASE}" + export TAG_NAME_BASE=$previous_release_version + oc_login - export K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') - - cluster_setup - initiate_upgrade_base_deployments - + K8S_CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') + export K8S_CLUSTER_ROUTER_BASE + + cluster_setup_ocp_helm + local url="https://${RELEASE_NAME}-developer-hub-${NAME_SPACE}.${K8S_CLUSTER_ROUTER_BASE}" - - initiate_upgrade_deployments "${RELEASE_NAME}" "${NAME_SPACE}" "${url}" + initiate_upgrade_base_deployments "${RELEASE_NAME}" "${NAME_SPACE}" "${url}" + deploy_orchestrator_workflows "${NAME_SPACE}" + initiate_upgrade_deployments "${RELEASE_NAME}" "${NAME_SPACE}" "${url}" + check_upgrade_and_test "${DEPLOYMENT_NAME}" "${RELEASE_NAME}" "${NAME_SPACE}" "${url}" -} \ No newline at end of file +} diff --git a/.ibm/pipelines/ocp-cluster-claim-login.sh b/.ibm/pipelines/ocp-cluster-claim-login.sh index 9f54d2a572..00a5c7904b 100755 --- a/.ibm/pipelines/ocp-cluster-claim-login.sh +++ b/.ibm/pipelines/ocp-cluster-claim-login.sh @@ -1,41 +1,45 @@ #!/bin/bash -# Prompt the user for the prow log url -read -p "Enter the prow log url: " input_url +# Check if prow log URL is provided as parameter, otherwise prompt for it +if [[ $# -eq 0 ]]; then + read -p "Enter the prow log url: " input_url +else + input_url="$1" +fi id=$(echo "$input_url" | awk -F'/' '{print $NF}') job=$(echo "$input_url" | awk -F'/' '{print $(NF-1)}') build_log_url="https://prow.ci.openshift.org/log?container=test&id=${id}&job=${job}" -namespace=$(curl -s $build_log_url | grep "The claimed cluster" | sed -E 's/.*The claimed cluster ([^.]+)\ is ready after.*/\1/') +namespace=$(curl -s $build_log_url | grep "The claimed cluster" | sed -E 's/.*The claimed cluster ([^.]+)\ is ready after.*/\1/') # Output the constructed URL echo "Prow build log URL: $build_log_url" echo "hosted-mgmt Namespace: $namespace" if [[ -z "$namespace" ]]; then - echo "Cluster claim not found. Please provide a valid prow url that uses cluster claim." - exit 1 -elif [[ ! "$namespace" =~ ^rhdh-4-17-us-east-2 ]]; then - echo "Namespace must start with 'rhdh-4-17-us-east-2'." - exit 1 + echo "Cluster claim not found. Please provide a valid prow url that uses cluster claim." + exit 1 +elif [[ ! "$namespace" =~ ^rhdh-[0-9]+-[0-9]+-us-east-2 ]]; then + echo "Namespace must match pattern 'rhdh-[version]-us-east-2'." + exit 1 fi # Log in to the cluster oc login --web https://api.hosted-mgmt.ci.devcluster.openshift.com:6443 -if ! oc get namespace "$namespace" >/dev/null 2>&1; then - echo "Namespace ${namespace} is expired or deleted, exiting..." - exit 1 +if ! oc get namespace "$namespace" > /dev/null 2>&1; then + echo "Namespace ${namespace} is expired or deleted, exiting..." + exit 1 fi # Try to retrieve secrets from the namespace namespace_secrets=$(oc get secrets -n "$namespace" 2>&1) if echo "$namespace_secrets" | grep -q "Forbidden"; then - echo "Error: You do not have access to the namespace '$namespace'." - echo "check if you are member of 'rhdh-pool-admins' group at: https://rover.redhat.com/groups/search?q=rhdh-pool-admins" - echo "Please reach out to the rhdh-qe team for assistance." - exit 1 + echo "Error: You do not have access to the namespace '$namespace'." + echo "check if you are member of 'rhdh-pool-admins' group at: https://rover.redhat.com/groups/search?q=rhdh-pool-admins" + echo "Please reach out to the rhdh-qe team for assistance." + exit 1 fi cluster_secret=$(oc get secrets -n "$namespace" | grep admin-password | awk '{print $1}') @@ -53,26 +57,26 @@ oc project showcase read -p "Do you want to open the OpenShift web console? (y/n): " open_console if [[ "$open_console" == "y" || "$open_console" == "Y" ]]; then - - console_url="https://console-openshift-console.apps.${namespace}.rhdh-qe.devcluster.openshift.com/dashboards" - - echo "Opening web console at $console_url..." - echo "Use bellow user and password to login into web console:" - echo "Username: kubeadmin" - echo "Password: $password" - echo "Password copied to clipboard" - echo $password | pbcopy - sleep 3 - - # Attempt to open the web console in the default browser - if command -v xdg-open &> /dev/null; then - xdg-open "$console_url" # For Linux systems - elif command -v open &> /dev/null; then - open "$console_url" # For macOS - else - echo "Unable to detect a browser. Please open the following URL manually:" - echo "$console_url" - fi + + console_url="https://console-openshift-console.apps.${namespace}.rhdh-qe.devcluster.openshift.com/dashboards" + + echo "Opening web console at $console_url..." + echo "Use bellow user and password to login into web console:" + echo "Username: kubeadmin" + echo "Password: $password" + echo "Password copied to clipboard" + echo $password | pbcopy + sleep 3 + + # Attempt to open the web console in the default browser + if command -v xdg-open &> /dev/null; then + xdg-open "$console_url" # For Linux systems + elif command -v open &> /dev/null; then + open "$console_url" # For macOS + else + echo "Unable to detect a browser. Please open the following URL manually:" + echo "$console_url" + fi else - echo "Web console not opened." -fi \ No newline at end of file + echo "Web console not opened." +fi diff --git a/.ibm/pipelines/openshift-ci-tests.sh b/.ibm/pipelines/openshift-ci-tests.sh index ed2e524f18..89f3f40e17 100755 --- a/.ibm/pipelines/openshift-ci-tests.sh +++ b/.ibm/pipelines/openshift-ci-tests.sh @@ -1,113 +1,160 @@ #!/bin/bash -set -e +set -o errexit +set -o errtrace +set -o nounset export PS4='[$(date "+%Y-%m-%d %H:%M:%S")] ' # logs timestamp for every cmd. -# Define log file names and directories. -LOGFILE="test-log" -export DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -export CURRENT_DEPLOYMENT=0 # Counter for current deployment. -export STATUS_DEPLOYMENT_NAMESPACE # Array that holds the namespaces of deployments. -export STATUS_FAILED_TO_DEPLOY # Array that indicates if deployment failed. false = success, true = failure -export STATUS_TEST_FAILED # Array that indicates if test run failed. false = success, true = failure +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +export DIR + +export OPENSHIFT_CI="${OPENSHIFT_CI:-false}" +if [[ -z "${OPENSHIFT_CI}" || "${OPENSHIFT_CI}" == "false" ]]; then + # NOTE: Use this file to override the environment variables for the local testing. + echo "Sourcing env_override.local.sh" + # shellcheck source=.ibm/pipelines/env_override.local.sh + source "${DIR}/env_override.local.sh" +fi + +echo "Sourcing env_variables.sh" +# shellcheck source=.ibm/pipelines/env_variables.sh +source "${DIR}/env_variables.sh" echo "Sourcing reporting.sh" # shellcheck source=.ibm/pipelines/reporting.sh source "${DIR}/reporting.sh" save_overall_result 0 # Initialize overall result to 0 (success). -export OVERALL_RESULT # Define a cleanup function to be executed upon script exit. -# shellcheck disable=SC2317 -cleanup() { - if [[ $? -ne 0 ]]; then - - echo "Exited with an error, setting OVERALL_RESULT to 1" - save_overall_result 1 - fi - echo "Cleaning up before exiting" - if [[ "${OPENSHIFT_CI}" == "true" ]]; then - case "$JOB_NAME" in - *gke*) - echo "Calling cleanup_gke" - cleanup_gke - ;; - esac - fi - rm -rf ~/tmpbin -} - +# shellcheck source=.ibm/pipelines/cleanup.sh +source "${DIR}/cleanup.sh" trap cleanup EXIT INT ERR -SCRIPTS=( - "utils.sh" - "env_variables.sh" - "clear-database.sh" -) - -# Source explicitly specified scripts -for SCRIPT in "${SCRIPTS[@]}"; do - source "${DIR}/${SCRIPT}" - echo "Loaded ${SCRIPT}" -done +echo "Sourcing utils.sh" +# shellcheck source=.ibm/pipelines/utils.sh +source "${DIR}/utils.sh" -# Source all scripts in jobs directory -for SCRIPT in "${DIR}"/jobs/*.sh; do - if [ -f "$SCRIPT" ]; then - source "$SCRIPT" - echo "Loaded ${SCRIPT}" - fi -done +echo "Sourcing clear-database.sh" +# shellcheck source=.ibm/pipelines/clear-database.sh +source "${DIR}/clear-database.sh" main() { echo "Log file: ${LOGFILE}" echo "JOB_NAME : $JOB_NAME" - export_chart_version - detect_ocp_and_set_env_var + CHART_VERSION=$(get_chart_version "$CHART_MAJOR_VERSION") + export CHART_VERSION + detect_ocp + detect_container_platform case "$JOB_NAME" in - *aks-helm*) + *aks*helm*nightly*) + echo "Sourcing aks-helm.sh" + # shellcheck source=.ibm/pipelines/jobs/aks-helm.sh + source "${DIR}/jobs/aks-helm.sh" echo "Calling handle_aks_helm" handle_aks_helm ;; - *aks-operator*) - echo "Calling handle_aks_helm" + *aks*operator*nightly*) + echo "Sourcing aks-operator.sh" + # shellcheck source=.ibm/pipelines/jobs/aks-operator.sh + source "${DIR}/jobs/aks-operator.sh" + echo "Calling handle_aks_operator" handle_aks_operator ;; - *e2e-tests-auth-providers-nightly) - echo "Calling handle_auth_providers" - handle_auth_providers + *eks*helm*nightly*) + echo "Sourcing eks-helm.sh" + # shellcheck source=.ibm/pipelines/jobs/eks-helm.sh + source "${DIR}/jobs/eks-helm.sh" + echo "Calling handle_eks_helm" + handle_eks_helm ;; - *gke-helm*) + *eks*operator*nightly*) + echo "Sourcing eks-operator.sh" + # shellcheck source=.ibm/pipelines/jobs/eks-operator.sh + source "${DIR}/jobs/eks-operator.sh" + echo "Calling handle_eks_operator" + handle_eks_operator + ;; + *gke*helm*nightly*) + echo "Sourcing gke-helm.sh" + # shellcheck source=.ibm/pipelines/jobs/gke-helm.sh + source "${DIR}/jobs/gke-helm.sh" echo "Calling handle_gke_helm" handle_gke_helm ;; - *gke-operator*) + *gke*operator*nightly*) + echo "Sourcing gke-operator.sh" + # shellcheck source=.ibm/pipelines/jobs/gke-operator.sh + source "${DIR}/jobs/gke-operator.sh" echo "Calling handle_gke_operator" handle_gke_operator ;; - *operator*) - echo "Calling handle_ocp_operator" - handle_ocp_operator + *ocp*operator*auth-providers*nightly*) + echo "Sourcing auth-providers.sh" + # shellcheck source=.ibm/pipelines/jobs/auth-providers.sh + source "${DIR}/jobs/auth-providers.sh" + echo "Calling handle_auth_providers" + handle_auth_providers ;; - *upgrade*) + *ocp*helm*sealights*nightly*) + echo "Sourcing ocp-nightly.sh" + # shellcheck source=.ibm/pipelines/jobs/ocp-nightly.sh + source "${DIR}/jobs/ocp-nightly.sh" + echo "Calling handle_ocp_nightly" + handle_ocp_nightly + ;; + *ocp*helm*upgrade*nightly*) + echo "Sourcing upgrade.sh" + # shellcheck source=.ibm/pipelines/jobs/upgrade.sh + source "${DIR}/jobs/upgrade.sh" echo "Calling helm upgrade" handle_ocp_helm_upgrade ;; - *nightly*) + *ocp*helm*nightly*) + echo "Sourcing ocp-nightly.sh" + # shellcheck source=.ibm/pipelines/jobs/ocp-nightly.sh + source "${DIR}/jobs/ocp-nightly.sh" + echo "Calling handle_ocp_nightly" + handle_ocp_nightly + ;; + *ocp*operator*nightly*) + echo "Sourcing ocp-operator.sh" + # shellcheck source=.ibm/pipelines/jobs/ocp-operator.sh + source "${DIR}/jobs/ocp-operator.sh" + echo "Calling handle_ocp_operator" + handle_ocp_operator + ;; + *osd-gcp*helm*nightly*) + echo "Sourcing ocp-nightly.sh" + # shellcheck source=.ibm/pipelines/jobs/ocp-nightly.sh + source "${DIR}/jobs/ocp-nightly.sh" echo "Calling handle_ocp_nightly" handle_ocp_nightly ;; - *pull*) + *osd-gcp*operator*nightly*) + echo "Sourcing ocp-operator.sh" + # shellcheck source=.ibm/pipelines/jobs/ocp-operator.sh + source "${DIR}/jobs/ocp-operator.sh" + echo "Calling handle_ocp_operator" + handle_ocp_operator + ;; + *pull*ocp*helm*) + echo "Sourcing ocp-pull.sh" + # shellcheck source=.ibm/pipelines/jobs/ocp-pull.sh + source "${DIR}/jobs/ocp-pull.sh" echo "Calling handle_ocp_pull" handle_ocp_pull ;; + *) + echo "ERROR: Unknown JOB_NAME pattern: $JOB_NAME" + echo "No matching handler found for this job type" + save_overall_result 1 + ;; esac echo "Main script completed with result: ${OVERALL_RESULT}" exit "${OVERALL_RESULT}" - } main diff --git a/.ibm/pipelines/reporting.sh b/.ibm/pipelines/reporting.sh index 83eb151ab0..7a0c7ed4f0 100644 --- a/.ibm/pipelines/reporting.sh +++ b/.ibm/pipelines/reporting.sh @@ -1,5 +1,12 @@ #!/bin/bash +# Variables for reporting +export CURRENT_DEPLOYMENT=0 # Counter for current deployment. +export STATUS_DEPLOYMENT_NAMESPACE # Array that holds the namespaces of deployments. +export STATUS_FAILED_TO_DEPLOY # Array that indicates if deployment failed. false = success, true = failure +export STATUS_TEST_FAILED # Array that indicates if test run failed. false = success, true = failure +export OVERALL_RESULT # Overall result of the test run. 0 = success, 1 = failure + mkdir -p "$ARTIFACT_DIR/reporting" save_status_deployment_namespace() { @@ -38,24 +45,6 @@ save_status_number_of_test_failed() { cp "$SHARED_DIR/STATUS_NUMBER_OF_TEST_FAILED.txt" "$ARTIFACT_DIR/reporting/STATUS_NUMBER_OF_TEST_FAILED.txt" } -save_status_data_router_failed() { - local current_deployment=$1 - local status=$2 - echo "Saving STATUS_DATA_ROUTER_FAILED[\"${current_deployment}\"]=${status}" - STATUS_DATA_ROUTER_FAILED["${current_deployment}"]="${status}" - printf "%s\n" "${STATUS_DATA_ROUTER_FAILED["${current_deployment}"]}" >> "$SHARED_DIR/STATUS_DATA_ROUTER_FAILED.txt" - cp "$SHARED_DIR/STATUS_DATA_ROUTER_FAILED.txt" "$ARTIFACT_DIR/reporting/STATUS_DATA_ROUTER_FAILED.txt" -} - -save_status_url_reportportal() { - local current_deployment=$1 - local url=$2 - echo "Saving STATUS_URL_REPORTPORTAL[\"${current_deployment}\"]" - STATUS_URL_REPORTPORTAL["${current_deployment}"]="${url}" - printf "%s\n" "${STATUS_URL_REPORTPORTAL["${current_deployment}"]}" >> "$SHARED_DIR/STATUS_URL_REPORTPORTAL.txt" - cp "$SHARED_DIR/STATUS_URL_REPORTPORTAL.txt" "$ARTIFACT_DIR/reporting/STATUS_URL_REPORTPORTAL.txt" -} - save_overall_result() { local result=$1 OVERALL_RESULT=${result} @@ -64,28 +53,61 @@ save_overall_result() { cp "$SHARED_DIR/OVERALL_RESULT.txt" "$ARTIFACT_DIR/reporting/OVERALL_RESULT.txt" } -# Align this function with the one in https://github.com/openshift/release/blob/master/ci-operator/step-registry/redhat-developer/rhdh/send/alert/redhat-developer-rhdh-send-alert-commands.sh +save_is_openshift() { + local is_openshift=$1 + echo "Saving IS_OPENSHIFT=${is_openshift}" + printf "%s" "${is_openshift}" > "$SHARED_DIR/IS_OPENSHIFT.txt" + cp "$SHARED_DIR/IS_OPENSHIFT.txt" "$ARTIFACT_DIR/reporting/IS_OPENSHIFT.txt" +} + +save_container_platform() { + local container_platform=$1 + local container_platform_version=$2 + echo "Saving CONTAINER_PLATFORM=${container_platform}" + echo "Saving CONTAINER_PLATFORM_VERSION=${container_platform_version}" + printf "%s" "${container_platform}" > "$SHARED_DIR/CONTAINER_PLATFORM.txt" + printf "%s" "${container_platform_version}" > "$SHARED_DIR/CONTAINER_PLATFORM_VERSION.txt" + cp "$SHARED_DIR/CONTAINER_PLATFORM.txt" "$ARTIFACT_DIR/reporting/CONTAINER_PLATFORM.txt" + cp "$SHARED_DIR/CONTAINER_PLATFORM_VERSION.txt" "$ARTIFACT_DIR/reporting/CONTAINER_PLATFORM_VERSION.txt" +} + get_artifacts_url() { - local project="${1:-""}" + local namespace=$1 + + if [ -z "${namespace}" ]; then + echo "Warning: namespace parameter is empty (this is expected only for top level artifacts directory)" >&2 + fi local artifacts_base_url="https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/test-platform-results" local artifacts_complete_url if [ -n "${PULL_NUMBER:-}" ]; then - artifacts_complete_url="${artifacts_base_url}/pr-logs/pull/${REPO_OWNER}_${REPO_NAME}/${PULL_NUMBER}/${JOB_NAME}/${BUILD_ID}/artifacts/e2e-tests/${REPO_OWNER}-${REPO_NAME}/artifacts/${project}" + local part_1="${JOB_NAME##pull-ci-redhat-developer-rhdh-main-}" # e.g. "e2e-ocp-operator-nightly" + local suite_name="${JOB_NAME##pull-ci-redhat-developer-rhdh-main-e2e-}" # e.g. "ocp-operator-nightly" + local part_2="redhat-developer-rhdh-${suite_name}" # e.g. "redhat-developer-rhdh-ocp-operator-nightly" + # Override part_2 based for specific cases that do not follow the standard naming convention. + case "$JOB_NAME" in + *osd-gcp*) + part_2="redhat-developer-rhdh-osd-gcp-helm-nightly" + ;; + *ocp-v*helm*-nightly*) + part_2="redhat-developer-rhdh-ocp-helm-nightly" + ;; + esac + artifacts_complete_url="${artifacts_base_url}/pr-logs/pull/${REPO_OWNER}_${REPO_NAME}/${PULL_NUMBER}/${JOB_NAME}/${BUILD_ID}/artifacts/${part_1}/${part_2}/artifacts/${namespace}" else - local part_1="${JOB_NAME##periodic-ci-redhat-developer-rhdh-"${RELEASE_BRANCH_NAME}"-}" # e.g. "e2e-tests-aks-helm-nightly" - local suite_name="${JOB_NAME##periodic-ci-redhat-developer-rhdh-"${RELEASE_BRANCH_NAME}"-e2e-tests-}" # e.g. "aks-helm-nightly" - local part_2="redhat-developer-rhdh-${suite_name}" # e.g. "redhat-developer-rhdh-aks-helm-nightly" + local part_1="${JOB_NAME##periodic-ci-redhat-developer-rhdh-"${RELEASE_BRANCH_NAME}"-}" # e.g. "e2e-aks-helm-nightly" + local suite_name="${JOB_NAME##periodic-ci-redhat-developer-rhdh-"${RELEASE_BRANCH_NAME}"-e2e-}" # e.g. "aks-helm-nightly" + local part_2="redhat-developer-rhdh-${suite_name}" # e.g. "redhat-developer-rhdh-aks-helm-nightly" # Override part_2 based for specific cases that do not follow the standard naming convention. case "$JOB_NAME" in *osd-gcp*) - part_2="redhat-developer-rhdh-osd-gcp-nightly" - ;; - *ocp-v*) - part_2="redhat-developer-rhdh-nightly" - ;; + part_2="redhat-developer-rhdh-osd-gcp-helm-nightly" + ;; + *ocp-v*helm*-nightly*) + part_2="redhat-developer-rhdh-ocp-helm-nightly" + ;; esac - artifacts_complete_url="${artifacts_base_url}/logs/${JOB_NAME}/${BUILD_ID}/artifacts/${part_1}/${part_2}/artifacts/${project}" + artifacts_complete_url="${artifacts_base_url}/logs/${JOB_NAME}/${BUILD_ID}/artifacts/${part_1}/${part_2}/artifacts/${namespace}" fi echo "${artifacts_complete_url}" } @@ -101,38 +123,29 @@ get_job_url() { echo "${job_complete_url}" } -reportportal_slack_alert() { - local release_name=$1 - local reportportal_launch_url=$2 +save_data_router_junit_results() { + if [[ "${OPENSHIFT_CI}" != "true" ]]; then return 0; fi - if [[ "$release_name" == *rbac* ]]; then - RUN_TYPE="rbac-nightly" - else - RUN_TYPE="nightly" - fi - if [[ ${RESULT} -eq 0 ]]; then - RUN_STATUS_EMOJI=":done-circle-check:" - RUN_STATUS="passed" - else - RUN_STATUS_EMOJI=":failed:" - RUN_STATUS="failed" - fi - jq -n \ - --arg run_status "$RUN_STATUS" \ - --arg run_type "$RUN_TYPE" \ - --arg reportportal_launch_url "$reportportal_launch_url" \ - --arg job_name "$JOB_NAME" \ - --arg run_status_emoji "$RUN_STATUS_EMOJI" \ - '{ - "RUN_STATUS": $run_status, - "RUN_TYPE": $run_type, - "REPORTPORTAL_LAUNCH_URL": $reportportal_launch_url, - "JOB_NAME": $job_name, - "RUN_STATUS_EMOJI": $run_status_emoji - }' > /tmp/data_router_slack_message.json - if ! curl -X POST -H 'Content-type: application/json' --data @/tmp/data_router_slack_message.json $SLACK_DATA_ROUTER_WEBHOOK_URL; then - echo "Failed to send ReportPortal Slack alert" - else - echo "ReportPortal Slack alert sent successfully" - fi + local namespace=$1 + + ARTIFACTS_URL=$(get_artifacts_url "${namespace}") + + cp "${ARTIFACT_DIR}/${namespace}/${JUNIT_RESULTS}" "${ARTIFACT_DIR}/${namespace}/${JUNIT_RESULTS}.original.xml" + + # Replace attachments with link to OpenShift CI storage + sed -i "s#\[\[ATTACHMENT|\(.*\)\]\]#${ARTIFACTS_URL}/\1#g" "${ARTIFACT_DIR}/${namespace}/${JUNIT_RESULTS}" + + # Convert XML property tags from self-closing format to self-closing format + # This handles cases where properties have both opening and closing tags + # Step 1: Remove all closing property tags + sed -i 's###g' "${ARTIFACT_DIR}/${namespace}/${JUNIT_RESULTS}" + # Step 2: Convert opening property tags to self-closing format + sed -i 's###g' "${ARTIFACT_DIR}/${namespace}/${JUNIT_RESULTS}" + + # Copy the metadata and JUnit results files to the shared directory + cp "${ARTIFACT_DIR}/${namespace}/${JUNIT_RESULTS}" "${SHARED_DIR}/junit-results-${namespace}.xml" + + echo "🗃️ JUnit results for ${namespace} adapted to Data Router format and saved to ARTIFACT_DIR and copied to SHARED_DIR" + echo "Shared directory contents:" + ls -la "${SHARED_DIR}" } diff --git a/.ibm/pipelines/resources/cluster_role/cluster-role-k8s.yaml b/.ibm/pipelines/resources/cluster_role/cluster-role-k8s.yaml index 3106a4262e..9df6a46efb 100644 --- a/.ibm/pipelines/resources/cluster_role/cluster-role-k8s.yaml +++ b/.ibm/pipelines/resources/cluster_role/cluster-role-k8s.yaml @@ -5,7 +5,7 @@ metadata: rules: # Base for Kubernetes plugin - apiGroups: - - '' + - "" resources: - pods - pods/log diff --git a/.ibm/pipelines/resources/cluster_role/cluster-role-ocm.yaml b/.ibm/pipelines/resources/cluster_role/cluster-role-ocm.yaml index 1eefdbf8a8..8f562cd5f0 100644 --- a/.ibm/pipelines/resources/cluster_role/cluster-role-ocm.yaml +++ b/.ibm/pipelines/resources/cluster_role/cluster-role-ocm.yaml @@ -3,20 +3,20 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: rhdh-k8s-plugin-ocm rules: -- apiGroups: - - cluster.open-cluster-management.io - resources: - - managedclusters - verbs: - - get - - watch - - list - - create -- apiGroups: - - internal.open-cluster-management.io - resources: - - managedclusterinfos - verbs: - - get - - watch - - list + - apiGroups: + - cluster.open-cluster-management.io + resources: + - managedclusters + verbs: + - get + - watch + - list + - create + - apiGroups: + - internal.open-cluster-management.io + resources: + - managedclusterinfos + verbs: + - get + - watch + - list diff --git a/.ibm/pipelines/resources/cluster_role_binding/cluster-role-binding-k8s.yaml b/.ibm/pipelines/resources/cluster_role_binding/cluster-role-binding-k8s.yaml index 6db03bd5f4..bca4c567bb 100644 --- a/.ibm/pipelines/resources/cluster_role_binding/cluster-role-binding-k8s.yaml +++ b/.ibm/pipelines/resources/cluster_role_binding/cluster-role-binding-k8s.yaml @@ -7,6 +7,6 @@ roleRef: kind: ClusterRole name: rhdh-k8s-plugin subjects: -- kind: ServiceAccount - name: rhdh-k8s-plugin - namespace: showcase-operator-nightly + - kind: ServiceAccount + name: rhdh-k8s-plugin + namespace: showcase-operator-nightly diff --git a/.ibm/pipelines/resources/config_map/app-config-rhdh-rbac.yaml b/.ibm/pipelines/resources/config_map/app-config-rhdh-rbac.yaml index 23f4f49d88..a064fb0493 100644 --- a/.ibm/pipelines/resources/config_map/app-config-rhdh-rbac.yaml +++ b/.ibm/pipelines/resources/config_map/app-config-rhdh-rbac.yaml @@ -7,7 +7,7 @@ backend: origin: ${RHDH_BASE_URL} auth: keys: - - secret: temp + - secret: ${BACKEND_SECRET} integrations: # Plugin: GitHub github: @@ -31,7 +31,7 @@ integrations: auth: environment: development session: - secret: superSecretSecret + secret: superSecretSecret providers: guest: dangerouslyAllowOutsideDevelopment: true @@ -56,17 +56,17 @@ proxy: endpoints: # Other Proxies # customize developer hub instance - '/developer-hub': + "/developer-hub": target: ${DH_TARGET_URL} changeOrigin: true # Change to "false" in case of using self hosted cluster with a self-signed certificate secure: false - '/acr/api': - target: 'https://rhdhqetest.azurecr.io/acr/v1/' + "/acr/api": + target: "https://rhdhqetest.azurecr.io/acr/v1/" changeOrigin: true headers: # If you use Bearer Token for authorization, please replace the 'Basic' with 'Bearer' in the following line. - Authorization: '${ACR_SECRET}' + Authorization: "${ACR_SECRET}" # Change to "false" in case of using self hosted artifactory instance with a self-signed certificate secure: false catalog: @@ -112,7 +112,7 @@ dynatrace: baseUrl: temp argocd: appLocatorMethods: - - type: 'config' + - type: "config" instances: - name: argoInstance1 url: temp @@ -125,13 +125,14 @@ permission: rbac: maxDepth: 1 policyFileReload: true - policies-csv-file: './rbac/rbac-policy.csv' - conditionalPoliciesFile: './rbac-conditions/conditional-policies.yaml' + policies-csv-file: "./rbac/rbac-policy.csv" + conditionalPoliciesFile: "./rbac-conditions/conditional-policies.yaml" pluginsWithPermission: - catalog - permission - scaffolder - kubernetes + - scorecard admin: users: - name: user:default/rhdh-qe diff --git a/.ibm/pipelines/resources/config_map/app-config-rhdh.yaml b/.ibm/pipelines/resources/config_map/app-config-rhdh.yaml index efd7f21a44..e030178b40 100644 --- a/.ibm/pipelines/resources/config_map/app-config-rhdh.yaml +++ b/.ibm/pipelines/resources/config_map/app-config-rhdh.yaml @@ -1,6 +1,4 @@ app: - sidebar: - logo: true support: url: https://github.com/redhat-developer/rhdh/issues items: @@ -13,7 +11,7 @@ app: branding: fullLogo: # QE Red Hat Developer Hub light: "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160pt%22%20height%3D%2280pt%22%20viewBox%3D%220%200%20160%2080%22%3E%3Cg%20fill%3D%22%23000%22%20style%3D%22text-align%3Astart%3Btext-align-last%3Aauto%22%20letter-spacing%3D%220%22%3E%3Ctext%20font-family%3D%22Red%20Hat%20Display%22%20font-size%3D%2240%22%20font-weight%3D%22700%22%20transform%3D%22translate(-.177%2054.263)%22%20word-spacing%3D%220%22%3E%3Ctspan%20x%3D%220%22%3EQE%3C%2Ftspan%3E%3C%2Ftext%3E%3Ctext%20font-family%3D%22Red%20Hat%20Text%22%20font-size%3D%2214%22%20font-weight%3D%22700%22%20transform%3D%22translate(57.565%2035.73)%22%20word-spacing%3D%220%22%3E%3Ctspan%20x%3D%220%22%3ERed%20Hat%3C%2Ftspan%3E%3Ctspan%20x%3D%220%22%20dy%3D%2218.516%22%3EDeveloper%20Hub%3C%2Ftspan%3E%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fsvg%3E" - dark: "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160pt%22%20height%3D%2280pt%22%20viewBox%3D%220%200%20160%2080%22%3E%3Cg%20fill%3D%22%23fff%22%20style%3D%22text-align%3Astart%3Btext-align-last%3Aauto%22%20letter-spacing%3D%220%22%3E%3Ctext%20font-family%3D%22Red%20Hat%20Display%22%20font-size%3D%2240%22%20font-weight%3D%22700%22%20transform%3D%22translate(-.177%2054.263)%22%20word-spacing%3D%220%22%3E%3Ctspan%20x%3D%220%22%3EQE%3C%2Ftspan%3E%3C%2Ftext%3E%3Ctext%20font-family%3D%22Red%20Hat%20Text%22%20font-size%3D%2214%22%20font-weight%3D%22700%22%20transform%3D%22translate(57.565%2035.73)%22%20word-spacing%3D%220%22%3E%3Ctspan%20x%3D%220%22%3ERed%20Hat%3C%2Ftspan%3E%3Ctspan%20x%3D%220%22%20dy%3D%2218.516%22%3EDeveloper%20Hub%3C%2Ftspan%3E%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fsvg%3E" + dark: "" # Dark logo in dynamic-global-header-config.yaml iconLogo: # QE icon light: "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2280pt%22%20height%3D%2280pt%22%20viewBox%3D%220%200%2080%2080%22%3E%3Ctext%20fill%3D%22%23000%22%20font-family%3D%22Red%20Hat%20Mono%22%20font-size%3D%2264%22%20font-weight%3D%22700%22%20letter-spacing%3D%220%22%20style%3D%22text-align%3Astart%3Btext-align-last%3Aauto%22%20transform%3D%22translate(1.6%2062.813)%22%20word-spacing%3D%220%22%3E%3Ctspan%20x%3D%220%22%3EQE%3C%2Ftspan%3E%3C%2Ftext%3E%3C%2Fsvg%3E" dark: "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2280pt%22%20height%3D%2280pt%22%20viewBox%3D%220%200%2080%2080%22%3E%3Ctext%20fill%3D%22%23fff%22%20font-family%3D%22Red%20Hat%20Mono%22%20font-size%3D%2264%22%20font-weight%3D%22700%22%20letter-spacing%3D%220%22%20style%3D%22text-align%3Astart%3Btext-align-last%3Aauto%22%20transform%3D%22translate(1.6%2062.813)%22%20word-spacing%3D%220%22%3E%3Ctspan%20x%3D%220%22%3EQE%3C%2Ftspan%3E%3C%2Ftext%3E%3C%2Fsvg%3E" @@ -24,17 +22,17 @@ app: headerColor2: "rgb(216, 164, 98)" navigationIndicatorColor: "rgb(98, 216, 105)" dark: - primaryColor: '#DC6ED9' - headerColor1: 'rgb(190, 122, 45)' - headerColor2: 'rgb(45, 190, 50)' - navigationIndicatorColor: 'rgb(45, 113, 190)' + primaryColor: "#DC6ED9" + headerColor1: "rgb(190, 122, 45)" + headerColor2: "rgb(45, 190, 50)" + navigationIndicatorColor: "rgb(45, 113, 190)" backend: baseUrl: ${RHDH_BASE_URL} cors: origin: ${RHDH_BASE_URL} reading: allow: - - host: 'github.com' + - host: "github.com" - host: ${DH_TARGET_URL} auth: dangerouslyDisableDefaultAuthPolicy: true @@ -44,7 +42,7 @@ backend: token: test-token subject: test-subject keys: - - secret: temp + - secret: ${BACKEND_SECRET} cache: store: redis connection: redis://${REDIS_USERNAME}:${REDIS_PASSWORD}@redis:6379 @@ -115,25 +113,25 @@ proxy: # endpoints: {} endpoints: # Other Proxies - '/acr/api': - target: 'https://rhdhqetest.azurecr.io/acr/v1/' + "/acr/api": + target: "https://rhdhqetest.azurecr.io/acr/v1/" changeOrigin: true headers: # If you use Bearer Token for authorization, please replace the 'Basic' with 'Bearer' in the following line. - Authorization: '${ACR_SECRET}' + Authorization: "${ACR_SECRET}" # Change to "false" in case of using self hosted artifactory instance with a self-signed certificate secure: false - '/quay/api': + "/quay/api": target: https://quay.io/ headers: - X-Requested-With: 'XMLHttpRequest' + X-Requested-With: "XMLHttpRequest" changeOrigin: true secure: true - '/add-test-header': + "/add-test-header": target: ${RHDH_BASE_URL_HTTP}/api/simple-chat credentials: forward headers: - 'x-proxy-test-header': 'hello!' + "x-proxy-test-header": "hello!" catalog: import: entityFilename: catalog-info.yaml @@ -185,10 +183,10 @@ catalog: initialDelay: { seconds: 15 } github: providerId: - organization: '${GITHUB_ORG}' + organization: "${GITHUB_ORG}" schedule: - frequency: { minutes: 30} - timeout: { minutes: 30} + frequency: { minutes: 30 } + timeout: { minutes: 30 } githubOrg: id: production githubUrl: "${GITHUB_URL}" @@ -208,7 +206,7 @@ dynatrace: baseUrl: temp argocd: appLocatorMethods: - - type: 'config' + - type: "config" instances: - name: argoInstance1 url: temp @@ -223,9 +221,15 @@ extensions: installation: enabled: false buildInfo: - title: 'RHDH Build info' + title: "RHDH Build info" card: - TechDocs builder: 'local' - Authentication provider: 'Github' + TechDocs builder: "local" + Authentication provider: "Github" RBAC: disabled - full: true + overrideBuildInfo: true +i18n: + locales: + - en + - fr + - de + defaultLocale: en diff --git a/.ibm/pipelines/resources/config_map/dynamic-global-floating-action-button-config.yaml b/.ibm/pipelines/resources/config_map/dynamic-global-floating-action-button-config.yaml index 956b7bc7be..30472d4c34 100644 --- a/.ibm/pipelines/resources/config_map/dynamic-global-floating-action-button-config.yaml +++ b/.ibm/pipelines/resources/config_map/dynamic-global-floating-action-button-config.yaml @@ -9,30 +9,30 @@ dynamicPlugins: importName: NullComponent config: icon: github - label: 'Git' + label: "Git" showLabel: true - toolTip: 'Github' + toolTip: "Github" to: https://github.com/redhat-developer/rhdh - mountPoint: global.floatingactionbutton/config importName: NullComponent config: icon: '' - label: 'Quay' + label: "Quay" showLabel: true - toolTip: 'Quay' - to: 'https://quay.io' - visibleOnPaths: ['/catalog'] + toolTip: "Quay" + to: "https://quay.io" + visibleOnPaths: ["/catalog"] red-hat-developer-hub.backstage-plugin-bulk-import: mountPoints: - mountPoint: global.floatingactionbutton/config importName: BulkImportPage config: - slot: 'bottom-left' + slot: "bottom-left" icon: bulkImportIcon - label: 'Bulk import' - toolTip: 'Register multiple repositories in bulk' + label: "Bulk import" + toolTip: "Register multiple repositories in bulk" to: /bulk-import/repositories - excludeOnPaths: ['/catalog'] + excludeOnPaths: ["/catalog"] appIcons: - name: bulkImportIcon importName: BulkImportIcon diff --git a/.ibm/pipelines/resources/config_map/dynamic-global-header-config.yaml b/.ibm/pipelines/resources/config_map/dynamic-global-header-config.yaml index ef9be9d618..6f2b1d580c 100644 --- a/.ibm/pipelines/resources/config_map/dynamic-global-header-config.yaml +++ b/.ibm/pipelines/resources/config_map/dynamic-global-header-config.yaml @@ -6,7 +6,17 @@ dynamicPlugins: - mountPoint: application/header importName: GlobalHeader config: - position: above-main-content + position: above-sidebar + - mountPoint: global.header/component + importName: CompanyLogo + config: + priority: 200 + props: + logo: + dark: "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160pt%22%20height%3D%2280pt%22%20viewBox%3D%220%200%20160%2080%22%3E%3Cg%20fill%3D%22%23fff%22%20style%3D%22text-align%3Astart%3Btext-align-last%3Aauto%22%20letter-spacing%3D%220%22%3E%3Ctext%20font-family%3D%22Red%20Hat%20Display%22%20font-size%3D%2240%22%20font-weight%3D%22700%22%20transform%3D%22translate(-.177%2054.263)%22%20word-spacing%3D%220%22%3E%3Ctspan%20x%3D%220%22%3EQE%3C%2Ftspan%3E%3C%2Ftext%3E%3Ctext%20font-family%3D%22Red%20Hat%20Text%22%20font-size%3D%2214%22%20font-weight%3D%22700%22%20transform%3D%22translate(57.565%2035.73)%22%20word-spacing%3D%220%22%3E%3Ctspan%20x%3D%220%22%3ERed%20Hat%3C%2Ftspan%3E%3Ctspan%20x%3D%220%22%20dy%3D%2218.516%22%3EDeveloper%20Hub%3C%2Ftspan%3E%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fsvg%3E" + width: 160 + height: 80 + to: "/" - mountPoint: global.header/component importName: HeaderIconButton config: @@ -67,6 +77,7 @@ dynamicPlugins: priority: 90 props: title: My profile + type: myProfile icon: account - mountPoint: global.header/profile importName: LogoutButton diff --git a/.ibm/pipelines/resources/config_map/dynamic-plugins-config.yaml b/.ibm/pipelines/resources/config_map/dynamic-plugins-config.yaml index c23aee85b5..81b44fdb1c 100644 --- a/.ibm/pipelines/resources/config_map/dynamic-plugins-config.yaml +++ b/.ibm/pipelines/resources/config_map/dynamic-plugins-config.yaml @@ -9,56 +9,56 @@ dynamicPlugins: importName: SearchBar config: layouts: - xl: { w: 10, h: 1, x: 1 } - lg: { w: 10, h: 1, x: 1 } - md: { w: 10, h: 1, x: 1 } - sm: { w: 10, h: 1, x: 1 } - xs: { w: 12, h: 1 } + xl: { w: 10, h: 1, x: 1 } + lg: { w: 10, h: 1, x: 1 } + md: { w: 10, h: 1, x: 1 } + sm: { w: 10, h: 1, x: 1 } + xs: { w: 12, h: 1 } xxs: { w: 12, h: 1 } - mountPoint: home.page/cards importName: QuickAccessCard config: layouts: - xl: { w: 7, h: 8 } - lg: { w: 7, h: 8 } - md: { w: 7, h: 8 } - sm: { w: 12, h: 8 } - xs: { w: 12, h: 8 } + xl: { w: 7, h: 8 } + lg: { w: 7, h: 8 } + md: { w: 7, h: 8 } + sm: { w: 12, h: 8 } + xs: { w: 12, h: 8 } xxs: { w: 12, h: 8 } - mountPoint: home.page/cards importName: CatalogStarredEntitiesCard config: layouts: - xl: { w: 5, h: 4, x: 7 } - lg: { w: 5, h: 4, x: 7 } - md: { w: 5, h: 4, x: 7 } - sm: { w: 12, h: 4 } - xs: { w: 12, h: 4 } + xl: { w: 5, h: 4, x: 7 } + lg: { w: 5, h: 4, x: 7 } + md: { w: 5, h: 4, x: 7 } + sm: { w: 12, h: 4 } + xs: { w: 12, h: 4 } xxs: { w: 12, h: 4 } - mountPoint: home.page/cards importName: Headline config: layouts: - xl: { w: 12, h: 1 } - lg: { w: 12, h: 1 } - md: { w: 12, h: 1 } - sm: { w: 12, h: 1 } - xs: { w: 12, h: 1 } + xl: { w: 12, h: 1 } + lg: { w: 12, h: 1 } + md: { w: 12, h: 1 } + sm: { w: 12, h: 1 } + xs: { w: 12, h: 1 } xxs: { w: 12, h: 1 } props: title: Placeholder tests - align: center + align: center - mountPoint: home.page/cards importName: Placeholder config: layouts: - xl: { x: 1, y: 0, w: 10, h: 1 } - lg: { x: 1, y: 0, w: 10, h: 1 } - md: { x: 1, y: 0, w: 10, h: 1 } - sm: { x: 0, y: 0, w: 12, h: 1 } - xs: { x: 0, y: 0, w: 12, h: 1 } + xl: { x: 1, y: 0, w: 10, h: 1 } + lg: { x: 1, y: 0, w: 10, h: 1 } + md: { x: 1, y: 0, w: 10, h: 1 } + sm: { x: 0, y: 0, w: 12, h: 1 } + xs: { x: 0, y: 0, w: 12, h: 1 } xxs: { x: 0, y: 0, w: 12, h: 1 } props: showBorder: true @@ -67,11 +67,11 @@ dynamicPlugins: importName: Placeholder config: layouts: - xl: { x: 0, y: 0, w: 7, h: 4 } - lg: { x: 0, y: 0, w: 7, h: 4 } - md: { x: 0, y: 0, w: 7, h: 4 } - sm: { x: 0, y: 0, w: 12, h: 4 } - xs: { x: 0, y: 0, w: 12, h: 4 } + xl: { x: 0, y: 0, w: 7, h: 4 } + lg: { x: 0, y: 0, w: 7, h: 4 } + md: { x: 0, y: 0, w: 7, h: 4 } + sm: { x: 0, y: 0, w: 12, h: 4 } + xs: { x: 0, y: 0, w: 12, h: 4 } xxs: { x: 0, y: 0, w: 12, h: 4 } props: showBorder: true @@ -80,11 +80,11 @@ dynamicPlugins: importName: Placeholder config: layouts: - xl: { x: 7, y: 0, w: 5, h: 4 } - lg: { x: 7, y: 0, w: 5, h: 4 } - md: { x: 7, y: 0, w: 5, h: 4 } - sm: { x: 0, y: 0, w: 12, h: 4 } - xs: { x: 0, y: 0, w: 12, h: 4 } + xl: { x: 7, y: 0, w: 5, h: 4 } + lg: { x: 7, y: 0, w: 5, h: 4 } + md: { x: 7, y: 0, w: 5, h: 4 } + sm: { x: 0, y: 0, w: 12, h: 4 } + xs: { x: 0, y: 0, w: 12, h: 4 } xxs: { x: 0, y: 0, w: 12, h: 4 } props: showBorder: true @@ -93,11 +93,11 @@ dynamicPlugins: importName: Headline config: layouts: - xl: { w: 12, h: 1 } - lg: { w: 12, h: 1 } - md: { w: 12, h: 1 } - sm: { w: 12, h: 1 } - xs: { w: 12, h: 1 } + xl: { w: 12, h: 1 } + lg: { w: 12, h: 1 } + md: { w: 12, h: 1 } + sm: { w: 12, h: 1 } + xs: { w: 12, h: 1 } xxs: { w: 12, h: 1 } props: title: Markdown tests @@ -107,17 +107,17 @@ dynamicPlugins: importName: MarkdownCard config: layouts: - xl: { w: 6, h: 4 } - lg: { w: 6, h: 4 } - md: { w: 6, h: 4 } - sm: { w: 6, h: 4 } - xs: { w: 6, h: 4 } + xl: { w: 6, h: 4 } + lg: { w: 6, h: 4 } + md: { w: 6, h: 4 } + sm: { w: 6, h: 4 } + xs: { w: 6, h: 4 } xxs: { w: 6, h: 4 } props: title: Company links content: | ### RHDH - + * [Website](https://developers.redhat.com/rhdh/overview) * [Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub/) * [GitHub Showcase](https://github.com/redhat-developer/rhdh) @@ -126,17 +126,17 @@ dynamicPlugins: importName: Markdown config: layouts: - xl: { w: 6, h: 4, x: 6 } - lg: { w: 6, h: 4, x: 6 } - md: { w: 6, h: 4, x: 6 } - sm: { w: 6, h: 4, x: 6 } - xs: { w: 6, h: 4, x: 6 } + xl: { w: 6, h: 4, x: 6 } + lg: { w: 6, h: 4, x: 6 } + md: { w: 6, h: 4, x: 6 } + sm: { w: 6, h: 4, x: 6 } + xs: { w: 6, h: 4, x: 6 } xxs: { w: 6, h: 4, x: 6 } props: title: Important company links content: | ### RHDH - + * [Website](https://developers.redhat.com/rhdh/overview) * [Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub/) * [GitHub Showcase](https://github.com/redhat-developer/rhdh) @@ -165,7 +165,7 @@ dynamicPlugins: sm: { w: 6, h: 4 } xs: { w: 6, h: 4 } xxs: { w: 6, h: 4 } - + default.main-menu-items: menuItems: default.list: @@ -208,18 +208,18 @@ dynamicPlugins: enabled: false pataknight.backstage-plugin-rhdh-qe-theme: appIcons: - - importName: LightIcon - name: lightIcon - - importName: DarkIcon - name: darkIcon + - importName: LightIcon + name: lightIcon + - importName: DarkIcon + name: darkIcon themes: - - icon: lightIcon - id: light-dynamic - importName: lightThemeProvider - title: Light Dynamic - variant: light - - icon: darkIcon - id: dark-dynamic - importName: darkThemeProvider - title: Dark Dynamic - variant: dark \ No newline at end of file + - icon: lightIcon + id: light-dynamic + importName: lightThemeProvider + title: Light Dynamic + variant: light + - icon: darkIcon + id: dark-dynamic + importName: darkThemeProvider + title: Dark Dynamic + variant: dark diff --git a/.ibm/pipelines/resources/config_map/rbac-policy.csv b/.ibm/pipelines/resources/config_map/rbac-policy.csv index f1b8eeeb0e..04ef38aecf 100644 --- a/.ibm/pipelines/resources/config_map/rbac-policy.csv +++ b/.ibm/pipelines/resources/config_map/rbac-policy.csv @@ -9,7 +9,9 @@ p, role:xyz/team_a, catalog-entity, read, allow p, role:xyz/team_a, catalog.entity.create, create, allow p, role:xyz/team_a, catalog.location.create, create, allow p, role:xyz/team_a, catalog.location.read, read, allow +p, role:default/team_a, scorecard.metric.read, read, allow +g, user:default/rhdh-qe, role:default/team_a g, user:default/rhdh-qe, role:default/qe_rbac_admin p, role:default/qe_rbac_admin, kubernetes.proxy, use, allow p, role:default/qe_rbac_admin, kubernetes.resources.read, read, allow @@ -33,3 +35,7 @@ p, role:default/kubernetes_reader, kubernetes.clusters.read, read, allow g, user:default/rhdh-qe-5, role:default/catalog_reader g, user:default/rhdh-qe-6, role:default/catalog_reader p, role:default/catalog_reader, catalog.entity.read, read, allow + +g, user:default/rhdh-qe, role:default/extension +p, role:default/extension, extension-plugin, read, allow +p, role:default/extension, extension-plugin, create, allow diff --git a/.ibm/pipelines/resources/pipeline-run/pipelines-operator.yaml b/.ibm/pipelines/resources/pipeline-run/pipelines-operator.yaml index af4a54e40b..c20a68122f 100644 --- a/.ibm/pipelines/resources/pipeline-run/pipelines-operator.yaml +++ b/.ibm/pipelines/resources/pipeline-run/pipelines-operator.yaml @@ -4,7 +4,7 @@ metadata: name: openshift-pipelines-operator namespace: openshift-operators spec: - channel: latest + channel: latest name: openshift-pipelines-operator-rh source: redhat-operators sourceNamespace: openshift-marketplace diff --git a/.ibm/pipelines/resources/postgres-db/postgres-crt-rds.yaml b/.ibm/pipelines/resources/postgres-db/postgres-crt-rds.yaml index f073f350b9..5f824fb98f 100644 --- a/.ibm/pipelines/resources/postgres-db/postgres-crt-rds.yaml +++ b/.ibm/pipelines/resources/postgres-db/postgres-crt-rds.yaml @@ -2532,4 +2532,4 @@ stringData: rZIqyBKllCgVeB9sMEsntn4bGLig7CS/N1y2mYdW/745yCLZv2gj0NXhPqgEIdVV f9DhFD4ohE1C63XP0kOQee+LYg/MY5vH8swpCSWxQgX5icv5jVDz8YTdCKgUc5u8 rM2p0kk= - -----END CERTIFICATE----- \ No newline at end of file + -----END CERTIFICATE----- diff --git a/.ibm/pipelines/resources/postgres-db/rds-app-config.yaml b/.ibm/pipelines/resources/postgres-db/rds-app-config.yaml index fb6ad53b6b..d779e8491a 100644 --- a/.ibm/pipelines/resources/postgres-db/rds-app-config.yaml +++ b/.ibm/pipelines/resources/postgres-db/rds-app-config.yaml @@ -4,15 +4,15 @@ app: backend: auth: externalAccess: - - type: legacy - options: - subject: legacy-default-config - secret: "secret" + - type: legacy + options: + subject: legacy-default-config + secret: "secret" baseUrl: ${RHDH_RUNTIME_URL} cors: origin: ${RHDH_RUNTIME_URL} database: - connection: # configure Backstage DB connection parameters + connection: # configure Backstage DB connection parameters host: ${POSTGRES_HOST} port: ${POSTGRES_PORT} user: ${POSTGRES_USER} @@ -21,4 +21,4 @@ auth: environment: development providers: guest: - dangerouslyAllowOutsideDevelopment: true \ No newline at end of file + dangerouslyAllowOutsideDevelopment: true diff --git a/.ibm/pipelines/resources/postgres-db/values-showcase-postgres.yaml b/.ibm/pipelines/resources/postgres-db/values-showcase-postgres.yaml index 1f5c40715c..56af337237 100644 --- a/.ibm/pipelines/resources/postgres-db/values-showcase-postgres.yaml +++ b/.ibm/pipelines/resources/postgres-db/values-showcase-postgres.yaml @@ -21,14 +21,14 @@ upstream: auth: externalAccess: - options: - secret: '${BACKEND_SECRET}' + secret: "${BACKEND_SECRET}" subject: legacy-default-config type: legacy baseUrl: 'https://{{- include "janus-idp.hostname" . }}' cors: origin: 'https://{{- include "janus-idp.hostname" . }}' database: - connection: # configure Backstage DB connection parameters + connection: # configure Backstage DB connection parameters host: ${POSTGRES_HOST} port: ${POSTGRES_PORT} user: ${POSTGRES_USER} diff --git a/.ibm/pipelines/resources/redis-cache/redis-deployment.yaml b/.ibm/pipelines/resources/redis-cache/redis-deployment.yaml index 9462cf88d3..0826f3d2df 100644 --- a/.ibm/pipelines/resources/redis-cache/redis-deployment.yaml +++ b/.ibm/pipelines/resources/redis-cache/redis-deployment.yaml @@ -15,40 +15,40 @@ spec: app: redis spec: containers: - - name: redis - image: redis:6.2 - ports: - - containerPort: 6379 - resources: - requests: - memory: "64Mi" - cpu: "250m" - limits: - memory: "256Mi" - cpu: "500m" - env: - - name: REDIS_USERNAME - valueFrom: - secretKeyRef: - name: redis-secret - key: REDIS_USERNAME - - name: REDIS_PASSWORD - valueFrom: - secretKeyRef: - name: redis-secret - key: REDIS_PASSWORD - command: - - /bin/sh - - -c - - | - echo "user ${REDIS_USERNAME} on >${REDIS_PASSWORD} allcommands allkeys" > /data/redis.conf - redis-server /data/redis.conf - volumeMounts: - - name: redis-data - mountPath: /data + - name: redis + image: redis:6.2 + ports: + - containerPort: 6379 + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "256Mi" + cpu: "500m" + env: + - name: REDIS_USERNAME + valueFrom: + secretKeyRef: + name: redis-secret + key: REDIS_USERNAME + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: redis-secret + key: REDIS_PASSWORD + command: + - /bin/sh + - -c + - | + echo "user ${REDIS_USERNAME} on >${REDIS_PASSWORD} allcommands allkeys" > /data/redis.conf + redis-server /data/redis.conf + volumeMounts: + - name: redis-data + mountPath: /data volumes: - - name: redis-data - emptyDir: {} + - name: redis-data + emptyDir: {} --- apiVersion: v1 kind: Service @@ -58,7 +58,7 @@ metadata: app: redis spec: ports: - - port: 6379 - targetPort: 6379 + - port: 6379 + targetPort: 6379 selector: app: redis diff --git a/.ibm/pipelines/resources/rhdh-operator/rhdh-start-rbac.yaml b/.ibm/pipelines/resources/rhdh-operator/rhdh-start-rbac.yaml index cad488fc57..ac407ba8af 100644 --- a/.ibm/pipelines/resources/rhdh-operator/rhdh-start-rbac.yaml +++ b/.ibm/pipelines/resources/rhdh-operator/rhdh-start-rbac.yaml @@ -4,7 +4,7 @@ metadata: name: rhdh-rbac spec: application: - image: 'quay.io/$QUAY_REPO:$TAG_NAME' + image: "quay.io/$QUAY_REPO:$TAG_NAME" appConfig: configMaps: - name: app-config-rhdh @@ -13,11 +13,11 @@ spec: extraEnvs: envs: - name: SEGMENT_TEST_MODE - value: 'true' + value: "true" - name: NODE_TLS_REJECT_UNAUTHORIZED - value: '0' + value: "0" - name: NODE_ENV - value: 'production' + value: "production" secrets: - name: rhdh-secrets extraFiles: diff --git a/.ibm/pipelines/resources/rhdh-operator/rhdh-start-rbac_K8s.yaml b/.ibm/pipelines/resources/rhdh-operator/rhdh-start-rbac_K8s.yaml index e898491268..2434c401ff 100644 --- a/.ibm/pipelines/resources/rhdh-operator/rhdh-start-rbac_K8s.yaml +++ b/.ibm/pipelines/resources/rhdh-operator/rhdh-start-rbac_K8s.yaml @@ -8,7 +8,7 @@ spec: - "rh-pull-secret" route: enabled: false - image: 'quay.io/$QUAY_REPO:$TAG_NAME' + image: "quay.io/$QUAY_REPO:$TAG_NAME" appConfig: configMaps: - name: app-config-rhdh @@ -17,11 +17,11 @@ spec: extraEnvs: envs: - name: SEGMENT_TEST_MODE - value: 'true' + value: "true" - name: NODE_TLS_REJECT_UNAUTHORIZED - value: '0' + value: "0" - name: NODE_ENV - value: 'production' + value: "production" secrets: - name: rhdh-secrets extraFiles: diff --git a/.ibm/pipelines/resources/rhdh-operator/rhdh-start-runtime.yaml b/.ibm/pipelines/resources/rhdh-operator/rhdh-start-runtime.yaml index ca9d10ccf9..eac2d59d81 100644 --- a/.ibm/pipelines/resources/rhdh-operator/rhdh-start-runtime.yaml +++ b/.ibm/pipelines/resources/rhdh-operator/rhdh-start-runtime.yaml @@ -1,10 +1,10 @@ kind: Backstage apiVersion: rhdh.redhat.com/v1alpha2 -metadata: +metadata: name: rhdh spec: application: - image: 'quay.io/$QUAY_REPO:$TAG_NAME' + image: "quay.io/$QUAY_REPO:$TAG_NAME" appConfig: configMaps: - name: app-config-rhdh diff --git a/.ibm/pipelines/resources/rhdh-operator/rhdh-start.yaml b/.ibm/pipelines/resources/rhdh-operator/rhdh-start.yaml index bf8bbfa26e..0beec531e9 100644 --- a/.ibm/pipelines/resources/rhdh-operator/rhdh-start.yaml +++ b/.ibm/pipelines/resources/rhdh-operator/rhdh-start.yaml @@ -4,7 +4,7 @@ metadata: name: rhdh spec: application: - image: 'quay.io/$QUAY_REPO:$TAG_NAME' + image: "quay.io/$QUAY_REPO:$TAG_NAME" appConfig: configMaps: - name: app-config-rhdh @@ -16,11 +16,11 @@ spec: extraEnvs: envs: - name: NODE_OPTIONS - value: '--no-node-snapshot' + value: "--no-node-snapshot" - name: NODE_ENV - value: 'production' + value: "production" - name: NODE_TLS_REJECT_UNAUTHORIZED - value: '0' + value: "0" secrets: - name: rhdh-secrets - name: redis-secret diff --git a/.ibm/pipelines/resources/rhdh-operator/rhdh-start_K8s.yaml b/.ibm/pipelines/resources/rhdh-operator/rhdh-start_K8s.yaml index ac1a455bc3..72e962e062 100644 --- a/.ibm/pipelines/resources/rhdh-operator/rhdh-start_K8s.yaml +++ b/.ibm/pipelines/resources/rhdh-operator/rhdh-start_K8s.yaml @@ -8,7 +8,7 @@ spec: - "rh-pull-secret" route: enabled: false - image: 'quay.io/$QUAY_REPO:$TAG_NAME' + image: "quay.io/$QUAY_REPO:$TAG_NAME" appConfig: configMaps: - name: app-config-rhdh @@ -18,7 +18,7 @@ spec: extraEnvs: envs: - name: NODE_OPTIONS - value: '--no-node-snapshot' + value: "--no-node-snapshot" secrets: - name: rhdh-secrets - name: redis-secret diff --git a/.ibm/pipelines/resources/topology_test/topology-test-ingress.yaml b/.ibm/pipelines/resources/topology_test/topology-test-ingress.yaml index f27e59e0ff..a1ce3f7a0a 100644 --- a/.ibm/pipelines/resources/topology_test/topology-test-ingress.yaml +++ b/.ibm/pipelines/resources/topology_test/topology-test-ingress.yaml @@ -16,4 +16,4 @@ spec: service: name: topology-test-service port: - number: 8080 \ No newline at end of file + number: 8080 diff --git a/.ibm/pipelines/resources/topology_test/topology-test-route.yaml b/.ibm/pipelines/resources/topology_test/topology-test-route.yaml index 5bdf59bc89..7726012765 100644 --- a/.ibm/pipelines/resources/topology_test/topology-test-route.yaml +++ b/.ibm/pipelines/resources/topology_test/topology-test-route.yaml @@ -11,4 +11,4 @@ spec: name: topology-test-service port: targetPort: 8080 - wildcardPolicy: None \ No newline at end of file + wildcardPolicy: None diff --git a/.ibm/pipelines/resources/topology_test/topology-test.yaml b/.ibm/pipelines/resources/topology_test/topology-test.yaml index b2f393eb8a..4858e608d9 100644 --- a/.ibm/pipelines/resources/topology_test/topology-test.yaml +++ b/.ibm/pipelines/resources/topology_test/topology-test.yaml @@ -13,7 +13,7 @@ spec: taskSpec: steps: - name: oc - image: 'quay.io/openshift/origin-cli:latest' + image: "quay.io/openshift/origin-cli:latest" script: | #!/bin/sh oc "$@" @@ -37,7 +37,7 @@ metadata: app.kubernetes.io/instance: topology-test app.kubernetes.io/name: topology-test backstage.io/kubernetes-id: developer-hub - annotations: + annotations: app.openshift.io/vcs-uri: "https://github.com/janus-idp/backstage-showcase" spec: replicas: 1 @@ -51,10 +51,10 @@ spec: backstage.io/kubernetes-id: developer-hub spec: containers: - - name: topology - image: nginxinc/nginx-unprivileged:stable-alpine - ports: - - containerPort: 8080 + - name: topology + image: nginxinc/nginx-unprivileged:stable-alpine + ports: + - containerPort: 8080 --- apiVersion: v1 kind: Service @@ -69,4 +69,4 @@ spec: ports: - protocol: TCP port: 8080 - targetPort: 8080 \ No newline at end of file + targetPort: 8080 diff --git a/.ibm/pipelines/utils.sh b/.ibm/pipelines/utils.sh index b685651498..d09c77a381 100755 --- a/.ibm/pipelines/utils.sh +++ b/.ibm/pipelines/utils.sh @@ -3,20 +3,20 @@ # shellcheck source=.ibm/pipelines/reporting.sh source "${DIR}/reporting.sh" -export_chart_version() { - export CHART_VERSION=$(curl -sSX GET "https://quay.io/api/v1/repository/rhdh/chart/tag/?onlyActiveTags=true&filter_tag_name=like:${CHART_MAJOR_VERSION}-" -H "Content-Type: application/json" \ - | jq '.tags[0].name' | grep -oE '[0-9]+\.[0-9]+-[0-9]+-CI') -} - retrieve_pod_logs() { - local pod_name=$1; local container=$2; local namespace=$3 + local pod_name=$1 + local container=$2 + local namespace=$3 echo " Retrieving logs for container: $container" # Save logs for the current and previous container kubectl logs $pod_name -c $container -n $namespace > "pod_logs/${pod_name}_${container}.log" || { echo " logs for container $container not found"; } - kubectl logs $pod_name -c $container -n $namespace --previous > "pod_logs/${pod_name}_${container}-previous.log" 2>/dev/null || { echo " Previous logs for container $container not found"; rm -f "pod_logs/${pod_name}_${container}-previous.log"; } + kubectl logs $pod_name -c $container -n $namespace --previous > "pod_logs/${pod_name}_${container}-previous.log" 2> /dev/null || { + echo " Previous logs for container $container not found" + rm -f "pod_logs/${pod_name}_${container}-previous.log" + } } -save_all_pod_logs(){ +save_all_pod_logs() { set +e local namespace=$1 rm -rf pod_logs && mkdir -p pod_logs @@ -39,164 +39,10 @@ save_all_pod_logs(){ done mkdir -p "${ARTIFACT_DIR}/${namespace}/pod_logs" - cp -a pod_logs/* "${ARTIFACT_DIR}/${namespace}/pod_logs" + cp -a pod_logs/* "${ARTIFACT_DIR}/${namespace}/pod_logs" || true set -e } -droute_send() { - if [[ "${OPENSHIFT_CI}" != "true" ]]; then return 0; fi - if [[ "${JOB_NAME}" == *rehearse* ]]; then return 0; fi - local original_context - original_context=$(oc config current-context) # Save original context - echo "Saving original context: $original_context" - ( # Open subshell - set +e - local droute_version="1.2.2" - local release_name=$1 - local project=$2 - local droute_project="droute" - local metadata_output="data_router_metadata_output.json" - - oc config set-credentials temp-user --token="${RHDH_PR_OS_CLUSTER_TOKEN}" - oc config set-cluster temp-cluster --server="${RHDH_PR_OS_CLUSTER_URL}" - oc config set-context temp-context --user=temp-user --cluster=temp-cluster - oc config use-context temp-context - oc whoami --show-server - trap 'oc config use-context "$original_context"' RETURN - - # Ensure that we are only grabbing the last matched pod - local droute_pod_name=$(oc get pods -n droute --no-headers -o custom-columns=":metadata.name" | grep ubi9-cert-rsync | awk '{print $1}' | tail -n 1) - local temp_droute=$(oc exec -n "${droute_project}" "${droute_pod_name}" -- /bin/bash -c "mktemp -d") - - ARTIFACTS_URL=$(get_artifacts_url) - JOB_URL=$(get_job_url) - - # Remove properties (only used for skipped test and invalidates the file if empty) - sed_inplace '//,/<\/properties>/d' "${ARTIFACT_DIR}/${project}/${JUNIT_RESULTS}" - # Replace attachments with link to OpenShift CI storage - sed_inplace "s#\[\[ATTACHMENT|\(.*\)\]\]#${ARTIFACTS_URL}/\1#g" "${ARTIFACT_DIR}/${project}/${JUNIT_RESULTS}" - - jq \ - --arg hostname "$REPORTPORTAL_HOSTNAME" \ - --arg project "$DATA_ROUTER_PROJECT" \ - --arg name "$JOB_NAME" \ - --arg description "[View job run details](${JOB_URL})" \ - --arg key1 "job_type" \ - --arg value1 "$JOB_TYPE" \ - --arg key2 "pr" \ - --arg value2 "$GIT_PR_NUMBER" \ - --arg key3 "job_name" \ - --arg value3 "$JOB_NAME" \ - --arg key4 "tag_name" \ - --arg value4 "$TAG_NAME" \ - --arg auto_finalization_treshold $DATA_ROUTER_AUTO_FINALIZATION_TRESHOLD \ - '.targets.reportportal.config.hostname = $hostname | - .targets.reportportal.config.project = $project | - .targets.reportportal.processing.launch.name = $name | - .targets.reportportal.processing.launch.description = $description | - .targets.reportportal.processing.launch.attributes += [ - {"key": $key1, "value": $value1}, - {"key": $key2, "value": $value2}, - {"key": $key3, "value": $value3}, - {"key": $key4, "value": $value4} - ] | - .targets.reportportal.processing.tfa.auto_finalization_threshold = ($auto_finalization_treshold | tonumber) - ' data_router/data_router_metadata_template.json > "${ARTIFACT_DIR}/${project}/${metadata_output}" - - # Send test by rsync to bastion pod. - local max_attempts=5 - local wait_seconds_step=1 - for ((i = 1; i <= max_attempts; i++)); do - echo "Attempt ${i} of ${max_attempts} to rsync test resuls to bastion pod." - if output=$(oc rsync --progress=true --include="${metadata_output}" --include="${JUNIT_RESULTS}" --exclude="*" -n "${droute_project}" "${ARTIFACT_DIR}/${project}/" "${droute_project}/${droute_pod_name}:${temp_droute}/" 2>&1); then - echo "$output" - save_status_data_router_failed "$CURRENT_DEPLOYMENT" false - break - elif ((i == max_attempts)); then - echo "Failed to rsync test results after ${max_attempts} attempts." - echo "Last rsync error details:" - echo "${output}" - echo "Troubleshooting steps:" - echo "1. Restart $droute_pod_name in $droute_project project/namespace" - save_status_data_router_failed "$CURRENT_DEPLOYMENT" true - return - else - sleep $((wait_seconds_step * i)) - fi - done - - # "Install" Data Router - oc exec -n "${droute_project}" "${droute_pod_name}" -- /bin/bash -c " - curl -fsSLk -o ${temp_droute}/droute-linux-amd64 'https://${DATA_ROUTER_NEXUS_HOSTNAME}/nexus/repository/dno-raw/droute-client/${droute_version}/droute-linux-amd64' \ - && chmod +x ${temp_droute}/droute-linux-amd64 \ - && ${temp_droute}/droute-linux-amd64 version" - - # Send test results through DataRouter and save the request ID. - local max_attempts=10 - local wait_seconds_step=1 - for ((i = 1; i <= max_attempts; i++)); do - echo "Attempt ${i} of ${max_attempts} to send test results through Data Router." - if output=$(oc exec -n "${droute_project}" "${droute_pod_name}" -- /bin/bash -c " - ${temp_droute}/droute-linux-amd64 send --metadata ${temp_droute}/${metadata_output} \ - --url '${DATA_ROUTER_URL}' \ - --username '${DATA_ROUTER_USERNAME}' \ - --password '${DATA_ROUTER_PASSWORD}' \ - --results '${temp_droute}/${JUNIT_RESULTS}' \ - --verbose" 2>&1) && \ - DATA_ROUTER_REQUEST_ID=$(echo "$output" | grep "request:" | awk '{print $2}') && - [ -n "$DATA_ROUTER_REQUEST_ID" ]; then - echo "Test results successfully sent through Data Router." - echo "Request ID: $DATA_ROUTER_REQUEST_ID" - break - elif ((i == max_attempts)); then - echo "Failed to send test results after ${max_attempts} attempts." - echo "Last Data Router error details:" - echo "${output}" - echo "Troubleshooting steps:" - echo "1. Restart $droute_pod_name in $droute_project project/namespace" - echo "2. Check the Data Router documentation: https://spaces.redhat.com/pages/viewpage.action?pageId=115488042" - echo "3. Ask for help at Slack: #forum-dno-datarouter" - save_status_data_router_failed "$CURRENT_DEPLOYMENT" true - return - else - sleep $((wait_seconds_step * i)) - fi - done - - # shellcheck disable=SC2317 - if [[ "$JOB_NAME" == *periodic-* ]]; then - local max_attempts=30 - local wait_seconds=2 - for ((i = 1; i <= max_attempts; i++)); do - # Get DataRouter request information. - DATA_ROUTER_REQUEST_OUTPUT=$(oc exec -n "${droute_project}" "${droute_pod_name}" -- /bin/bash -c " - ${temp_droute}/droute-linux-amd64 request get \ - --url ${DATA_ROUTER_URL} \ - --username ${DATA_ROUTER_USERNAME} \ - --password ${DATA_ROUTER_PASSWORD} \ - ${DATA_ROUTER_REQUEST_ID}") - # Try to extract the ReportPortal launch URL from the request. This fails if it doesn't contain the launch URL. - REPORTPORTAL_LAUNCH_URL=$(echo "$DATA_ROUTER_REQUEST_OUTPUT" | yq e '.targets[0].events[] | select(.component == "reportportal-connector") | .message | fromjson | .[0].launch_url' -) - if [[ -n "$REPORTPORTAL_LAUNCH_URL" ]]; then - save_status_url_reportportal $CURRENT_DEPLOYMENT $REPORTPORTAL_LAUNCH_URL - reportportal_slack_alert $release_name $REPORTPORTAL_LAUNCH_URL - return 0 - else - echo "Attempt ${i} of ${max_attempts}: ReportPortal launch URL not ready yet." - sleep "${wait_seconds}" - fi - done - fi - oc exec -n "${droute_project}" "${droute_pod_name}" -- /bin/bash -c "rm -rf ${temp_droute}/*" - set -e - ) # Close subshell - oc config use-context "$original_context" # Restore original context - if ! kubectl auth can-i get pods >/dev/null 2>&1; then - echo "Failed to restore the context and authenticate with the cluster. Logging in again." - oc_login - fi -} - # Merge the base YAML value file with the differences file for Kubernetes yq_merge_value_files() { local plugin_operation=$1 # Chose whether you want to merge or overwrite the plugins key (the second file will overwrite the first) @@ -235,53 +81,55 @@ yq_merge_value_files() { # Waits for a Kubernetes/OpenShift deployment to become ready within a specified timeout period wait_for_deployment() { - local namespace=$1 - local resource_name=$2 - local timeout_minutes=${3:-5} # Default timeout: 5 minutes - local check_interval=${4:-10} # Default interval: 10 seconds - - # Validate required parameters - if [[ -z "$namespace" || -z "$resource_name" ]]; then - echo "Error: Missing required parameters" - echo "Usage: wait_for_deployment [timeout_minutes] [check_interval_seconds]" - echo "Example: wait_for_deployment my-namespace my-deployment 5 10" - return 1 + local namespace=$1 + local resource_name=$2 + local timeout_minutes=${3:-5} # Default timeout: 5 minutes + local check_interval=${4:-10} # Default interval: 10 seconds + + # Validate required parameters + if [[ -z "$namespace" || -z "$resource_name" ]]; then + echo "Error: Missing required parameters" + echo "Usage: wait_for_deployment [timeout_minutes] [check_interval_seconds]" + echo "Example: wait_for_deployment my-namespace my-deployment 5 10" + return 1 + fi + + local max_attempts=$((timeout_minutes * 60 / check_interval)) + + echo "Waiting for resource '$resource_name' in namespace '$namespace' (timeout: ${timeout_minutes}m)..." + + for ((i = 1; i <= max_attempts; i++)); do + # Get the first pod name matching the resource name + local pod_name + pod_name=$(oc get pods -n "$namespace" | grep "$resource_name" | awk '{print $1}' | head -n 1) + + if [[ -n "$pod_name" ]]; then + # Check if pod's Ready condition is True + local is_ready + is_ready=$(oc get pod "$pod_name" -n "$namespace" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}') + # Verify pod is both Ready and Running + if [[ "$is_ready" == "True" ]] \ + && oc get pod "$pod_name" -n "$namespace" | grep -q "Running"; then + echo "Pod '$pod_name' is running and ready" + return 0 + else + echo "Pod '$pod_name' is not ready (Ready: $is_ready)" + fi + else + echo "No pods found matching '$resource_name' in namespace '$namespace'" fi - local max_attempts=$((timeout_minutes * 60 / check_interval)) - - echo "Waiting for resource '$resource_name' in namespace '$namespace' (timeout: ${timeout_minutes}m)..." - - for ((i=1; i<=max_attempts; i++)); do - # Get the first pod name matching the resource name - local pod_name=$(oc get pods -n "$namespace" | grep "$resource_name" | awk '{print $1}' | head -n 1) - - if [[ -n "$pod_name" ]]; then - # Check if pod's Ready condition is True - local is_ready=$(oc get pod "$pod_name" -n "$namespace" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}') - # Verify pod is both Ready and Running - if [[ "$is_ready" == "True" ]] && \ - oc get pod "$pod_name" -n "$namespace" | grep -q "Running"; then - echo "Pod '$pod_name' is running and ready" - return 0 - else - echo "Pod '$pod_name' is not ready (Ready: $is_ready)" - fi - else - echo "No pods found matching '$resource_name' in namespace '$namespace'" - fi - - echo "Still waiting... (${i}/${max_attempts} checks)" - sleep "$check_interval" - done + echo "Still waiting... (${i}/${max_attempts} checks)" + sleep "$check_interval" + done - # Timeout occurred - echo "Timeout waiting for resource to be ready. Please check:" - echo "oc get pods -n $namespace | grep $resource_name" - return 1 + # Timeout occurred + echo "Timeout waiting for resource to be ready. Please check:" + echo "oc get pods -n $namespace | grep $resource_name" + return 1 } -wait_for_svc(){ +wait_for_svc() { local svc_name=$1 local namespace=$2 local timeout=${3:-300} @@ -296,13 +144,28 @@ wait_for_svc(){ " || echo "Error: Timed out waiting for $svc_name service creation." } +wait_for_endpoint() { + local endpoint_name=$1 + local namespace=$2 + local timeout=${3:-500} + + timeout "${timeout}" bash -c " + echo ${endpoint_name} + while ! kubectl get endpoints $endpoint_name -n $namespace &> /dev/null; do + echo \"Waiting for ${endpoint_name} endpoint to be created...\" + sleep 5 + done + echo \"Endpoint ${endpoint_name} is created.\" + " || echo "Error: Timed out waiting for $endpoint_name endpoint creation." +} + # Creates an OpenShift Operator subscription -install_subscription(){ - name=$1 # Name of the subscription - namespace=$2 # Namespace to install the operator - channel=$3 # Channel to subscribe to - package=$4 # Package name of the operator - source_name=$5 # Name of the source catalog +install_subscription() { + name=$1 # Name of the subscription + namespace=$2 # Namespace to install the operator + channel=$3 # Channel to subscribe to + package=$4 # Package name of the operator + source_name=$5 # Name of the source catalog source_namespace=$6 # Source namespace (typically openshift-marketplace or olm) # Apply the subscription manifest oc apply -f - << EOD @@ -320,7 +183,7 @@ spec: EOD } -create_secret_dockerconfigjson(){ +create_secret_dockerconfigjson() { namespace=$1 secret_name=$2 dockerconfigjson_value=$3 @@ -353,9 +216,9 @@ setup_image_pull_secret() { # Monitors the status of an operator in an OpenShift namespace. # It checks the ClusterServiceVersion (CSV) for a specific operator to verify if its phase matches an expected value. check_operator_status() { - local timeout=${1:-300} # Timeout in seconds (default 300) - local namespace=$2 # Namespace to check - local operator_name=$3 # Operator name + local timeout=${1:-300} # Timeout in seconds (default 300) + local namespace=$2 # Namespace to check + local operator_name=$3 # Operator name local expected_status=${4:-"Succeeded"} # Expected status phase (default Succeeded) echo "Checking the status of operator '${operator_name}' in namespace '${namespace}' with a timeout of ${timeout} seconds." @@ -372,17 +235,29 @@ check_operator_status() { } # Installs the Crunchy Postgres Operator from Openshift Marketplace using predefined parameters -install_crunchy_postgres_ocp_operator(){ +install_crunchy_postgres_ocp_operator() { install_subscription postgresql openshift-operators v5 postgresql community-operators openshift-marketplace check_operator_status 300 "openshift-operators" "Crunchy Postgres for Kubernetes" "Succeeded" } # Installs the Crunchy Postgres Operator from OperatorHub.io -install_crunchy_postgres_k8s_operator(){ +install_crunchy_postgres_k8s_operator() { install_subscription postgresql openshift-operators v5 postgresql community-operators openshift-marketplace check_operator_status 300 "operators" "Crunchy Postgres for Kubernetes" "Succeeded" } +# Installs the OpenShift Serverless Logic Operator (SonataFlow) from OpenShift Marketplace +install_serverless_logic_ocp_operator() { + install_subscription logic-operator-rhel8 openshift-operators alpha logic-operator-rhel8 redhat-operators openshift-marketplace + check_operator_status 300 "openshift-operators" "OpenShift Serverless Logic Operator" "Succeeded" +} + +# Installs the OpenShift Serverless Operator (Knative) from OpenShift Marketplace +install_serverless_ocp_operator() { + install_subscription serverless-operator openshift-operators stable serverless-operator redhat-operators openshift-marketplace + check_operator_status 300 "openshift-operators" "Red Hat OpenShift Serverless" "Succeeded" +} + uninstall_helmchart() { local project=$1 local release=$2 @@ -398,12 +273,12 @@ configure_namespace() { delete_namespace $project if ! oc create namespace "${project}"; then - echo "Error: Failed to create namespace ${project}" >&2 - exit 1 + echo "Error: Failed to create namespace ${project}" >&2 + exit 1 fi if ! oc config set-context --current --namespace="${project}"; then - echo "Error: Failed to set context for namespace ${project}" >&2 - exit 1 + echo "Error: Failed to set context for namespace ${project}" >&2 + exit 1 fi echo "Namespace ${project} is ready." @@ -411,7 +286,7 @@ configure_namespace() { delete_namespace() { local project=$1 - if oc get namespace "$project" >/dev/null 2>&1; then + if oc get namespace "$project" > /dev/null 2>&1; then echo "Namespace ${project} exists. Attempting to delete..." # Remove blocking finalizers @@ -437,16 +312,16 @@ configure_external_postgres_db() { oc get secret postgress-external-db-cluster-cert -n "${NAME_SPACE_POSTGRES_DB}" -o jsonpath='{.data.tls\.key}' | base64 --decode > postgres-tsl-key oc create secret generic postgress-external-db-cluster-cert \ - --from-file=ca.crt=postgres-ca \ - --from-file=tls.crt=postgres-tls-crt \ - --from-file=tls.key=postgres-tsl-key \ - --dry-run=client -o yaml | oc apply -f - --namespace="${project}" + --from-file=ca.crt=postgres-ca \ + --from-file=tls.crt=postgres-tls-crt \ + --from-file=tls.key=postgres-tsl-key \ + --dry-run=client -o yaml | oc apply -f - --namespace="${project}" - POSTGRES_PASSWORD=$(oc get secret/postgress-external-db-pguser-janus-idp -n "${NAME_SPACE_POSTGRES_DB}" -o jsonpath={.data.password}) + POSTGRES_PASSWORD=$(oc get secret/postgress-external-db-pguser-janus-idp -n "${NAME_SPACE_POSTGRES_DB}" -o jsonpath='{.data.password}') sed_inplace "s|POSTGRES_PASSWORD:.*|POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" POSTGRES_HOST=$(echo -n "postgress-external-db-primary.$NAME_SPACE_POSTGRES_DB.svc.cluster.local" | base64 | tr -d '\n') sed_inplace "s|POSTGRES_HOST:.*|POSTGRES_HOST: ${POSTGRES_HOST}|g" "${DIR}/resources/postgres-db/postgres-cred.yaml" - oc apply -f "${DIR}/resources/postgres-db/postgres-cred.yaml" --namespace="${project}" + oc apply -f "${DIR}/resources/postgres-db/postgres-cred.yaml" --namespace="${project}" } apply_yaml_files() { @@ -458,82 +333,82 @@ apply_yaml_files() { oc config set-context --current --namespace="${project}" local files=( - "$dir/resources/service_account/service-account-rhdh.yaml" - "$dir/resources/cluster_role_binding/cluster-role-binding-k8s.yaml" - "$dir/resources/cluster_role/cluster-role-k8s.yaml" - "$dir/resources/cluster_role/cluster-role-ocm.yaml" - ) + "$dir/resources/service_account/service-account-rhdh.yaml" + "$dir/resources/cluster_role_binding/cluster-role-binding-k8s.yaml" + "$dir/resources/cluster_role/cluster-role-k8s.yaml" + "$dir/resources/cluster_role/cluster-role-ocm.yaml" + ) + + for file in "${files[@]}"; do + sed_inplace "s/namespace:.*/namespace: ${project}/g" "$file" + done - for file in "${files[@]}"; do - sed_inplace "s/namespace:.*/namespace: ${project}/g" "$file" - done + DH_TARGET_URL=$(echo -n "test-backstage-customization-provider-${project}.${K8S_CLUSTER_ROUTER_BASE}" | base64 -w 0) + RHDH_BASE_URL=$(echo -n "$rhdh_base_url" | base64 | tr -d '\n') + RHDH_BASE_URL_HTTP=$(echo -n "${rhdh_base_url/https/http}" | base64 | tr -d '\n') + export DH_TARGET_URL RHDH_BASE_URL RHDH_BASE_URL_HTTP - DH_TARGET_URL=$(echo -n "test-backstage-customization-provider-${project}.${K8S_CLUSTER_ROUTER_BASE}" | base64 -w 0) - RHDH_BASE_URL=$(echo -n "$rhdh_base_url" | base64 | tr -d '\n') - RHDH_BASE_URL_HTTP=$(echo -n "${rhdh_base_url/https/http}" | base64 | tr -d '\n') - export DH_TARGET_URL RHDH_BASE_URL RHDH_BASE_URL_HTTP + oc apply -f "$dir/resources/service_account/service-account-rhdh.yaml" --namespace="${project}" + oc apply -f "$dir/auth/service-account-rhdh-secret.yaml" --namespace="${project}" - oc apply -f "$dir/resources/service_account/service-account-rhdh.yaml" --namespace="${project}" - oc apply -f "$dir/auth/service-account-rhdh-secret.yaml" --namespace="${project}" + oc apply -f "$dir/resources/cluster_role/cluster-role-k8s.yaml" --namespace="${project}" + oc apply -f "$dir/resources/cluster_role_binding/cluster-role-binding-k8s.yaml" --namespace="${project}" + oc apply -f "$dir/resources/cluster_role/cluster-role-ocm.yaml" --namespace="${project}" + oc apply -f "$dir/resources/cluster_role_binding/cluster-role-binding-ocm.yaml" --namespace="${project}" - oc apply -f "$dir/resources/cluster_role/cluster-role-k8s.yaml" --namespace="${project}" - oc apply -f "$dir/resources/cluster_role_binding/cluster-role-binding-k8s.yaml" --namespace="${project}" - oc apply -f "$dir/resources/cluster_role/cluster-role-ocm.yaml" --namespace="${project}" - oc apply -f "$dir/resources/cluster_role_binding/cluster-role-binding-ocm.yaml" --namespace="${project}" + OCM_CLUSTER_TOKEN=$(oc get secret rhdh-k8s-plugin-secret -n "${project}" -o=jsonpath='{.data.token}') + export OCM_CLUSTER_TOKEN + envsubst < "${DIR}/auth/secrets-rhdh-secrets.yaml" | oc apply --namespace="${project}" -f - - OCM_CLUSTER_TOKEN=$(oc get secret rhdh-k8s-plugin-secret -n "${project}" -o=jsonpath='{.data.token}') - export OCM_CLUSTER_TOKEN - envsubst < "${DIR}/auth/secrets-rhdh-secrets.yaml" | oc apply --namespace="${project}" -f - + # Select the configuration file based on the namespace or job + config_file=$(select_config_map_file) + # Apply the ConfigMap with the correct file + create_app_config_map "$config_file" "$project" - # Select the configuration file based on the namespace or job - config_file=$(select_config_map_file) - # Apply the ConfigMap with the correct file - create_app_config_map "$config_file" "$project" + oc create configmap dynamic-plugins-config \ + --from-file="dynamic-plugins-config.yaml"="$dir/resources/config_map/dynamic-plugins-config.yaml" \ + --namespace="${project}" \ + --dry-run=client -o yaml | oc apply -f - - oc create configmap dynamic-plugins-config \ - --from-file="dynamic-plugins-config.yaml"="$dir/resources/config_map/dynamic-plugins-config.yaml" \ - --namespace="${project}" \ + if [[ "$JOB_NAME" == *operator* ]] && [[ "${project}" == *rbac* ]]; then + oc create configmap rbac-policy \ + --from-file="rbac-policy.csv"="$dir/resources/config_map/rbac-policy.csv" \ + --from-file="conditional-policies.yaml"="/tmp/conditional-policies.yaml" \ + --namespace="$project" \ --dry-run=client -o yaml | oc apply -f - - - if [[ "$JOB_NAME" == *operator* ]] && [[ "${project}" == *rbac* ]]; then - oc create configmap rbac-policy \ - --from-file="rbac-policy.csv"="$dir/resources/config_map/rbac-policy.csv" \ - --from-file="conditional-policies.yaml"="/tmp/conditional-policies.yaml" \ - --namespace="$project" \ - --dry-run=client -o yaml | oc apply -f - - else - oc create configmap rbac-policy \ - --from-file="rbac-policy.csv"="$dir/resources/config_map/rbac-policy.csv" \ - --namespace="$project" \ - --dry-run=client -o yaml | oc apply -f - - fi - - # configuration for testing global floating action button. - oc create configmap dynamic-global-floating-action-button-config \ - --from-file="dynamic-global-floating-action-button-config.yaml"="$dir/resources/config_map/dynamic-global-floating-action-button-config.yaml" \ - --namespace="${project}" \ + else + oc create configmap rbac-policy \ + --from-file="rbac-policy.csv"="$dir/resources/config_map/rbac-policy.csv" \ + --namespace="$project" \ --dry-run=client -o yaml | oc apply -f - + fi - # configuration for testing global header and header mount points. - oc create configmap dynamic-global-header-config \ - --from-file="dynamic-global-header-config.yaml"="$dir/resources/config_map/dynamic-global-header-config.yaml" \ - --namespace="${project}" \ - --dry-run=client -o yaml | oc apply -f - + # configuration for testing global floating action button. + oc create configmap dynamic-global-floating-action-button-config \ + --from-file="dynamic-global-floating-action-button-config.yaml"="$dir/resources/config_map/dynamic-global-floating-action-button-config.yaml" \ + --namespace="${project}" \ + --dry-run=client -o yaml | oc apply -f - - # Create Pipeline run for tekton test case. - oc apply -f "$dir/resources/pipeline-run/hello-world-pipeline.yaml" - oc apply -f "$dir/resources/pipeline-run/hello-world-pipeline-run.yaml" + # configuration for testing global header and header mount points. + oc create configmap dynamic-global-header-config \ + --from-file="dynamic-global-header-config.yaml"="$dir/resources/config_map/dynamic-global-header-config.yaml" \ + --namespace="${project}" \ + --dry-run=client -o yaml | oc apply -f - - # Create Deployment and Pipeline for Topology test. - oc apply -f "$dir/resources/topology_test/topology-test.yaml" - if [[ -z "${IS_OPENSHIFT}" || "$(to_lowercase "${IS_OPENSHIFT}")" == "false" ]]; then - kubectl apply -f "$dir/resources/topology_test/topology-test-ingress.yaml" - else - oc apply -f "$dir/resources/topology_test/topology-test-route.yaml" - fi + # Create Pipeline run for tekton test case. + oc apply -f "$dir/resources/pipeline-run/hello-world-pipeline.yaml" + oc apply -f "$dir/resources/pipeline-run/hello-world-pipeline-run.yaml" + + # Create Deployment and Pipeline for Topology test. + oc apply -f "$dir/resources/topology_test/topology-test.yaml" + if [[ -z "${IS_OPENSHIFT}" || "${IS_OPENSHIFT}" == "false" ]]; then + kubectl apply -f "$dir/resources/topology_test/topology-test-ingress.yaml" + else + oc apply -f "$dir/resources/topology_test/topology-test-route.yaml" + fi - # Create secret for sealight job to pull image from private quay repository. - if [[ "$JOB_NAME" == *"sealight"* ]]; then kubectl create secret docker-registry quay-secret --docker-server=quay.io --docker-username=$RHDH_SEALIGHTS_BOT_USER --docker-password=$RHDH_SEALIGHTS_BOT_TOKEN --namespace="${project}"; fi + # Create secret for sealight job to pull image from private quay repository. + if [[ "$JOB_NAME" == *"sealight"* ]]; then kubectl create secret docker-registry quay-secret --docker-server=quay.io --docker-username=$RHDH_SEALIGHTS_BOT_USER --docker-password=$RHDH_SEALIGHTS_BOT_TOKEN --namespace="${project}"; fi } deploy_test_backstage_customization_provider() { @@ -541,7 +416,7 @@ deploy_test_backstage_customization_provider() { echo "Deploying test-backstage-customization-provider in namespace ${project}" # Check if the buildconfig already exists - if ! oc get buildconfig test-backstage-customization-provider -n "${project}" >/dev/null 2>&1; then + if ! oc get buildconfig test-backstage-customization-provider -n "${project}" > /dev/null 2>&1; then echo "Creating new app for test-backstage-customization-provider" oc new-app -S openshift/nodejs:18-minimal-ubi8 oc new-app https://github.com/janus-qe/test-backstage-customization-provider --image-stream="openshift/nodejs:18-ubi8" --namespace="${project}" @@ -637,18 +512,16 @@ run_tests() { mkdir -p "${ARTIFACT_DIR}/${project}/test-results" mkdir -p "${ARTIFACT_DIR}/${project}/attachments/screenshots" - cp -a "${e2e_tests_dir}/test-results/"* "${ARTIFACT_DIR}/${project}/test-results" - cp -a "${e2e_tests_dir}/${JUNIT_RESULTS}" "${ARTIFACT_DIR}/${project}/${JUNIT_RESULTS}" + cp -a "${e2e_tests_dir}/test-results/"* "${ARTIFACT_DIR}/${project}/test-results" || true + cp -a "${e2e_tests_dir}/${JUNIT_RESULTS}" "${ARTIFACT_DIR}/${project}/${JUNIT_RESULTS}" || true - if [ -d "${e2e_tests_dir}/screenshots" ]; then - cp -a "${e2e_tests_dir}/screenshots/"* "${ARTIFACT_DIR}/${project}/attachments/screenshots/" - fi + cp -a "${e2e_tests_dir}/screenshots/"* "${ARTIFACT_DIR}/${project}/attachments/screenshots/" || true - ansi2html <"/tmp/${LOGFILE}" >"/tmp/${LOGFILE}.html" - cp -a "/tmp/${LOGFILE}.html" "${ARTIFACT_DIR}/${project}" - cp -a "${e2e_tests_dir}/playwright-report/"* "${ARTIFACT_DIR}/${project}" + ansi2html < "/tmp/${LOGFILE}" > "/tmp/${LOGFILE}.html" + cp -a "/tmp/${LOGFILE}.html" "${ARTIFACT_DIR}/${project}" || true + cp -a "${e2e_tests_dir}/playwright-report/"* "${ARTIFACT_DIR}/${project}" || true - droute_send "${release_name}" "${project}" + save_data_router_junit_results "${project}" echo "${project} RESULT: ${RESULT}" if [ "${RESULT}" -ne 0 ]; then @@ -673,8 +546,8 @@ check_backstage_running() { local release_name=$1 local namespace=$2 local url=$3 - local max_attempts=$4 - local wait_seconds=$5 + local max_attempts=${4:-30} + local wait_seconds=${5:-30} if [ -z "${url}" ]; then echo "Error: URL is not set. Please provide a valid URL." @@ -684,14 +557,14 @@ check_backstage_running() { echo "Checking if Backstage is up and running at ${url}" for ((i = 1; i <= max_attempts; i++)); do + # Check HTTP status local http_status http_status=$(curl --insecure -I -s -o /dev/null -w "%{http_code}" "${url}") if [ "${http_status}" -eq 200 ]; then - echo "Backstage is up and running!" + echo "✅ Backstage is up and running!" export BASE_URL="${url}" - echo "######## BASE URL ########" - echo "${BASE_URL}" + echo "BASE_URL: ${BASE_URL}" return 0 else echo "Attempt ${i} of ${max_attempts}: Backstage not yet available (HTTP Status: ${http_status})" @@ -700,8 +573,11 @@ check_backstage_running() { fi done - echo "Failed to reach Backstage at ${BASE_URL} after ${max_attempts} attempts." | tee -a "/tmp/${LOGFILE}" - cp -a "/tmp/${LOGFILE}" "${ARTIFACT_DIR}/${namespace}/" + echo "❌ Failed to reach Backstage at ${url} after ${max_attempts} attempts." + oc get events -n "${namespace}" --sort-by='.lastTimestamp' | tail -10 + mkdir -p "${ARTIFACT_DIR}/${namespace}" + cp -a "/tmp/${LOGFILE}" "${ARTIFACT_DIR}/${namespace}/" || true + save_all_pod_logs "${namespace}" return 1 } @@ -724,11 +600,11 @@ uninstall_olm() { } # Installs the advanced-cluster-management OCP Operator -install_acm_ocp_operator(){ +install_acm_ocp_operator() { oc apply -f "${DIR}/cluster/operators/acm/operator-group.yaml" - install_subscription advanced-cluster-management open-cluster-management release-2.12 advanced-cluster-management redhat-operators openshift-marketplace + install_subscription advanced-cluster-management open-cluster-management release-2.14 advanced-cluster-management redhat-operators openshift-marketplace wait_for_deployment "open-cluster-management" "multiclusterhub-operator" - wait_for_svc multiclusterhub-operator-webhook open-cluster-management + wait_for_endpoint "multiclusterhub-operator-webhook" "open-cluster-management" oc apply -f "${DIR}/cluster/operators/acm/multiclusterhub.yaml" # wait until multiclusterhub is Running. timeout 900 bash -c 'while true; do @@ -742,10 +618,10 @@ install_acm_ocp_operator(){ # TODO # Installs Open Cluster Management K8S Operator (alternative of advanced-cluster-management for K8S clusters) # TODO: Verify K8s compatibility and enable OCM tests if compatible -install_ocm_k8s_operator(){ +install_ocm_k8s_operator() { install_subscription my-cluster-manager operators stable cluster-manager operatorhubio-catalog olm wait_for_deployment "operators" "cluster-manager" - wait_for_svc multiclusterhub-operator-work-webhook open-cluster-management + wait_for_endpoint "multiclusterhub-operator-work-webhook" "open-cluster-management" oc apply -f "${DIR}/cluster/operators/acm/multiclusterhub.yaml" # wait until multiclusterhub is Running. timeout 600 bash -c 'while true; do @@ -767,13 +643,7 @@ install_pipelines_operator() { # Install the operator and wait for deployment install_subscription openshift-pipelines-operator openshift-operators latest openshift-pipelines-operator-rh redhat-operators openshift-marketplace wait_for_deployment "openshift-operators" "pipelines" - timeout 300 bash -c ' - while ! oc get svc tekton-pipelines-webhook -n openshift-pipelines &> /dev/null; do - echo "Waiting for tekton-pipelines-webhook service to be created..." - sleep 5 - done - echo "Service tekton-pipelines-webhook is created." - ' || echo "Error: Timed out waiting for tekton-pipelines-webhook service creation." + wait_for_endpoint "tekton-pipelines-webhook" "openshift-pipelines" fi } @@ -786,47 +656,44 @@ install_tekton_pipelines() { echo "Tekton Pipelines is not installed. Installing..." kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml wait_for_deployment "tekton-pipelines" "${DISPLAY_NAME}" - timeout 300 bash -c ' - while ! kubectl get endpoints tekton-pipelines-webhook -n tekton-pipelines &> /dev/null; do - echo "Waiting for tekton-pipelines-webhook endpoints to be ready..." - sleep 5 - done - echo "Endpoints for tekton-pipelines-webhook are ready." - ' || echo "Error: Timed out waiting for tekton-pipelines-webhook endpoints." + wait_for_endpoint "tekton-pipelines-webhook" "tekton-pipelines" fi } delete_tekton_pipelines() { - echo "Checking for Tekton Pipelines installation..." - # Check if tekton-pipelines namespace exists - if kubectl get namespace tekton-pipelines &> /dev/null; then - echo "Found Tekton Pipelines installation. Attempting to delete..." - # Delete the resources and ignore errors - kubectl delete -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml --ignore-not-found=true 2>/dev/null || true - # Wait for namespace deletion (with timeout) - echo "Waiting for Tekton Pipelines namespace to be deleted..." - timeout 30 bash -c ' + echo "Checking for Tekton Pipelines installation..." + # Check if tekton-pipelines namespace exists + if kubectl get namespace tekton-pipelines &> /dev/null; then + echo "Found Tekton Pipelines installation. Attempting to delete..." + # Delete the resources and ignore errors + kubectl delete -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml --ignore-not-found=true 2> /dev/null || true + # Wait for namespace deletion (with timeout) + echo "Waiting for Tekton Pipelines namespace to be deleted..." + timeout 30 bash -c ' while kubectl get namespace tekton-pipelines &> /dev/null; do echo "Waiting for tekton-pipelines namespace deletion..." sleep 5 done echo "Tekton Pipelines deleted successfully." ' || echo "Warning: Timed out waiting for namespace deletion, continuing..." - else - echo "Tekton Pipelines is not installed. Nothing to delete." + else + echo "Tekton Pipelines is not installed. Nothing to delete." fi } -cluster_setup() { +cluster_setup_ocp_helm() { install_pipelines_operator install_acm_ocp_operator install_crunchy_postgres_ocp_operator + install_orchestrator_infra_chart } cluster_setup_ocp_operator() { install_pipelines_operator install_acm_ocp_operator install_crunchy_postgres_ocp_operator + install_serverless_ocp_operator + install_serverless_logic_ocp_operator } cluster_setup_k8s_operator() { @@ -843,6 +710,33 @@ cluster_setup_k8s_helm() { # install_crunchy_postgres_k8s_operator # Works with K8s but disabled in values file } +install_orchestrator_infra_chart() { + ORCH_INFRA_NS="orchestrator-infra" + configure_namespace ${ORCH_INFRA_NS} + + echo "Deploying orchestrator-infra chart" + cd "${DIR}" + helm upgrade -i orch-infra -n "${ORCH_INFRA_NS}" \ + "oci://quay.io/rhdh/orchestrator-infra-chart" --version "${CHART_VERSION}" \ + --wait --timeout=5m \ + --set serverlessLogicOperator.subscription.spec.installPlanApproval=Automatic \ + --set serverlessOperator.subscription.spec.installPlanApproval=Automatic + + until [ "$(oc get pods -n openshift-serverless --no-headers 2> /dev/null | wc -l)" -gt 0 ]; do + sleep 5 + done + + until [ "$(oc get pods -n openshift-serverless-logic --no-headers 2> /dev/null | wc -l)" -gt 0 ]; do + sleep 5 + done + + oc wait pod --all --for=condition=Ready --namespace=openshift-serverless --timeout=5m + oc wait pod --all --for=condition=Ready --namespace=openshift-serverless-logic --timeout=5m + + oc get crd | grep "sonataflow" || echo "Sonataflow CRDs not found" + oc get crd | grep "knative" || echo "Serverless CRDs not found" +} + # Helper function to get common helm set parameters get_image_helm_set_params() { local params="" @@ -864,6 +758,7 @@ perform_helm_install() { local namespace=$2 local value_file=$3 + # shellcheck disable=SC2046 helm upgrade -i "${release_name}" -n "${namespace}" \ "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ -f "${DIR}/value_files/${value_file}" \ @@ -875,10 +770,14 @@ base_deployment() { configure_namespace ${NAME_SPACE} deploy_redis_cache "${NAME_SPACE}" + + cd "${DIR}" local rhdh_base_url="https://${RELEASE_NAME}-developer-hub-${NAME_SPACE}.${K8S_CLUSTER_ROUTER_BASE}" apply_yaml_files "${DIR}" "${NAME_SPACE}" "${rhdh_base_url}" echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE}" perform_helm_install "${RELEASE_NAME}" "${NAME_SPACE}" "${HELM_CHART_VALUE_FILE_NAME}" + + deploy_orchestrator_workflows "${NAME_SPACE}" } rbac_deployment() { @@ -891,6 +790,19 @@ rbac_deployment() { apply_yaml_files "${DIR}" "${NAME_SPACE_RBAC}" "${rbac_rhdh_base_url}" echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${RELEASE_NAME_RBAC}" perform_helm_install "${RELEASE_NAME_RBAC}" "${NAME_SPACE_RBAC}" "${HELM_CHART_RBAC_VALUE_FILE_NAME}" + + # NOTE: This is a workaround to allow the sonataflow platform to connect to the external postgres db using ssl. + until [[ $(oc get jobs -n "${NAME_SPACE_RBAC}" 2> /dev/null | grep "${RELEASE_NAME_RBAC}-create-sonataflow-database" | wc -l) -eq 1 ]]; do + echo "Waiting for sf db creation job to be created. Retrying in 5 seconds..." + sleep 5 + done + oc wait --for=condition=complete job/"${RELEASE_NAME_RBAC}-create-sonataflow-database" -n "${NAME_SPACE_RBAC}" --timeout=3m + oc -n "${NAME_SPACE_RBAC}" patch sfp sonataflow-platform --type=merge \ + -p '{"spec":{"services":{"jobService":{"podTemplate":{"container":{"env":[{"name":"QUARKUS_DATASOURCE_REACTIVE_URL","value":"postgresql://postgress-external-db-primary.postgress-external-db.svc.cluster.local:5432/sonataflow?search_path=jobs-service&sslmode=require&ssl=true&trustAll=true"},{"name":"QUARKUS_DATASOURCE_REACTIVE_SSL_MODE","value":"require"},{"name":"QUARKUS_DATASOURCE_REACTIVE_TRUST_ALL","value":"true"}]}}}}}}' + oc rollout restart deployment/sonataflow-platform-jobs-service -n "${NAME_SPACE_RBAC}" + + # initiate orchestrator workflows deployment + deploy_orchestrator_workflows "${NAME_SPACE_RBAC}" } initiate_deployments() { @@ -901,20 +813,34 @@ initiate_deployments() { # install base RHDH deployment before upgrade initiate_upgrade_base_deployments() { + local release_name=$1 + local namespace=$2 + local url=$3 + local max_attempts=${4:-30} # Default to 30 if not set + local wait_seconds=${5:-30} + echo "Initiating base RHDH deployment before upgrade" - configure_namespace ${NAME_SPACE} + CURRENT_DEPLOYMENT=$((CURRENT_DEPLOYMENT + 1)) + save_status_deployment_namespace $CURRENT_DEPLOYMENT "$namespace" - deploy_redis_cache "${NAME_SPACE}" + configure_namespace "${namespace}" + + deploy_redis_cache "${namespace}" cd "${DIR}" - local rhdh_base_url="https://${RELEASE_NAME}-developer-hub-${NAME_SPACE}.${K8S_CLUSTER_ROUTER_BASE}" - apply_yaml_files "${DIR}" "${NAME_SPACE}" "${rhdh_base_url}" - echo "Deploying image from base repository: ${QUAY_REPO_BASE}, TAG_NAME_BASE: ${TAG_NAME_BASE}, in NAME_SPACE: ${NAME_SPACE}" - helm upgrade -i "${RELEASE_NAME}" -n "${NAME_SPACE}" \ + apply_yaml_files "${DIR}" "${namespace}" "${url}" + echo "Deploying image from base repository: ${QUAY_REPO_BASE}, TAG_NAME_BASE: ${TAG_NAME_BASE}, in NAME_SPACE: ${namespace}" + + # Get dynamic value file path based on previous release version + local previous_release_value_file + previous_release_value_file=$(get_previous_release_value_file "showcase") + echo "Using dynamic value file: ${previous_release_value_file}" + + helm upgrade -i "${release_name}" -n "${namespace}" \ "${HELM_CHART_URL}" --version "${CHART_VERSION_BASE}" \ - -f "${DIR}/value_files/${HELM_CHART_VALUE_FILE_NAME_BASE}" \ + -f "${previous_release_value_file}" \ --set global.clusterRouterBase="${K8S_CLUSTER_ROUTER_BASE}" \ --set upstream.backstage.image.repository="${QUAY_REPO_BASE}" \ --set upstream.backstage.image.tag="${TAG_NAME_BASE}" @@ -924,33 +850,26 @@ initiate_upgrade_deployments() { local release_name=$1 local namespace=$2 local url=$3 - local max_attempts=${4:-30} # Default to 30 if not set + local max_attempts=${4:-30} # Default to 30 if not set local wait_seconds=${5:-30} local wait_upgrade="10m" - # check if the base rhdh deployment is running - if check_backstage_running "${release_name}" "${namespace}" "${url}" "${max_attempts}" "${wait_seconds}"; then - - echo "Display pods of base RHDH deployment before upgrade for verification..." - oc get pods -n "${namespace}" - - echo "Initiating upgrade deployment" - cd "${DIR}" + echo "Initiating upgrade deployment" + cd "${DIR}" - echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE}" + yq_merge_value_files "merge" "${DIR}/value_files/${HELM_CHART_VALUE_FILE_NAME}" "${DIR}/value_files/diff-values_showcase_upgrade.yaml" "/tmp/merged_value_file.yaml" + echo "Deploying image from repository: ${QUAY_REPO}, TAG_NAME: ${TAG_NAME}, in NAME_SPACE: ${NAME_SPACE}" - helm upgrade -i "${RELEASE_NAME}" -n "${NAME_SPACE}" \ + helm upgrade -i "${RELEASE_NAME}" -n "${NAME_SPACE}" \ "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ - -f "${DIR}/value_files/${HELM_CHART_VALUE_FILE_NAME}" \ + -f "/tmp/merged_value_file.yaml" \ --set global.clusterRouterBase="${K8S_CLUSTER_ROUTER_BASE}" \ --set upstream.backstage.image.repository="${QUAY_REPO}" \ --set upstream.backstage.image.tag="${TAG_NAME}" \ --wait --timeout=${wait_upgrade} - oc get pods -n "${namespace}" - else - echo "Backstage is not running. Exiting..." - fi + oc get pods -n "${namespace}" + save_all_pod_logs $namespace } initiate_runtime_deployment() { @@ -967,6 +886,7 @@ initiate_runtime_deployment() { # Create secret for sealight job to pull image from private quay repository. if [[ "$JOB_NAME" == *"sealight"* ]]; then kubectl create secret docker-registry quay-secret --docker-server=quay.io --docker-username=$RHDH_SEALIGHTS_BOT_USER --docker-password=$RHDH_SEALIGHTS_BOT_TOKEN --namespace="${namespace}"; fi + # shellcheck disable=SC2046 helm upgrade -i "${release_name}" -n "${namespace}" \ "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ -f "$DIR/resources/postgres-db/values-showcase-postgres.yaml" \ @@ -975,28 +895,36 @@ initiate_runtime_deployment() { } initiate_sanity_plugin_checks_deployment() { - configure_namespace "${NAME_SPACE_SANITY_PLUGINS_CHECK}" - uninstall_helmchart "${NAME_SPACE_SANITY_PLUGINS_CHECK}" "${RELEASE_NAME}" - deploy_redis_cache "${NAME_SPACE_SANITY_PLUGINS_CHECK}" - apply_yaml_files "${DIR}" "${NAME_SPACE_SANITY_PLUGINS_CHECK}" "${sanity_plugins_url}" + local release_name=$1 + local name_space_sanity_plugins_check=$2 + local sanity_plugins_url=$3 + + configure_namespace "${name_space_sanity_plugins_check}" + uninstall_helmchart "${name_space_sanity_plugins_check}" "${release_name}" + deploy_redis_cache "${name_space_sanity_plugins_check}" + apply_yaml_files "${DIR}" "${name_space_sanity_plugins_check}" "${sanity_plugins_url}" yq_merge_value_files "overwrite" "${DIR}/value_files/${HELM_CHART_VALUE_FILE_NAME}" "${DIR}/value_files/${HELM_CHART_SANITY_PLUGINS_DIFF_VALUE_FILE_NAME}" "/tmp/${HELM_CHART_SANITY_PLUGINS_MERGED_VALUE_FILE_NAME}" - mkdir -p "${ARTIFACT_DIR}/${NAME_SPACE_SANITY_PLUGINS_CHECK}" - cp -a "/tmp/${HELM_CHART_SANITY_PLUGINS_MERGED_VALUE_FILE_NAME}" "${ARTIFACT_DIR}/${NAME_SPACE_SANITY_PLUGINS_CHECK}/" # Save the final value-file into the artifacts directory. - helm upgrade -i "${RELEASE_NAME}" -n "${NAME_SPACE_SANITY_PLUGINS_CHECK}" \ + mkdir -p "${ARTIFACT_DIR}/${name_space_sanity_plugins_check}" + cp -a "/tmp/${HELM_CHART_SANITY_PLUGINS_MERGED_VALUE_FILE_NAME}" "${ARTIFACT_DIR}/${name_space_sanity_plugins_check}/" || true # Save the final value-file into the artifacts directory. + # shellcheck disable=SC2046 + helm upgrade -i "${release_name}" -n "${name_space_sanity_plugins_check}" \ "${HELM_CHART_URL}" --version "${CHART_VERSION}" \ -f "/tmp/${HELM_CHART_SANITY_PLUGINS_MERGED_VALUE_FILE_NAME}" \ --set global.clusterRouterBase="${K8S_CLUSTER_ROUTER_BASE}" \ - $(get_image_helm_set_params) + $(get_image_helm_set_params) \ + --set orchestrator.enabled=true } check_and_test() { local release_name=$1 local namespace=$2 local url=$3 - local max_attempts=${4:-30} # Default to 30 if not set - local wait_seconds=${5:-30} # Default to 30 if not set + local max_attempts=${4:-30} # Default to 30 if not set + local wait_seconds=${5:-30} # Default to 30 if not set + CURRENT_DEPLOYMENT=$((CURRENT_DEPLOYMENT + 1)) - save_status_deployment_namespace $CURRENT_DEPLOYMENT $namespace + save_status_deployment_namespace $CURRENT_DEPLOYMENT "$namespace" + if check_backstage_running "${release_name}" "${namespace}" "${url}" "${max_attempts}" "${wait_seconds}"; then save_status_failed_to_deploy $CURRENT_DEPLOYMENT false echo "Display pods for verification..." @@ -1022,6 +950,9 @@ check_upgrade_and_test() { check_and_test "${release_name}" "${namespace}" "${url}" else echo "Helm upgrade encountered an issue or timed out. Exiting..." + save_status_failed_to_deploy $CURRENT_DEPLOYMENT true + save_status_test_failed $CURRENT_DEPLOYMENT true + save_overall_result 1 fi } @@ -1033,11 +964,11 @@ check_helm_upgrade() { echo "Checking rollout status for deployment: ${deployment_name} in namespace: ${namespace}..." if oc rollout status "deployment/${deployment_name}" -n "${namespace}" --timeout="${timeout}s" -w; then - echo "RHDH upgrade is complete." - return 0 + echo "RHDH upgrade is complete." + return 0 else - echo "RHDH upgrade encountered an issue or timed out." - return 1 + echo "RHDH upgrade encountered an issue or timed out." + return 1 fi } @@ -1066,6 +997,21 @@ force_delete_namespace() { local project=$1 echo "Forcefully deleting namespace ${project}." oc get namespace "$project" -o json | jq '.spec = {"finalizers":[]}' | oc replace --raw "/api/v1/namespaces/$project/finalize" -f - + + local elapsed=0 + local sleep_interval=2 + local timeout_seconds=${2:-120} + + while oc get namespace "$project" &> /dev/null; do + if [[ $elapsed -ge $timeout_seconds ]]; then + echo "Timeout: Namespace '${project}' was not deleted within $timeout_seconds seconds." >&2 + return 1 + fi + sleep $sleep_interval + elapsed=$((elapsed + sleep_interval)) + done + + echo "Namespace '${project}' successfully deleted." } oc_login() { @@ -1077,12 +1023,72 @@ is_openshift() { oc get routes.route.openshift.io &> /dev/null || kubectl get routes.route.openshift.io &> /dev/null } -detect_ocp_and_set_env_var() { +detect_ocp() { echo "Detecting OCP or K8s and populating IS_OPENSHIFT variable..." if [[ "${IS_OPENSHIFT}" == "" ]]; then IS_OPENSHIFT=$(is_openshift && echo 'true' || echo 'false') fi + echo IS_OPENSHIFT: "${IS_OPENSHIFT}" + save_is_openshift "${IS_OPENSHIFT}" +} + +detect_container_platform() { + echo "Detecting container platform and populating CONTAINER_PLATFORM variable..." + + # Determine platform type based on IS_OPENSHIFT variable + if [[ "${IS_OPENSHIFT}" == "true" ]]; then + case "$JOB_NAME" in + *osd-gcp*) + CONTAINER_PLATFORM="osd-gcp" + ;; + *) + CONTAINER_PLATFORM="ocp" + ;; + esac + # Get OCP version + if command -v oc &> /dev/null; then + CONTAINER_PLATFORM_VERSION=$(oc version 2> /dev/null | grep "Server Version:" | cut -d' ' -f3 | cut -d'.' -f1,2 || echo "unknown") + else + CONTAINER_PLATFORM_VERSION="unknown" + fi + else + # Determine Kubernetes distribution based on JOB_NAME pattern + case "$JOB_NAME" in + *aks*) + CONTAINER_PLATFORM="aks" + ;; + *eks*) + CONTAINER_PLATFORM="eks" + ;; + *gke*) + CONTAINER_PLATFORM="gke" + ;; + *iks*) + CONTAINER_PLATFORM="iks" + ;; + *) + CONTAINER_PLATFORM="unknown" + ;; + esac + + # Get Kubernetes version + if command -v kubectl &> /dev/null; then + CONTAINER_PLATFORM_VERSION=$(kubectl version 2> /dev/null | grep "Server Version:" | cut -d' ' -f3 | sed 's/^v//' | cut -d'.' -f1,2 || echo "unknown") + else + CONTAINER_PLATFORM_VERSION="unknown" + fi + fi + + echo "CONTAINER_PLATFORM: ${CONTAINER_PLATFORM}" + echo "CONTAINER_PLATFORM_VERSION: ${CONTAINER_PLATFORM_VERSION}" + + # Export variables for use in other scripts + export CONTAINER_PLATFORM + export CONTAINER_PLATFORM_VERSION + + # Save platform information for reporting + save_container_platform "${CONTAINER_PLATFORM}" "${CONTAINER_PLATFORM_VERSION}" } # Helper function for cross-platform sed @@ -1096,13 +1102,372 @@ sed_inplace() { fi } -# Helper function for case conversion -to_lowercase() { - if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS - using tr - echo "$1" | tr '[:upper:]' '[:lower:]' +# Function to get the appropriate release version based on current branch +# Return the latest release version if current branch is not a release branch +# Return the previous release version if current branch is a release branch +get_previous_release_version() { + local version=$1 + + # Check if version parameter is provided + if [[ -z "$version" ]]; then + echo "Error: Version parameter is required" >&2 + exit 1 + save_overall_result 1 + fi + + # Validate version format (should be like "1.6") + if [[ ! "$version" =~ ^[0-9]+\.[0-9]+$ ]]; then + echo "Error: Version must be in format X.Y (e.g., 1.6)" >&2 + exit 1 + save_overall_result 1 + fi + + # Extract major and minor version numbers + local major_version + major_version=$(echo "$version" | cut -d'.' -f1) + local minor_version + minor_version=$(echo "$version" | cut -d'.' -f2) + + # Calculate previous minor version + local previous_minor=$((minor_version - 1)) + + # Check if previous minor version is valid (non-negative) + if [[ $previous_minor -lt 0 ]]; then + echo "Error: Cannot calculate previous version for $version" >&2 + exit 1 + save_overall_result 1 + fi + + # Return the previous version + echo "${major_version}.${previous_minor}" +} + +get_chart_version() { + local chart_major_version=$1 + curl -sSX GET "https://quay.io/api/v1/repository/rhdh/chart/tag/?onlyActiveTags=true&filter_tag_name=like:${chart_major_version}-" -H "Content-Type: application/json" \ + | jq '.tags[0].name' | grep -oE '[0-9]+\.[0-9]+-[0-9]+-CI' +} + +# Helper function to get dynamic value file path based on previous release version +get_previous_release_value_file() { + local value_file_type=${1:-"showcase"} # Default to showcase, can be "showcase-rbac" for RBAC + + # Get the previous release version + local previous_release_version + previous_release_version=$(get_previous_release_version "$CHART_MAJOR_VERSION") + + if [[ -z "$previous_release_version" ]]; then + echo "Failed to determine previous release version." >&2 + save_overall_result 1 + exit 1 + fi + + echo "Using previous release version: ${previous_release_version}" >&2 + + # Construct the GitHub URL for the value file + local github_url="https://raw.githubusercontent.com/redhat-developer/rhdh/release-${previous_release_version}/.ibm/pipelines/value_files/values_${value_file_type}.yaml" + + # Create a temporary file path for the downloaded value file + local temp_value_file="/tmp/values_${value_file_type}_${previous_release_version}.yaml" + + echo "Fetching value file from: ${github_url}" >&2 + + # Download the value file from GitHub + if curl -fsSL "${github_url}" -o "${temp_value_file}"; then + echo "Successfully downloaded value file to: ${temp_value_file}" >&2 + echo "${temp_value_file}" else - # Linux - using bash parameter expansion - echo "${1,,}" + echo "Failed to download value file from GitHub." >&2 + save_overall_result 1 + exit 1 fi } + +# Helper function to deploy workflows for orchestrator testing +deploy_orchestrator_workflows() { + local namespace=$1 + + local WORKFLOW_REPO="https://github.com/rhdh-orchestrator-test/serverless-workflows.git" + local WORKFLOW_DIR="${DIR}/serverless-workflows" + local WORKFLOW_MANIFESTS="${WORKFLOW_DIR}/workflows/experimentals/user-onboarding/manifests/" + + rm -rf "${WORKFLOW_DIR}" + git clone "${WORKFLOW_REPO}" "${WORKFLOW_DIR}" + + if [[ "$namespace" == "${NAME_SPACE_RBAC}" ]]; then + local pqsl_secret_name="postgres-cred" + local pqsl_user_key="POSTGRES_USER" + local pqsl_password_key="POSTGRES_PASSWORD" + local pqsl_svc_name="postgress-external-db-primary" + local patch_namespace="${NAME_SPACE_POSTGRES_DB}" + else + local pqsl_secret_name="rhdh-postgresql-svcbind-postgres" + local pqsl_user_key="username" + local pqsl_password_key="password" + local pqsl_svc_name="rhdh-postgresql" + local patch_namespace="$namespace" + fi + + oc apply -f "${WORKFLOW_MANIFESTS}" + + helm repo add orchestrator-workflows https://rhdhorchestrator.io/serverless-workflows + helm install greeting orchestrator-workflows/greeting -n "$namespace" + + until [[ $(oc get sf -n "$namespace" --no-headers 2> /dev/null | wc -l) -eq 2 ]]; do + echo "No sf resources found. Retrying in 5 seconds..." + sleep 5 + done + + for workflow in greeting user-onboarding; do + oc -n "$namespace" patch sonataflow "$workflow" --type merge -p "{\"spec\": { \"persistence\": { \"postgresql\": { \"secretRef\": {\"name\": \"$pqsl_secret_name\",\"userKey\": \"$pqsl_user_key\",\"passwordKey\": \"$pqsl_password_key\"},\"serviceRef\": {\"name\": \"$pqsl_svc_name\",\"namespace\": \"$patch_namespace\"}}}}}" + done +} + +# Helper function to deploy workflows for orchestrator testing +deploy_orchestrator_workflows_operator() { + local namespace=$1 + + local WORKFLOW_REPO="https://github.com/rhdh-orchestrator-test/serverless-workflows.git" + local WORKFLOW_DIR="${DIR}/serverless-workflows" + local WORKFLOW_MANIFESTS="${WORKFLOW_DIR}/workflows/experimentals/user-onboarding/manifests/" + + rm -rf "${WORKFLOW_DIR}" + git clone --depth=1 "${WORKFLOW_REPO}" "${WORKFLOW_DIR}" + + # Wait for backstage and sonata flow pods to be ready before continuing + wait_for_deployment $namespace backstage-psql 15 + wait_for_deployment $namespace backstage-rhdh 15 + wait_for_deployment $namespace sonataflow-platform-data 20 + wait_for_deployment $namespace sonataflow-platform-jobs-service 20 + + # Dynamic PostgreSQL configuration detection + # Dynamic discovery of PostgreSQL secret and service using patterns + local pqsl_secret_name + pqsl_secret_name=$(oc get secrets -n "$namespace" -o name | grep "backstage-psql" | grep "secret" | head -1 | sed 's/secret\///') + local pqsl_user_key="POSTGRES_USER" + local pqsl_password_key="POSTGRES_PASSWORD" + local pqsl_svc_name + pqsl_svc_name=$(oc get svc -n "$namespace" -o name | grep "backstage-psql" | grep -v "secret" | head -1 | sed 's/service\///') + local patch_namespace="$namespace" + local sonataflow_db="backstage_plugin_orchestrator" + + # Validate that we found the required resources + if [[ -z "$pqsl_secret_name" ]]; then + echo "Error: No PostgreSQL secret found matching pattern 'backstage-psql.*secret' in namespace '$namespace'" + return 1 + fi + + if [[ -z "$pqsl_svc_name" ]]; then + echo "Error: No PostgreSQL service found matching pattern 'backstage-psql' in namespace '$namespace'" + return 1 + fi + + echo "Found PostgreSQL secret: $pqsl_secret_name" + echo "Found PostgreSQL service: $pqsl_svc_name" + + # Apply user-onboarding workflow manifests + oc apply -f "${WORKFLOW_MANIFESTS}" -n "$namespace" + + # Install greeting workflow via helm + helm repo add orchestrator-workflows https://rhdhorchestrator.io/serverless-workflows || true + helm upgrade --install greeting orchestrator-workflows/greeting -n "$namespace" --wait --timeout=5m --atomic + + # Wait for sonataflow resources to be created (regardless of state) + timeout 30s bash -c " + until [[ \$(oc get sf -n $namespace --no-headers 2>/dev/null | wc -l) -eq 2 ]]; do + echo \"Waiting for 2 sf resources... Current count: \$(oc get sf -n $namespace --no-headers 2>/dev/null | wc -l)\" + sleep 5 + done + " + echo "Updating user-onboarding secret with dynamic service URLs..." + # Update the user-onboarding secret with correct service URLs + local onboarding_server_url="http://user-onboarding-server:8080" + + # Dynamically determine the backstage service (excluding psql) + local backstage_service + backstage_service=$(oc get svc -l app.kubernetes.io/name=backstage -n "$namespace" --no-headers=true | grep -v psql | awk '{print $1}' | head -1) + if [[ -z "$backstage_service" ]]; then + echo "Warning: No backstage service found, using fallback" + backstage_service="backstage-rhdh" + fi + local backstage_notifications_url="http://${backstage_service}:80" + + # Get the notifications bearer token from rhdh-secrets + local notifications_bearer_token + notifications_bearer_token=$(oc get secret rhdh-secrets -n "$namespace" -o json | jq '.data.BACKEND_SECRET' -r | base64 -d) + if [[ -z "$notifications_bearer_token" ]]; then + echo "Warning: No BACKEND_SECRET found in rhdh-secrets, using empty token" + notifications_bearer_token="" + fi + + # Base64 encode the URLs and token + local onboarding_server_url_b64 + onboarding_server_url_b64=$(echo -n "$onboarding_server_url" | base64 -w 0) + local backstage_notifications_url_b64 + backstage_notifications_url_b64=$(echo -n "$backstage_notifications_url" | base64 -w 0) + local notifications_bearer_token_b64 + notifications_bearer_token_b64=$(echo -n "$notifications_bearer_token" | base64 -w 0) + + # Patch the secret + oc patch secret user-onboarding-creds -n "$namespace" --type merge -p "{ + \"data\": { + \"ONBOARDING_SERVER_URL\": \"$onboarding_server_url_b64\", + \"BACKSTAGE_NOTIFICATIONS_URL\": \"$backstage_notifications_url_b64\", + \"NOTIFICATIONS_BEARER_TOKEN\": \"$notifications_bearer_token_b64\" + } + }" + echo "User-onboarding secret updated successfully!" + + for workflow in greeting user-onboarding; do + # Create PostgreSQL patch configuration + local postgres_patch + postgres_patch=$( + cat << EOF +{ + "spec": { + "persistence": { + "postgresql": { + "secretRef": { + "name": "$pqsl_secret_name", + "userKey": "$pqsl_user_key", + "passwordKey": "$pqsl_password_key" + }, + "serviceRef": { + "name": "$pqsl_svc_name", + "namespace": "$patch_namespace", + "databaseName": "$sonataflow_db" + } + } + } + } +} +EOF + ) + + echo "Patching SonataFlow '$workflow' with PostgreSQL configuration..." + oc -n "$namespace" patch sonataflow "$workflow" --type merge -p "$postgres_patch" + + echo "Restarting deployment for '$workflow'..." + oc rollout status deployment/"$workflow" -n "$namespace" --timeout=600s + done + + echo "Waiting for all workflow pods to be running..." + wait_for_deployment $namespace greeting 5 + wait_for_deployment $namespace user-onboarding 5 + + echo "All workflow pods are now running!" +} + +# Helper function to wait for backstage resource to exist in namespace +wait_for_backstage_resource() { + local namespace=$1 + local max_attempts=40 # 40 attempts * 15 seconds = 10 minutes + + local sleep_interval=15 + + echo "Waiting for backstage resource to exist in namespace: $namespace" + + for ((i = 1; i <= max_attempts; i++)); do + if [[ $(oc get backstage -n "$namespace" -o json | jq '.items | length') -gt 0 ]]; then + echo "Backstage resource found in namespace: $namespace" + return 0 + fi + echo "Attempt $i/$max_attempts: No backstage resource found, waiting ${sleep_interval}s..." + sleep $sleep_interval + done + + echo "Error: No backstage resource found after 10 minutes" + return 1 +} + +# Helper function to enable orchestrator plugins by merging default and custom dynamic plugins +enable_orchestrator_plugins_op() { + local namespace=$1 + + # Validate required parameter + if [[ -z "$namespace" ]]; then + echo "Error: Missing required namespace parameter" + echo "Usage: enable_orchestrator_plugins_op " + return 1 + fi + + echo "Enabling orchestrator plugins in namespace: $namespace" + + # Wait for backstage resource to exist + wait_for_backstage_resource "$namespace" + sleep 5 + + # Setup working directory + local work_dir="/tmp/orchestrator-plugins-merge" + rm -rf "$work_dir" && mkdir -p "$work_dir" + + # Extract custom dynamic plugins configmap + echo "Extracting custom dynamic plugins configmap..." + if ! oc get cm dynamic-plugins -n "$namespace" -o json | jq '.data."dynamic-plugins.yaml"' -r > "$work_dir/custom-plugins.yaml"; then + echo "Error: Failed to extract dynamic-plugins configmap" + return 1 + fi + + # Find and extract default configmap + echo "Finding default dynamic plugins configmap..." + local default_cm + default_cm=$(oc get cm -n "$namespace" --no-headers | grep "backstage-dynamic-plugins" | awk '{print $1}' | head -1) + + if [[ -z "$default_cm" ]]; then + echo "Error: No default configmap found matching pattern 'backstage-dynamic-plugins-'" + return 1 + fi + + echo "Found default configmap: $default_cm" + if ! oc get cm "$default_cm" -n "$namespace" -o json | jq '.data."dynamic-plugins.yaml"' -r > "$work_dir/default-plugins.yaml"; then + echo "Error: Failed to extract $default_cm configmap" + return 1 + fi + + # Extract plugins array with disabled: false and append to custom plugins + echo "Extracting and enabling default plugins..." + if ! yq eval '.plugins | map(. + {"disabled": false})' "$work_dir/default-plugins.yaml" > "$work_dir/default-plugins-array.yaml"; then + echo "Error: Failed to extract and modify plugins array from default file" + return 1 + fi + + if ! yq eval '.plugins += load("'$work_dir'/default-plugins-array.yaml")' -i "$work_dir/custom-plugins.yaml"; then + echo "Error: Failed to append default plugins to custom plugins" + return 1 + fi + + # Use the modified custom file as the final merged result + if ! cp "$work_dir/custom-plugins.yaml" "$work_dir/merged-plugins.yaml"; then + echo "Error: Failed to create merged plugins file" + return 1 + fi + + # Apply new configmap with merged content + if ! oc create configmap dynamic-plugins \ + --from-file="dynamic-plugins.yaml=$work_dir/merged-plugins.yaml" \ + -n "$namespace" --dry-run=client -o yaml | oc apply -f -; then + echo "Error: Failed to apply updated dynamic-plugins configmap" + return 1 + fi + + # Find and restart backstage deployment + echo "Finding backstage deployment..." + local backstage_deployment + backstage_deployment=$(oc get deployment -n "$namespace" --no-headers | grep "^backstage-rhdh" | awk '{print $1}' | head -1) + + if [[ -z "$backstage_deployment" ]]; then + echo "Error: No backstage deployment found matching pattern 'backstage-rhdh*'" + return 1 + fi + + echo "Restarting backstage deployment: $backstage_deployment" + if ! oc rollout restart deployment/"$backstage_deployment" -n "$namespace"; then + echo "Error: Failed to restart backstage deployment" + return 1 + fi + + # Cleanup + rm -rf "$work_dir" + + echo "Successfully enabled orchestrator plugins in namespace: $namespace" +} diff --git a/.ibm/pipelines/value_files/diff-values_showcase-rbac_AKS.yaml b/.ibm/pipelines/value_files/diff-values_showcase-rbac_AKS.yaml index 716484371d..e6a0891e09 100644 --- a/.ibm/pipelines/value_files/diff-values_showcase-rbac_AKS.yaml +++ b/.ibm/pipelines/value_files/diff-values_showcase-rbac_AKS.yaml @@ -1,6 +1,6 @@ -# This file is for AKS installation only. +# This file is for AKS installation only. # It is applied by `helm upgrade` after the `values-showcase.yaml` is applied and only contains complementary differences for AKS. -# Note, that it overwrites the whole key that is present in this file. +# Note, that it overwrites the whole key that is present in this file. # The only exception is global.dynamic.plugins, that gets merged with the base file. route: enabled: false @@ -37,16 +37,16 @@ upstream: valueFrom: secretKeyRef: key: postgres-password - name: '{{ .Release.Name }}-postgresql' + name: "{{ .Release.Name }}-postgresql" # disable telemetry in CI - name: SEGMENT_TEST_MODE - value: 'true' + value: "true" - name: NODE_TLS_REJECT_UNAUTHORIZED - value: '0' + value: "0" - name: NODE_ENV - value: 'production' + value: "production" - name: ENABLE_CORE_ROOTHTTPROUTER_OVERRIDE - value: 'true' + value: "true" extraVolumeMounts: # The initContainer below will install dynamic plugins in this volume mount. - name: dynamic-plugins-root @@ -61,18 +61,12 @@ upstream: # could be changed to a [generic ephemeral volume](https://docs.openshift.com/container-platform/4.13/storage/generic-ephemeral-vols.html#generic-ephemeral-vols-procedure_generic-ephemeral-volumes). - name: dynamic-plugins-root emptyDir: {} - - name: rbac-policy - configMap: - defaultMode: 420 - name: rbac-policy - - name: rbac-conditions - emptyDir: {} # Volume that will expose the `dynamic-plugins.yaml` file from the `dynamic-plugins` config map. # The `dynamic-plugins` config map is created by the helm chart from the content of the `global.dynamic` field. - name: dynamic-plugins configMap: defaultMode: 420 - name: dynamic-plugins + name: '{{ printf "%s-dynamic-plugins" .Release.Name }}' optional: true # Optional volume that allows exposing the `.npmrc` file (through a `dynamic-plugins-npmrc` secret) # to be used when running `npm pack` during the dynamic plugins installation by the initContainer. @@ -80,7 +74,18 @@ upstream: secret: defaultMode: 420 optional: true - secretName: dynamic-plugins-npmrc + secretName: '{{ printf "%s-dynamic-plugins-npmrc" .Release.Name }}' + - name: dynamic-plugins-registry-auth + secret: + defaultMode: 416 + optional: true + secretName: '{{ printf "%s-dynamic-plugins-registry-auth" .Release.Name }}' + - name: rbac-policy + configMap: + defaultMode: 420 + name: rbac-policy + - name: rbac-conditions + emptyDir: {} extraEnvVarsSecrets: - rhdh-secrets podSecurityContext: @@ -116,26 +121,27 @@ upstream: valueFrom: secretKeyRef: key: postgres-password - name: '{{ .Release.Name }}-postgresql' + name: "{{ .Release.Name }}-postgresql" # Tolerations and affinity needed to be scheduled on a spot AKS cluster. Only `postgresql` require it. tolerations: - - key: "kubernetes.azure.com/scalesetpriority" - operator: "Equal" - value: "spot" - effect: "NoSchedule" + - key: "kubernetes.azure.com/scalesetpriority" + operator: "Equal" + value: "spot" + effect: "NoSchedule" affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - - weight: 1 - preference: - matchExpressions: - - key: "kubernetes.azure.com/scalesetpriority" - operator: In - values: - - "spot" + - weight: 1 + preference: + matchExpressions: + - key: "kubernetes.azure.com/scalesetpriority" + operator: In + values: + - "spot" volumePermissions: enabled: true ingress: enabled: true className: webapprouting.kubernetes.azure.com - host: '' \ No newline at end of file + host: "" +orchestrator: null diff --git a/.ibm/pipelines/value_files/diff-values_showcase-rbac_EKS.yaml b/.ibm/pipelines/value_files/diff-values_showcase-rbac_EKS.yaml new file mode 100644 index 0000000000..e6b5448cde --- /dev/null +++ b/.ibm/pipelines/value_files/diff-values_showcase-rbac_EKS.yaml @@ -0,0 +1,139 @@ +# This file is for EKS installation only. +# It is applied by `helm upgrade` after the `values-showcase.yaml` is applied and only contains complementary differences for EKS. +# Note, that it overwrites the whole key that is present in this file. +# The only exception is global.dynamic.plugins, that gets merged with the base file. +route: + enabled: false +global: + dynamic: + plugins: [] +upstream: + backstage: + appConfig: + app: + # Please update to match host in case you don't want to configure hostname via `global.clusterRouterBase` or `global.host`. + baseUrl: 'https://{{- include "janus-idp.hostname" . }}' + backend: + baseUrl: 'https://{{- include "janus-idp.hostname" . }}' + cors: + origin: 'https://{{- include "janus-idp.hostname" . }}' + database: + connection: + host: null + port: null + password: ${POSTGRESQL_ADMIN_PASSWORD} + user: postgres + ssl: null + auth: + keys: + - secret: ${BACKEND_SECRET} + extraEnvVars: + - name: BACKEND_SECRET + valueFrom: + secretKeyRef: + key: backend-secret + name: '{{ include "janus-idp.backend-secret-name" $ }}' + - name: POSTGRESQL_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: postgres-password + name: "{{ .Release.Name }}-postgresql" + # disable telemetry in CI + - name: SEGMENT_TEST_MODE + value: "true" + - name: NODE_TLS_REJECT_UNAUTHORIZED + value: "0" + - name: NODE_ENV + value: "production" + - name: ENABLE_CORE_ROOTHTTPROUTER_OVERRIDE + value: "true" + extraVolumeMounts: + # The initContainer below will install dynamic plugins in this volume mount. + - name: dynamic-plugins-root + mountPath: /opt/app-root/src/dynamic-plugins-root + - name: rbac-policy + mountPath: /opt/app-root/src/rbac + - name: rbac-conditions + mountPath: /opt/app-root/src/rbac-conditions + extraVolumes: + # -- Ephemeral volume that will contain the dynamic plugins installed by the initContainer below at start. + # To have more control on underlying storage, the [emptyDir](https://docs.openshift.com/container-platform/4.13/storage/understanding-ephemeral-storage.html) + # could be changed to a [generic ephemeral volume](https://docs.openshift.com/container-platform/4.13/storage/generic-ephemeral-vols.html#generic-ephemeral-vols-procedure_generic-ephemeral-volumes). + - name: dynamic-plugins-root + emptyDir: {} + # Volume that will expose the `dynamic-plugins.yaml` file from the `dynamic-plugins` config map. + # The `dynamic-plugins` config map is created by the helm chart from the content of the `global.dynamic` field. + - name: dynamic-plugins + configMap: + defaultMode: 420 + name: '{{ printf "%s-dynamic-plugins" .Release.Name }}' + optional: true + # Optional volume that allows exposing the `.npmrc` file (through a `dynamic-plugins-npmrc` secret) + # to be used when running `npm pack` during the dynamic plugins installation by the initContainer. + - name: dynamic-plugins-npmrc + secret: + defaultMode: 420 + optional: true + secretName: '{{ printf "%s-dynamic-plugins-npmrc" .Release.Name }}' + - name: dynamic-plugins-registry-auth + secret: + defaultMode: 416 + optional: true + secretName: '{{ printf "%s-dynamic-plugins-registry-auth" .Release.Name }}' + - name: rbac-policy + configMap: + defaultMode: 420 + name: rbac-policy + - name: rbac-conditions + emptyDir: {} + extraEnvVarsSecrets: + - rhdh-secrets + podSecurityContext: + fsGroup: 3000 + startupProbe: + failureThreshold: 10 # Override the default to account for longer startup time on Kubernetes. + postgresql: + enabled: true + postgresqlDataDir: /var/lib/pgsql/data/userdata + image: + registry: quay.io + repository: fedora/postgresql-15 + tag: latest + auth: + secretKeys: + adminPasswordKey: postgres-password + userPasswordKey: password + existingSecret: null + primary: + securityContext: + enabled: false + podSecurityContext: + enabled: true + fsGroup: 3000 + containerSecurityContext: + enabled: false + persistence: + enabled: true + size: 1Gi + mountPath: /var/lib/pgsql/data + extraEnvVars: + - name: POSTGRESQL_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: postgres-password + name: "{{ .Release.Name }}-postgresql" + volumePermissions: + enabled: true + service: + # NodePort is required for the ALB to route to the Service + type: NodePort + ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: alb + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/certificate-arn: $EKS_DOMAIN_NAME_CERTIFICATE_ARN + alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' + alb.ingress.kubernetes.io/ssl-redirect: "443" + external-dns.alpha.kubernetes.io/hostname: $EKS_INSTANCE_DOMAIN_NAME +orchestrator: null diff --git a/.ibm/pipelines/value_files/diff-values_showcase-rbac_GKE.yaml b/.ibm/pipelines/value_files/diff-values_showcase-rbac_GKE.yaml index 33981f3266..f147af0706 100644 --- a/.ibm/pipelines/value_files/diff-values_showcase-rbac_GKE.yaml +++ b/.ibm/pipelines/value_files/diff-values_showcase-rbac_GKE.yaml @@ -1,6 +1,6 @@ -# This file is for GKE installation only. +# This file is for GKE installation only. # It is applied by `helm upgrade` after the `values-showcase.yaml` is applied and only contains complementary differences for GKE. -# Note, that it overwrites the whole key that is present in this file. +# Note, that it overwrites the whole key that is present in this file. # e.g. global.dynamic.plugins key is completely overwritten by the content of this file. route: enabled: false @@ -37,16 +37,16 @@ upstream: valueFrom: secretKeyRef: key: postgres-password - name: '{{ .Release.Name }}-postgresql' + name: "{{ .Release.Name }}-postgresql" # disable telemetry in CI - name: SEGMENT_TEST_MODE - value: 'true' + value: "true" - name: NODE_TLS_REJECT_UNAUTHORIZED - value: '0' + value: "0" - name: NODE_ENV - value: 'production' + value: "production" - name: ENABLE_CORE_ROOTHTTPROUTER_OVERRIDE - value: 'true' + value: "true" extraVolumeMounts: # The initContainer below will install dynamic plugins in this volume mount. - name: dynamic-plugins-root @@ -61,18 +61,12 @@ upstream: # could be changed to a [generic ephemeral volume](https://docs.openshift.com/container-platform/4.13/storage/generic-ephemeral-vols.html#generic-ephemeral-vols-procedure_generic-ephemeral-volumes). - name: dynamic-plugins-root emptyDir: {} - - name: rbac-policy - configMap: - defaultMode: 420 - name: rbac-policy - - name: rbac-conditions - emptyDir: {} # Volume that will expose the `dynamic-plugins.yaml` file from the `dynamic-plugins` config map. # The `dynamic-plugins` config map is created by the helm chart from the content of the `global.dynamic` field. - name: dynamic-plugins configMap: defaultMode: 420 - name: dynamic-plugins + name: '{{ printf "%s-dynamic-plugins" .Release.Name }}' optional: true # Optional volume that allows exposing the `.npmrc` file (through a `dynamic-plugins-npmrc` secret) # to be used when running `npm pack` during the dynamic plugins installation by the initContainer. @@ -80,7 +74,18 @@ upstream: secret: defaultMode: 420 optional: true - secretName: dynamic-plugins-npmrc + secretName: '{{ printf "%s-dynamic-plugins-npmrc" .Release.Name }}' + - name: dynamic-plugins-registry-auth + secret: + defaultMode: 416 + optional: true + secretName: '{{ printf "%s-dynamic-plugins-registry-auth" .Release.Name }}' + - name: rbac-policy + configMap: + defaultMode: 420 + name: rbac-policy + - name: rbac-conditions + emptyDir: {} extraEnvVarsSecrets: - rhdh-secrets podSecurityContext: @@ -116,17 +121,18 @@ upstream: valueFrom: secretKeyRef: key: postgres-password - name: '{{ .Release.Name }}-postgresql' + name: "{{ .Release.Name }}-postgresql" volumePermissions: enabled: true service: type: NodePort ingress: enabled: true - host: '' + host: "" annotations: kubernetes.io/ingress.class: gce kubernetes.io/ingress.global-static-ip-name: rhdh-static-ip ingress.gcp.kubernetes.io/pre-shared-cert: "" networking.gke.io/v1beta1.FrontendConfig: rhdh-gke-ingress-security-config - className: gce \ No newline at end of file + className: gce +orchestrator: null diff --git a/.ibm/pipelines/value_files/diff-values_showcase-sanity-plugins.yaml b/.ibm/pipelines/value_files/diff-values_showcase-sanity-plugins.yaml index 875796bac9..fab6e54bdd 100644 --- a/.ibm/pipelines/value_files/diff-values_showcase-sanity-plugins.yaml +++ b/.ibm/pipelines/value_files/diff-values_showcase-sanity-plugins.yaml @@ -19,7 +19,7 @@ global: username: "temp" password: "temp" appLocatorMethods: - - type: 'config' + - type: "config" instances: - name: argoInstance1 url: "temp" @@ -30,7 +30,7 @@ global: username: "temp" password: "temp" appLocatorMethods: - - type: 'config' + - type: "config" instances: - name: argoInstance1 url: "temp" @@ -51,9 +51,9 @@ global: jenkins: instances: - name: default - baseUrl: 'temp' - username: 'temp' - apiKey: 'temp' + baseUrl: "temp" + username: "temp" + apiKey: "temp" - package: ./dynamic-plugins/dist/backstage-community-plugin-jenkins disabled: false - package: ./dynamic-plugins/dist/backstage-plugin-notifications @@ -67,7 +67,7 @@ global: processors: email: transportConfig: - sender: 'temp' + sender: "temp" - package: ./dynamic-plugins/dist/backstage-plugin-signals-backend-dynamic disabled: false - package: ./dynamic-plugins/dist/backstage-plugin-signals @@ -78,9 +78,9 @@ global: sonarqube: instances: - name: default - instanceKey: 'mySonarqube' - baseUrl: 'https://default-sonarqube.example.com' - apiKey: '123456789abcdef0123456789abcedf012' + instanceKey: "mySonarqube" + baseUrl: "https://default-sonarqube.example.com" + apiKey: "123456789abcdef0123456789abcedf012" - package: ./dynamic-plugins/dist/backstage-community-plugin-sonarqube disabled: false - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page @@ -103,11 +103,11 @@ global: disabled: true pluginConfig: pagerDuty: - apiBaseUrl: 'temp' + apiBaseUrl: "temp" oauth: - clientId: 'temp' - clientSecret: 'temp' - subDomain: 'temp' + clientId: "temp" + clientSecret: "temp" + subDomain: "temp" - package: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-gerrit-dynamic disabled: false - package: ./dynamic-plugins/dist/roadiehq-scaffolder-backend-module-utils-dynamic @@ -123,11 +123,11 @@ global: pluginConfig: servicenow: # The base url of the ServiceNow instance. - baseUrl: 'temp' + baseUrl: "temp" # The username to use for authentication. - username: 'temp' + username: "temp" # The password to use for authentication. - password: 'temp' + password: "temp" - package: ./dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic disabled: false - package: ./dynamic-plugins/dist/backstage-community-plugin-3scale-backend-dynamic @@ -137,8 +137,8 @@ global: providers: threeScaleApiEntity: default: - baseUrl: 'temp' - accessToken: 'temp' + baseUrl: "temp" + accessToken: "temp" - package: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic disabled: false pluginConfig: @@ -147,7 +147,7 @@ global: providers: bitbucketCloud: default: # identifies your ingested dataset - workspace: 'temp' + workspace: "temp" - package: ./dynamic-plugins/dist/backstage-community-plugin-dynatrace disabled: false - package: ./dynamic-plugins/dist/roadiehq-backstage-plugin-jira @@ -165,8 +165,7 @@ global: - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic disabled: false - package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-msgraph-dynamic - disabled: true - # TODO: Fix failing test and re-enable plugin - https://issues.redhat.com/browse/RHDHBUGS-1871 + disabled: false pluginConfig: catalog: providers: @@ -176,7 +175,39 @@ global: tenantId: temp clientId: temp clientSecret: temp + schedule: + frequency: + minutes: 60 + initialDelay: + seconds: 15 + timeout: + minutes: 15 - package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-ldap-dynamic disabled: false + pluginConfig: + catalog: + providers: + ldapOrg: + default: + target: temp + bind: + dn: temp + secret: temp + users: + - dn: temp + options: + filter: (uid=*) + groups: + - dn: temp + options: + filter: (cn=*) + schedule: + frequency: + minutes: 60 + initialDelay: + seconds: 15 + timeout: + minutes: 15 + - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic disabled: false diff --git a/.ibm/pipelines/value_files/diff-values_showcase_AKS.yaml b/.ibm/pipelines/value_files/diff-values_showcase_AKS.yaml index b79cba91f9..17433f1a11 100644 --- a/.ibm/pipelines/value_files/diff-values_showcase_AKS.yaml +++ b/.ibm/pipelines/value_files/diff-values_showcase_AKS.yaml @@ -24,23 +24,24 @@ upstream: fsGroup: 3000 # Tolerations and affinity needed to be scheduled on a spot AKS cluster. Only `postgresql` require it. tolerations: - - key: "kubernetes.azure.com/scalesetpriority" - operator: "Equal" - value: "spot" - effect: "NoSchedule" + - key: "kubernetes.azure.com/scalesetpriority" + operator: "Equal" + value: "spot" + effect: "NoSchedule" affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - - weight: 1 - preference: - matchExpressions: - - key: "kubernetes.azure.com/scalesetpriority" - operator: In - values: - - "spot" + - weight: 1 + preference: + matchExpressions: + - key: "kubernetes.azure.com/scalesetpriority" + operator: In + values: + - "spot" volumePermissions: enabled: true ingress: enabled: true className: webapprouting.kubernetes.azure.com - host: '' + host: "" +orchestrator: null diff --git a/.ibm/pipelines/value_files/diff-values_showcase_EKS.yaml b/.ibm/pipelines/value_files/diff-values_showcase_EKS.yaml new file mode 100644 index 0000000000..45b345eb31 --- /dev/null +++ b/.ibm/pipelines/value_files/diff-values_showcase_EKS.yaml @@ -0,0 +1,41 @@ +# This file is for EKS installation only. +# It is applied by `helm upgrade` after the `values-showcase.yaml` is applied and only contains complementary differences for EKS. +# Note, that it overwrites the whole key that is present in this file. +# The only exception is global.dynamic.plugins, that gets merged with the base file. +# The place holders will be replaced by ENV variables by `envsubst` command` +route: + enabled: false +global: + host: $EKS_INSTANCE_DOMAIN_NAME + dynamic: + plugins: + - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic + disabled: false +upstream: + backstage: + extraEnvVarsSecrets: + - rhdh-secrets + podSecurityContext: + fsGroup: 3000 + startupProbe: + failureThreshold: 10 # Override the default to account for longer startup time on Kubernetes. + postgresql: + primary: + podSecurityContext: + enabled: true + fsGroup: 3000 + volumePermissions: + enabled: true + service: + # NodePort is required for the ALB to route to the Service + type: NodePort + ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: alb + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/certificate-arn: $EKS_DOMAIN_NAME_CERTIFICATE_ARN + alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' + alb.ingress.kubernetes.io/ssl-redirect: "443" + external-dns.alpha.kubernetes.io/hostname: $EKS_INSTANCE_DOMAIN_NAME +orchestrator: null diff --git a/.ibm/pipelines/value_files/diff-values_showcase_GKE.yaml b/.ibm/pipelines/value_files/diff-values_showcase_GKE.yaml index 14eccabc1e..68bbb9ec23 100644 --- a/.ibm/pipelines/value_files/diff-values_showcase_GKE.yaml +++ b/.ibm/pipelines/value_files/diff-values_showcase_GKE.yaml @@ -34,3 +34,4 @@ upstream: ingress.gcp.kubernetes.io/pre-shared-cert: "" networking.gke.io/v1beta1.FrontendConfig: rhdh-gke-ingress-security-config className: gce +orchestrator: null diff --git a/.ibm/pipelines/value_files/diff-values_showcase_upgrade.yaml b/.ibm/pipelines/value_files/diff-values_showcase_upgrade.yaml new file mode 100644 index 0000000000..e89df06861 --- /dev/null +++ b/.ibm/pipelines/value_files/diff-values_showcase_upgrade.yaml @@ -0,0 +1 @@ +orchestrator: null diff --git a/.ibm/pipelines/value_files/values_showcase-auth-providers.yaml b/.ibm/pipelines/value_files/values_showcase-auth-providers.yaml index e9af26bf92..d2920c3b9a 100644 --- a/.ibm/pipelines/value_files/values_showcase-auth-providers.yaml +++ b/.ibm/pipelines/value_files/values_showcase-auth-providers.yaml @@ -18,7 +18,7 @@ upstream: auth: environment: production session: - secret: superSecretSecret + secret: superSecretSecret providers: guest: dangerouslyAllowOutsideDevelopment: true @@ -42,7 +42,7 @@ upstream: metadataUrl: ${RHSSO76_METADATA_URL} clientId: ${RHSSO76_CLIENT_ID} clientSecret: ${RHSSO76_CLIENT_SECRET} - prompt: auto + prompt: auto callbackUrl: ${RHSSO76_CALLBACK_URL} signIn: resolvers: @@ -69,12 +69,12 @@ upstream: - type: url target: https://github.com/redhat-developer/red-hat-developer-hub-software-templates/blob/main/templates.yaml rules: - - allow: [API, Component, Group, User, Resource, Location, System, Template] + - allow: [API, Component, Group, User, Resource, Location, System, Template] providers: githubOrg: - id: github githubUrl: https://github.com - orgs: ['${AUTH_PROVIDERS_GH_ORG_NAME}'] + orgs: ["${AUTH_PROVIDERS_GH_ORG_NAME}"] schedule: initialDelay: { seconds: 0 } frequency: { minutes: 1 } @@ -110,7 +110,7 @@ upstream: enabled: true rbac: policyFileReload: true - policies-csv-file: './rbac/rbac-policy.csv' + policies-csv-file: "./rbac/rbac-policy.csv" admin: users: - name: user:default/qeadmin_rhdhtesting.onmicrosoft.com @@ -128,7 +128,7 @@ upstream: image: registry: quay.io repository: rhdh/rhdh-hub-rhel9 - tag: 'next' + tag: "next" readinessProbe: failureThreshold: 3 httpGet: @@ -159,15 +159,15 @@ upstream: valueFrom: secretKeyRef: key: postgres-password - name: '{{ .Release.Name }}-postgresql' + name: "{{ .Release.Name }}-postgresql" # disable telemetry in CI - name: SEGMENT_TEST_MODE - value: 'true' + value: "true" - name: NODE_OPTIONS - value: '--no-node-snapshot' + value: "--no-node-snapshot" args: # This additional `app-config`` file is generated by the initContainer below, and contains the merged configuration of installed dynamic plugins. - - '--config' + - "--config" - dynamic-plugins-root/app-config.dynamic-plugins.yaml extraVolumeMounts: - mountPath: /opt/app-root/src/dynamic-plugins-root @@ -252,6 +252,6 @@ upstream: valueFrom: secretKeyRef: key: postgres-password - name: '{{ .Release.Name }}-postgresql' + name: "{{ .Release.Name }}-postgresql" ingress: - host: '{{ .Values.global.host }}' \ No newline at end of file + host: "{{ .Values.global.host }}" diff --git a/.ibm/pipelines/value_files/values_showcase-rbac.yaml b/.ibm/pipelines/value_files/values_showcase-rbac.yaml index f1b5f5f63f..0c340ddbf1 100644 --- a/.ibm/pipelines/value_files/values_showcase-rbac.yaml +++ b/.ibm/pipelines/value_files/values_showcase-rbac.yaml @@ -5,7 +5,7 @@ global: includes: # -- List of dynamic plugins included inside the `rhdh-community/rhdh` container image, some of which are disabled by default. # This file ONLY works with the `rhdh-community/rhdh` container image. - - 'dynamic-plugins.default.yaml' + - "dynamic-plugins.default.yaml" # -- List of dynamic plugins, possibly overriding the plugins listed in `includes` files. # Every item defines the plugin `package` as a [NPM package spec](https://docs.npmjs.com/cli/v10/using-npm/package-spec), @@ -20,7 +20,7 @@ global: github: my-test-org: organization: janus-qe - catalogPath: '/catalog-info.yaml' + catalogPath: "/catalog-info.yaml" schedule: frequency: minutes: 1 @@ -53,16 +53,16 @@ global: clusterLocatorMethods: - clusters: - authProvider: serviceAccount - name: 'my-cluster' + name: "my-cluster" serviceAccountToken: ${K8S_CLUSTER_TOKEN_ENCODED} url: ${K8S_CLUSTER_API_SERVER_URL} skipTLSVerify: true type: config customResources: # Add for tekton - - apiVersion: 'v1beta1' - group: 'tekton.dev' - plural: 'pipelines' + - apiVersion: "v1beta1" + group: "tekton.dev" + plural: "pipelines" - apiVersion: v1beta1 group: tekton.dev plural: pipelineruns @@ -70,9 +70,9 @@ global: group: tekton.dev plural: taskruns # Add for topology plugin - - apiVersion: 'v1' - group: 'route.openshift.io' - plural: 'routes' + - apiVersion: "v1" + group: "route.openshift.io" + plural: "routes" serviceLocatorMethod: type: multiTenant # Enable OCM plugins. @@ -108,6 +108,40 @@ global: disabled: false - package: ./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment disabled: true + #Enable Scorecard plugin. + - disabled: false + package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard + pluginConfig: + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-scorecard: + entityTabs: + - path: "/scorecard" + title: Scorecard + titleKey: catalog.entityPage.scorecard.title + mountPoint: entity.page.scorecard + mountPoints: + - mountPoint: entity.page.scorecard/cards + importName: EntityScorecardContent + config: + layout: + gridColumn: 1 / -1 + - disabled: false + package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard-backend + - disabled: false + package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github + pluginConfig: + integrations: + github: + - host: github.com + token: "{gh-token}" + - disabled: false + package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira + pluginConfig: + jira: + baseUrl: "{jira-base-url}" + token: "{jira-api-token}" + product: datacenter # -- Upstream Backstage [chart configuration](https://github.com/backstage/charts/blob/main/charts/backstage/values.yaml) # @default -- Use Openshift compatible settings @@ -192,11 +226,11 @@ upstream: name: '{{ include "janus-idp.backend-secret-name" $ }}' # disable telemetry in CI - name: SEGMENT_TEST_MODE - value: 'true' + value: "true" - name: NODE_TLS_REJECT_UNAUTHORIZED - value: '0' + value: "0" - name: NODE_ENV - value: 'production' + value: "production" extraVolumeMounts: # The initContainer below will install dynamic plugins in this volume mount. - name: dynamic-plugins-root @@ -256,7 +290,7 @@ upstream: image: '{{ include "backstage.image" . }}' command: - sh - - '-c' + - "-c" - | cat > /rbac-conditions/conditional-policies.yaml < void;\n private rootDirectoryWatcher?: chokidar.FSWatcher;\n private subscribers: (() => void)[] = [];\n\n private constructor(\n private readonly config: Config,\n private readonly logger: LoggerService,\n private readonly backstageRoot: string,\n private readonly preferAlpha: boolean,\n ) {}\n\n static create(options: DynamicPluginScannerOptions): PluginScanner {\n const scanner = new PluginScanner(\n options.config,\n options.logger,\n options.backstageRoot,\n options.preferAlpha || false,\n );\n scanner.applyConfig();\n return scanner;\n }\n\n subscribeToRootDirectoryChange(subscriber: () => void) {\n this.subscribers.push(subscriber);\n }\n\n get rootDirectory(): string | undefined {\n return this._rootDirectory;\n }\n\n private applyConfig(): void | never {\n const dynamicPlugins = this.config.getOptional(configKey);\n if (!dynamicPlugins) {\n this.logger.info(`'${configKey}' config entry not found.`);\n this._rootDirectory = undefined;\n return;\n }\n if (typeof dynamicPlugins !== 'object') {\n this.logger.warn(`'${configKey}' config entry should be an object.`);\n this._rootDirectory = undefined;\n return;\n }\n if (!('rootDirectory' in dynamicPlugins)) {\n this.logger.warn(\n `'${configKey}' config entry does not contain the 'rootDirectory' field.`,\n );\n this._rootDirectory = undefined;\n return;\n }\n if (typeof dynamicPlugins.rootDirectory !== 'string') {\n this.logger.warn(\n `'${configKey}.rootDirectory' config entry should be a string.`,\n );\n this._rootDirectory = undefined;\n return;\n }\n\n const dynamicPluginsRootPath = path.isAbsolute(dynamicPlugins.rootDirectory)\n ? path.resolve(dynamicPlugins.rootDirectory)\n : path.resolve(this.backstageRoot, dynamicPlugins.rootDirectory);\n\n if (\n !path\n .dirname(dynamicPluginsRootPath)\n .startsWith(path.resolve(this.backstageRoot))\n ) {\n const nodePath = process.env.NODE_PATH;\n const backstageNodeModules = path.resolve(\n this.backstageRoot,\n 'node_modules',\n );\n if (\n !nodePath ||\n !nodePath.split(path.delimiter).includes(backstageNodeModules)\n ) {\n throw new Error(\n `Dynamic plugins under '${dynamicPluginsRootPath}' cannot access backstage modules in '${backstageNodeModules}'.\\n` +\n `Please add '${backstageNodeModules}' to the 'NODE_PATH' when running the backstage backend.`,\n );\n }\n }\n if (!lstatSync(dynamicPluginsRootPath).isDirectory()) {\n throw new Error('Not a directory');\n }\n\n this._rootDirectory = dynamicPluginsRootPath;\n }\n\n async scanRoot(): Promise {\n if (!this._rootDirectory) {\n return { packages: [] };\n }\n\n const dynamicPluginsLocation = this._rootDirectory;\n const scannedPlugins: ScannedPluginPackage[] = [];\n for (const dirEnt of await fs.readdir(dynamicPluginsLocation, {\n withFileTypes: true,\n })) {\n const pluginDir = dirEnt;\n\n if (pluginDir.name === 'lost+found') {\n this.logger.debug(`skipping '${pluginDir.name}' system directory`);\n continue;\n }\n const pluginHome = path.normalize(\n path.resolve(dynamicPluginsLocation, pluginDir.name),\n );\n if (dirEnt.isSymbolicLink()) {\n if (!(await fs.lstat(await fs.readlink(pluginHome))).isDirectory()) {\n this.logger.info(\n `skipping '${pluginHome}' since it is not a directory`,\n );\n continue;\n }\n } else if (!dirEnt.isDirectory()) {\n this.logger.info(\n `skipping '${pluginHome}' since it is not a directory`,\n );\n continue;\n }\n\n let scannedPlugin: ScannedPluginPackage;\n try {\n scannedPlugin = await this.scanDir(pluginHome);\n if (!scannedPlugin.manifest.main) {\n throw new Error(\"field 'main' not found in 'package.json'\");\n }\n if (!scannedPlugin.manifest.backstage?.role) {\n throw new Error(\"field 'backstage.role' not found in 'package.json'\");\n }\n } catch (e) {\n if (e instanceof ForwardedError) {\n this.logger.error(e.message, e.cause);\n } else {\n this.logger.error(\n `failed to load dynamic plugin manifest from '${pluginHome}'`,\n e,\n );\n }\n continue;\n }\n scannedPlugins.push(scannedPlugin);\n }\n return { packages: scannedPlugins };\n }\n\n private async scanDir(pluginHome: string): Promise {\n const manifestFile = path.resolve(pluginHome, 'package.json');\n const content = await fs.readFile(manifestFile);\n const manifest: ScannedPluginManifest = JSON.parse(content.toString());\n const scannedPluginPackage: ScannedPluginPackage = {\n location: url.pathToFileURL(pluginHome),\n manifest: manifest,\n };\n\n if (this.preferAlpha) {\n const pluginHomeAlpha = path.resolve(pluginHome, 'alpha');\n if (existsSync(pluginHomeAlpha)) {\n if ((await fs.lstat(pluginHomeAlpha)).isDirectory()) {\n try {\n const alphaContent = await fs.readFile(\n path.resolve(pluginHomeAlpha, 'package.json'),\n );\n scannedPluginPackage.alphaManifest = JSON.parse(\n alphaContent.toString(),\n );\n } catch (e) {\n throw new ForwardedError(\n `failed to load dynamic plugin manifest from '${pluginHome}/alpha'`,\n e,\n );\n }\n } else {\n this.logger.warn(\n `skipping '${pluginHomeAlpha}' since it is not a directory`,\n );\n }\n }\n }\n\n return scannedPluginPackage;\n }\n\n async trackChanges(): Promise {\n const setupRootDirectoryWatcher = async (): Promise => {\n return new Promise((resolve, reject) => {\n if (!this._rootDirectory) {\n resolve();\n return;\n }\n const callSubscribers = debounce(() => {\n this.subscribers.forEach(s => s());\n }, 500);\n let ready = false;\n this.rootDirectoryWatcher = chokidar\n .watch(this._rootDirectory, {\n ignoreInitial: true,\n followSymlinks: true,\n depth: 1,\n disableGlobbing: true,\n })\n .on(\n 'all',\n (\n event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir',\n eventPath: string,\n _: Stats | undefined,\n ): void => {\n if (\n (['addDir', 'unlinkDir'].includes(event) &&\n path.dirname(eventPath) === this._rootDirectory) ||\n (['add', 'unlink', 'change'].includes(event) &&\n path.dirname(path.dirname(eventPath)) ===\n this._rootDirectory &&\n path.basename(eventPath) === 'package.json')\n ) {\n this.logger.info(\n `rootDirectory changed (${event} - ${eventPath}): scanning plugins again`,\n );\n callSubscribers();\n } else {\n this.logger.debug(\n `rootDirectory changed (${event} - ${eventPath}): no need to scan plugins again`,\n );\n }\n },\n )\n .on('error', (error: Error) => {\n this.logger.error(\n `error while watching '${this.rootDirectory}'`,\n error,\n );\n if (!ready) {\n reject(error);\n }\n })\n .on('ready', () => {\n ready = true;\n resolve();\n });\n });\n };\n\n await setupRootDirectoryWatcher();\n if (this.config.subscribe) {\n const { unsubscribe } = this.config.subscribe(async (): Promise => {\n const oldRootDirectory = this._rootDirectory;\n try {\n this.applyConfig();\n } catch (e) {\n this.logger.error(\n 'failed to apply new config for dynamic plugins',\n e,\n );\n }\n if (oldRootDirectory !== this._rootDirectory) {\n this.logger.info(\n `rootDirectory changed in Config from '${oldRootDirectory}' to '${this._rootDirectory}'`,\n );\n this.subscribers.forEach(s => s());\n if (this.rootDirectoryWatcher) {\n await this.rootDirectoryWatcher.close();\n }\n await setupRootDirectoryWatcher();\n }\n });\n this.configUnsubscribe = unsubscribe;\n }\n }\n\n async untrackChanges() {\n if (this.rootDirectoryWatcher) {\n this.rootDirectoryWatcher.close();\n }\n if (this.configUnsubscribe) {\n this.configUnsubscribe();\n }\n }\n\n destructor() {\n this.untrackChanges();\n }\n}\n"],"names":["path","lstatSync","fs","ForwardedError","url","existsSync","debounce","chokidar"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCO,MAAM,SAAY,GAAA;AAElB,MAAM,aAAc,CAAA;AAAA,EAMjB,WACW,CAAA,MAAA,EACA,MACA,EAAA,aAAA,EACA,WACjB,EAAA;AAJiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA;AAChB,EAVK,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,oBAAA;AAAA,EACA,cAA8B,EAAC;AAAA,EASvC,OAAO,OAAO,OAAqD,EAAA;AACjE,IAAA,MAAM,UAAU,IAAI,aAAA;AAAA,MAClB,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,aAAA;AAAA,MACR,QAAQ,WAAe,IAAA;AAAA,KACzB;AACA,IAAA,OAAA,CAAQ,WAAY,EAAA;AACpB,IAAO,OAAA,OAAA;AAAA;AACT,EAEA,+BAA+B,UAAwB,EAAA;AACrD,IAAK,IAAA,CAAA,WAAA,CAAY,KAAK,UAAU,CAAA;AAAA;AAClC,EAEA,IAAI,aAAoC,GAAA;AACtC,IAAA,OAAO,IAAK,CAAA,cAAA;AAAA;AACd,EAEQ,WAA4B,GAAA;AAClC,IAAA,MAAM,cAAiB,GAAA,IAAA,CAAK,MAAO,CAAA,WAAA,CAAY,SAAS,CAAA;AACxD,IAAA,IAAI,CAAC,cAAgB,EAAA;AACnB,MAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,CAAI,CAAA,EAAA,SAAS,CAA2B,yBAAA,CAAA,CAAA;AACzD,MAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA;AACtB,MAAA;AAAA;AAEF,IAAI,IAAA,OAAO,mBAAmB,QAAU,EAAA;AACtC,MAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,CAAI,CAAA,EAAA,SAAS,CAAqC,mCAAA,CAAA,CAAA;AACnE,MAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA;AACtB,MAAA;AAAA;AAEF,IAAI,IAAA,EAAE,mBAAmB,cAAiB,CAAA,EAAA;AACxC,MAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,QACV,IAAI,SAAS,CAAA,0DAAA;AAAA,OACf;AACA,MAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA;AACtB,MAAA;AAAA;AAEF,IAAI,IAAA,OAAO,cAAe,CAAA,aAAA,KAAkB,QAAU,EAAA;AACpD,MAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,QACV,IAAI,SAAS,CAAA,gDAAA;AAAA,OACf;AACA,MAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA;AACtB,MAAA;AAAA;AAGF,IAAA,MAAM,yBAAyBA,eAAK,CAAA,UAAA,CAAW,cAAe,CAAA,aAAa,IACvEA,eAAK,CAAA,OAAA,CAAQ,cAAe,CAAA,aAAa,IACzCA,eAAK,CAAA,OAAA,CAAQ,IAAK,CAAA,aAAA,EAAe,eAAe,aAAa,CAAA;AAEjE,IACE,IAAA,CAACA,eACE,CAAA,OAAA,CAAQ,sBAAsB,CAAA,CAC9B,UAAW,CAAAA,eAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,aAAa,CAAC,CAC9C,EAAA;AACA,MAAM,MAAA,QAAA,GAAW,QAAQ,GAAI,CAAA,SAAA;AAC7B,MAAA,MAAM,uBAAuBA,eAAK,CAAA,OAAA;AAAA,QAChC,IAAK,CAAA,aAAA;AAAA,QACL;AAAA,OACF;AACA,MACE,IAAA,CAAC,QACD,IAAA,CAAC,QAAS,CAAA,KAAA,CAAMA,gBAAK,SAAS,CAAA,CAAE,QAAS,CAAA,oBAAoB,CAC7D,EAAA;AACA,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,uBAAA,EAA0B,sBAAsB,CAAA,sCAAA,EAAyC,oBAAoB,CAAA;AAAA,YAAA,EAC5F,oBAAoB,CAAA,wDAAA;AAAA,SACvC;AAAA;AACF;AAEF,IAAA,IAAI,CAACC,YAAA,CAAU,sBAAsB,CAAA,CAAE,aAAe,EAAA;AACpD,MAAM,MAAA,IAAI,MAAM,iBAAiB,CAAA;AAAA;AAGnC,IAAA,IAAA,CAAK,cAAiB,GAAA,sBAAA;AAAA;AACxB,EAEA,MAAM,QAAsC,GAAA;AAC1C,IAAI,IAAA,CAAC,KAAK,cAAgB,EAAA;AACxB,MAAO,OAAA,EAAE,QAAU,EAAA,EAAG,EAAA;AAAA;AAGxB,IAAA,MAAM,yBAAyB,IAAK,CAAA,cAAA;AACpC,IAAA,MAAM,iBAAyC,EAAC;AAChD,IAAA,KAAA,MAAW,MAAU,IAAA,MAAMC,aAAG,CAAA,OAAA,CAAQ,sBAAwB,EAAA;AAAA,MAC5D,aAAe,EAAA;AAAA,KAChB,CAAG,EAAA;AACF,MAAA,MAAM,SAAY,GAAA,MAAA;AAElB,MAAI,IAAA,SAAA,CAAU,SAAS,YAAc,EAAA;AACnC,QAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,CAAa,UAAA,EAAA,SAAA,CAAU,IAAI,CAAoB,kBAAA,CAAA,CAAA;AACjE,QAAA;AAAA;AAEF,MAAA,MAAM,aAAaF,eAAK,CAAA,SAAA;AAAA,QACtBA,eAAK,CAAA,OAAA,CAAQ,sBAAwB,EAAA,SAAA,CAAU,IAAI;AAAA,OACrD;AACA,MAAI,IAAA,MAAA,CAAO,gBAAkB,EAAA;AAC3B,QAAI,IAAA,CAAA,CAAE,MAAME,aAAA,CAAG,KAAM,CAAA,MAAMA,aAAG,CAAA,QAAA,CAAS,UAAU,CAAC,CAAG,EAAA,WAAA,EAAe,EAAA;AAClE,UAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,YACV,aAAa,UAAU,CAAA,6BAAA;AAAA,WACzB;AACA,UAAA;AAAA;AACF,OACS,MAAA,IAAA,CAAC,MAAO,CAAA,WAAA,EAAe,EAAA;AAChC,QAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,UACV,aAAa,UAAU,CAAA,6BAAA;AAAA,SACzB;AACA,QAAA;AAAA;AAGF,MAAI,IAAA,aAAA;AACJ,MAAI,IAAA;AACF,QAAgB,aAAA,GAAA,MAAM,IAAK,CAAA,OAAA,CAAQ,UAAU,CAAA;AAC7C,QAAI,IAAA,CAAC,aAAc,CAAA,QAAA,CAAS,IAAM,EAAA;AAChC,UAAM,MAAA,IAAI,MAAM,0CAA0C,CAAA;AAAA;AAE5D,QAAA,IAAI,CAAC,aAAA,CAAc,QAAS,CAAA,SAAA,EAAW,IAAM,EAAA;AAC3C,UAAM,MAAA,IAAI,MAAM,oDAAoD,CAAA;AAAA;AACtE,eACO,CAAG,EAAA;AACV,QAAA,IAAI,aAAaC,qBAAgB,EAAA;AAC/B,UAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,CAAE,CAAA,OAAA,EAAS,EAAE,KAAK,CAAA;AAAA,SAC/B,MAAA;AACL,UAAA,IAAA,CAAK,MAAO,CAAA,KAAA;AAAA,YACV,gDAAgD,UAAU,CAAA,CAAA,CAAA;AAAA,YAC1D;AAAA,WACF;AAAA;AAEF,QAAA;AAAA;AAEF,MAAA,cAAA,CAAe,KAAK,aAAa,CAAA;AAAA;AAEnC,IAAO,OAAA,EAAE,UAAU,cAAe,EAAA;AAAA;AACpC,EAEA,MAAc,QAAQ,UAAmD,EAAA;AACvE,IAAA,MAAM,YAAe,GAAAH,eAAA,CAAK,OAAQ,CAAA,UAAA,EAAY,cAAc,CAAA;AAC5D,IAAA,MAAM,OAAU,GAAA,MAAME,aAAG,CAAA,QAAA,CAAS,YAAY,CAAA;AAC9C,IAAA,MAAM,QAAkC,GAAA,IAAA,CAAK,KAAM,CAAA,OAAA,CAAQ,UAAU,CAAA;AACrE,IAAA,MAAM,oBAA6C,GAAA;AAAA,MACjD,QAAA,EAAUE,cAAI,CAAA,aAAA,CAAc,UAAU,CAAA;AAAA,MACtC;AAAA,KACF;AAEA,IAAA,IAAI,KAAK,WAAa,EAAA;AACpB,MAAA,MAAM,eAAkB,GAAAJ,eAAA,CAAK,OAAQ,CAAA,UAAA,EAAY,OAAO,CAAA;AACxD,MAAI,IAAAK,aAAA,CAAW,eAAe,CAAG,EAAA;AAC/B,QAAA,IAAA,CAAK,MAAMH,aAAG,CAAA,KAAA,CAAM,eAAe,CAAA,EAAG,aAAe,EAAA;AACnD,UAAI,IAAA;AACF,YAAM,MAAA,YAAA,GAAe,MAAMA,aAAG,CAAA,QAAA;AAAA,cAC5BF,eAAA,CAAK,OAAQ,CAAA,eAAA,EAAiB,cAAc;AAAA,aAC9C;AACA,YAAA,oBAAA,CAAqB,gBAAgB,IAAK,CAAA,KAAA;AAAA,cACxC,aAAa,QAAS;AAAA,aACxB;AAAA,mBACO,CAAG,EAAA;AACV,YAAA,MAAM,IAAIG,qBAAA;AAAA,cACR,gDAAgD,UAAU,CAAA,OAAA,CAAA;AAAA,cAC1D;AAAA,aACF;AAAA;AACF,SACK,MAAA;AACL,UAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,YACV,aAAa,eAAe,CAAA,6BAAA;AAAA,WAC9B;AAAA;AACF;AACF;AAGF,IAAO,OAAA,oBAAA;AAAA;AACT,EAEA,MAAM,YAA8B,GAAA;AAClC,IAAA,MAAM,4BAA4B,YAA2B;AAC3D,MAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,QAAI,IAAA,CAAC,KAAK,cAAgB,EAAA;AACxB,UAAQ,OAAA,EAAA;AACR,UAAA;AAAA;AAEF,QAAM,MAAA,eAAA,GAAkBG,0BAAS,MAAM;AACrC,UAAA,IAAA,CAAK,WAAY,CAAA,OAAA,CAAQ,CAAK,CAAA,KAAA,CAAA,EAAG,CAAA;AAAA,WAChC,GAAG,CAAA;AACN,QAAA,IAAI,KAAQ,GAAA,KAAA;AACZ,QAAA,IAAA,CAAK,oBAAuB,GAAAC,mBAAA,CACzB,KAAM,CAAA,IAAA,CAAK,cAAgB,EAAA;AAAA,UAC1B,aAAe,EAAA,IAAA;AAAA,UACf,cAAgB,EAAA,IAAA;AAAA,UAChB,KAAO,EAAA,CAAA;AAAA,UACP,eAAiB,EAAA;AAAA,SAClB,CACA,CAAA,EAAA;AAAA,UACC,KAAA;AAAA,UACA,CACE,KACA,EAAA,SAAA,EACA,CACS,KAAA;AACT,YAAA,IACG,CAAC,QAAA,EAAU,WAAW,CAAA,CAAE,SAAS,KAAK,CAAA,IACrCP,eAAK,CAAA,OAAA,CAAQ,SAAS,CAAM,KAAA,IAAA,CAAK,cAClC,IAAA,CAAC,OAAO,QAAU,EAAA,QAAQ,CAAE,CAAA,QAAA,CAAS,KAAK,CAAA,IACzCA,eAAK,CAAA,OAAA,CAAQA,gBAAK,OAAQ,CAAA,SAAS,CAAC,CAAA,KAClC,KAAK,cACP,IAAAA,eAAA,CAAK,QAAS,CAAA,SAAS,MAAM,cAC/B,EAAA;AACA,cAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,gBACV,CAAA,uBAAA,EAA0B,KAAK,CAAA,GAAA,EAAM,SAAS,CAAA,yBAAA;AAAA,eAChD;AACA,cAAgB,eAAA,EAAA;AAAA,aACX,MAAA;AACL,cAAA,IAAA,CAAK,MAAO,CAAA,KAAA;AAAA,gBACV,CAAA,uBAAA,EAA0B,KAAK,CAAA,GAAA,EAAM,SAAS,CAAA,gCAAA;AAAA,eAChD;AAAA;AACF;AACF,SAED,CAAA,EAAA,CAAG,OAAS,EAAA,CAAC,KAAiB,KAAA;AAC7B,UAAA,IAAA,CAAK,MAAO,CAAA,KAAA;AAAA,YACV,CAAA,sBAAA,EAAyB,KAAK,aAAa,CAAA,CAAA,CAAA;AAAA,YAC3C;AAAA,WACF;AACA,UAAA,IAAI,CAAC,KAAO,EAAA;AACV,YAAA,MAAA,CAAO,KAAK,CAAA;AAAA;AACd,SACD,CAAA,CACA,EAAG,CAAA,OAAA,EAAS,MAAM;AACjB,UAAQ,KAAA,GAAA,IAAA;AACR,UAAQ,OAAA,EAAA;AAAA,SACT,CAAA;AAAA,OACJ,CAAA;AAAA,KACH;AAEA,IAAA,MAAM,yBAA0B,EAAA;AAChC,IAAI,IAAA,IAAA,CAAK,OAAO,SAAW,EAAA;AACzB,MAAA,MAAM,EAAE,WAAY,EAAA,GAAI,IAAK,CAAA,MAAA,CAAO,UAAU,YAA2B;AACvE,QAAA,MAAM,mBAAmB,IAAK,CAAA,cAAA;AAC9B,QAAI,IAAA;AACF,UAAA,IAAA,CAAK,WAAY,EAAA;AAAA,iBACV,CAAG,EAAA;AACV,UAAA,IAAA,CAAK,MAAO,CAAA,KAAA;AAAA,YACV,gDAAA;AAAA,YACA;AAAA,WACF;AAAA;AAEF,QAAI,IAAA,gBAAA,KAAqB,KAAK,cAAgB,EAAA;AAC5C,UAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,YACV,CAAyC,sCAAA,EAAA,gBAAgB,CAAS,MAAA,EAAA,IAAA,CAAK,cAAc,CAAA,CAAA;AAAA,WACvF;AACA,UAAA,IAAA,CAAK,WAAY,CAAA,OAAA,CAAQ,CAAK,CAAA,KAAA,CAAA,EAAG,CAAA;AACjC,UAAA,IAAI,KAAK,oBAAsB,EAAA;AAC7B,YAAM,MAAA,IAAA,CAAK,qBAAqB,KAAM,EAAA;AAAA;AAExC,UAAA,MAAM,yBAA0B,EAAA;AAAA;AAClC,OACD,CAAA;AACD,MAAA,IAAA,CAAK,iBAAoB,GAAA,WAAA;AAAA;AAC3B;AACF,EAEA,MAAM,cAAiB,GAAA;AACrB,IAAA,IAAI,KAAK,oBAAsB,EAAA;AAC7B,MAAA,IAAA,CAAK,qBAAqB,KAAM,EAAA;AAAA;AAElC,IAAA,IAAI,KAAK,iBAAmB,EAAA;AAC1B,MAAA,IAAA,CAAK,iBAAkB,EAAA;AAAA;AACzB;AACF,EAEA,UAAa,GAAA;AACX,IAAA,IAAA,CAAK,cAAe,EAAA;AAAA;AAExB;;;;;"} -\ No newline at end of file -+{"version":3,"file":"plugin-scanner.cjs.js","sources":["../../src/scanner/plugin-scanner.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Config } from '@backstage/config';\nimport { ScannedPluginPackage, ScannedPluginManifest } from './types';\nimport * as fs from 'fs/promises';\nimport { Stats, lstatSync, existsSync } from 'fs';\nimport * as chokidar from 'chokidar';\nimport * as path from 'path';\nimport * as url from 'url';\nimport debounce from 'lodash/debounce';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { ForwardedError } from '@backstage/errors';\n\nexport interface DynamicPluginScannerOptions {\n config: Config;\n backstageRoot: string;\n logger: LoggerService;\n preferAlpha?: boolean;\n}\n\nexport interface ScanRootResponse {\n packages: ScannedPluginPackage[];\n}\n\nexport const configKey = 'dynamicPlugins';\n\nexport class PluginScanner {\n private _rootDirectory?: string;\n private configUnsubscribe?: () => void;\n private rootDirectoryWatcher?: chokidar.FSWatcher;\n private subscribers: (() => void)[] = [];\n\n private constructor(\n private readonly config: Config,\n private readonly logger: LoggerService,\n private readonly backstageRoot: string,\n private readonly preferAlpha: boolean,\n ) {}\n\n static create(options: DynamicPluginScannerOptions): PluginScanner {\n const scanner = new PluginScanner(\n options.config,\n options.logger,\n options.backstageRoot,\n options.preferAlpha || false,\n );\n scanner.applyConfig();\n return scanner;\n }\n\n subscribeToRootDirectoryChange(subscriber: () => void) {\n this.subscribers.push(subscriber);\n }\n\n get rootDirectory(): string | undefined {\n return this._rootDirectory;\n }\n\n private applyConfig(): void | never {\n const dynamicPlugins = this.config.getOptional(configKey);\n if (!dynamicPlugins) {\n this.logger.info(`'${configKey}' config entry not found.`);\n this._rootDirectory = undefined;\n return;\n }\n if (typeof dynamicPlugins !== 'object') {\n this.logger.warn(`'${configKey}' config entry should be an object.`);\n this._rootDirectory = undefined;\n return;\n }\n if (!('rootDirectory' in dynamicPlugins)) {\n this.logger.warn(\n `'${configKey}' config entry does not contain the 'rootDirectory' field.`,\n );\n this._rootDirectory = undefined;\n return;\n }\n if (typeof dynamicPlugins.rootDirectory !== 'string') {\n this.logger.warn(\n `'${configKey}.rootDirectory' config entry should be a string.`,\n );\n this._rootDirectory = undefined;\n return;\n }\n\n const dynamicPluginsRootPath = path.isAbsolute(dynamicPlugins.rootDirectory)\n ? path.resolve(dynamicPlugins.rootDirectory)\n : path.resolve(this.backstageRoot, dynamicPlugins.rootDirectory);\n\n if (\n !path\n .dirname(dynamicPluginsRootPath)\n .startsWith(path.resolve(this.backstageRoot))\n ) {\n const nodePath = process.env.NODE_PATH;\n const backstageNodeModules = path.resolve(\n this.backstageRoot,\n 'node_modules',\n );\n if (\n !nodePath ||\n !nodePath.split(path.delimiter).includes(backstageNodeModules)\n ) {\n throw new Error(\n `Dynamic plugins under '${dynamicPluginsRootPath}' cannot access backstage modules in '${backstageNodeModules}'.\\n` +\n `Please add '${backstageNodeModules}' to the 'NODE_PATH' when running the backstage backend.`,\n );\n }\n }\n if (!lstatSync(dynamicPluginsRootPath).isDirectory()) {\n throw new Error('Not a directory');\n }\n\n this._rootDirectory = dynamicPluginsRootPath;\n }\n\n async scanRoot(): Promise {\n if (!this._rootDirectory) {\n return { packages: [] };\n }\n\n const dynamicPluginsLocation = this._rootDirectory;\n const scannedPlugins: ScannedPluginPackage[] = [];\n for (const dirEnt of await fs.readdir(dynamicPluginsLocation, {\n withFileTypes: true,\n })) {\n const pluginDir = dirEnt;\n\n if (pluginDir.name === 'lost+found') {\n this.logger.debug(`skipping '${pluginDir.name}' system directory`);\n continue;\n }\n const pluginHome = path.normalize(\n path.resolve(dynamicPluginsLocation, pluginDir.name),\n );\n if (dirEnt.isSymbolicLink()) {\n if (!(await fs.lstat(await fs.readlink(pluginHome))).isDirectory()) {\n this.logger.info(\n `skipping '${pluginHome}' since it is not a directory`,\n );\n continue;\n }\n } else if (!dirEnt.isDirectory()) {\n this.logger.info(\n `skipping '${pluginHome}' since it is not a directory`,\n );\n continue;\n }\n\n let scannedPlugin: ScannedPluginPackage;\n try {\n scannedPlugin = await this.scanDir(pluginHome);\n if (!scannedPlugin.manifest.main) {\n throw new Error(\"field 'main' not found in 'package.json'\");\n }\n if (!scannedPlugin.manifest.backstage?.role) {\n throw new Error(\"field 'backstage.role' not found in 'package.json'\");\n }\n } catch (e) {\n if (e instanceof ForwardedError) {\n this.logger.error(e.message, e.cause);\n } else {\n this.logger.error(\n `failed to load dynamic plugin manifest from '${pluginHome}'`,\n e,\n );\n }\n continue;\n }\n scannedPlugins.push(scannedPlugin);\n }\n return { packages: scannedPlugins };\n }\n\n private async scanDir(pluginHome: string): Promise {\n const manifestFile = path.resolve(pluginHome, 'package.json');\n const content = await fs.readFile(manifestFile);\n const manifest: ScannedPluginManifest = JSON.parse(content.toString());\n const scannedPluginPackage: ScannedPluginPackage = {\n location: url.pathToFileURL(pluginHome),\n manifest: manifest,\n };\n\n if (this.preferAlpha) {\n const pluginHomeAlpha = path.resolve(pluginHome, 'alpha');\n if (existsSync(pluginHomeAlpha)) {\n if ((await fs.lstat(pluginHomeAlpha)).isDirectory()) {\n try {\n const alphaContent = await fs.readFile(\n path.resolve(pluginHomeAlpha, 'package.json'),\n );\n scannedPluginPackage.alphaManifest = JSON.parse(\n alphaContent.toString(),\n );\n } catch (e) {\n throw new ForwardedError(\n `failed to load dynamic plugin manifest from '${pluginHome}/alpha'`,\n e,\n );\n }\n } else {\n this.logger.warn(\n `skipping '${pluginHomeAlpha}' since it is not a directory`,\n );\n }\n }\n }\n\n return scannedPluginPackage;\n }\n\n async trackChanges(): Promise {\n const setupRootDirectoryWatcher = async (): Promise => {\n return new Promise((resolve, reject) => {\n if (!this._rootDirectory) {\n resolve();\n return;\n }\n const callSubscribers = debounce(() => {\n this.subscribers.forEach(s => s());\n }, 500);\n let ready = false;\n this.rootDirectoryWatcher = chokidar\n .watch(this._rootDirectory, {\n ignoreInitial: true,\n followSymlinks: false,\n depth: 1,\n disableGlobbing: true,\n })\n .on(\n 'all',\n (\n event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir',\n eventPath: string,\n _: Stats | undefined,\n ): void => {\n if (\n (['addDir', 'unlinkDir'].includes(event) &&\n path.dirname(eventPath) === this._rootDirectory) ||\n (['add', 'unlink', 'change'].includes(event) &&\n path.dirname(path.dirname(eventPath)) ===\n this._rootDirectory &&\n path.basename(eventPath) === 'package.json')\n ) {\n this.logger.info(\n `rootDirectory changed (${event} - ${eventPath}): scanning plugins again`,\n );\n callSubscribers();\n } else {\n this.logger.debug(\n `rootDirectory changed (${event} - ${eventPath}): no need to scan plugins again`,\n );\n }\n },\n )\n .on('error', (error: Error) => {\n this.logger.error(\n `error while watching '${this.rootDirectory}'`,\n error,\n );\n if (!ready) {\n reject(error);\n }\n })\n .on('ready', () => {\n ready = true;\n resolve();\n });\n });\n };\n\n await setupRootDirectoryWatcher();\n if (this.config.subscribe) {\n const { unsubscribe } = this.config.subscribe(async (): Promise => {\n const oldRootDirectory = this._rootDirectory;\n try {\n this.applyConfig();\n } catch (e) {\n this.logger.error(\n 'failed to apply new config for dynamic plugins',\n e,\n );\n }\n if (oldRootDirectory !== this._rootDirectory) {\n this.logger.info(\n `rootDirectory changed in Config from '${oldRootDirectory}' to '${this._rootDirectory}'`,\n );\n this.subscribers.forEach(s => s());\n if (this.rootDirectoryWatcher) {\n await this.rootDirectoryWatcher.close();\n }\n await setupRootDirectoryWatcher();\n }\n });\n this.configUnsubscribe = unsubscribe;\n }\n }\n\n async untrackChanges() {\n if (this.rootDirectoryWatcher) {\n this.rootDirectoryWatcher.close();\n }\n if (this.configUnsubscribe) {\n this.configUnsubscribe();\n }\n }\n\n destructor() {\n this.untrackChanges();\n }\n}\n"],"names":["path","lstatSync","fs","ForwardedError","url","existsSync","debounce","chokidar"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCO,MAAM,SAAY,GAAA;AAElB,MAAM,aAAc,CAAA;AAAA,EAMjB,WACW,CAAA,MAAA,EACA,MACA,EAAA,aAAA,EACA,WACjB,EAAA;AAJiB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA;AACA,IAAA,IAAA,CAAA,WAAA,GAAA,WAAA;AAAA;AAChB,EAVK,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,oBAAA;AAAA,EACA,cAA8B,EAAC;AAAA,EASvC,OAAO,OAAO,OAAqD,EAAA;AACjE,IAAA,MAAM,UAAU,IAAI,aAAA;AAAA,MAClB,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,aAAA;AAAA,MACR,QAAQ,WAAe,IAAA;AAAA,KACzB;AACA,IAAA,OAAA,CAAQ,WAAY,EAAA;AACpB,IAAO,OAAA,OAAA;AAAA;AACT,EAEA,+BAA+B,UAAwB,EAAA;AACrD,IAAK,IAAA,CAAA,WAAA,CAAY,KAAK,UAAU,CAAA;AAAA;AAClC,EAEA,IAAI,aAAoC,GAAA;AACtC,IAAA,OAAO,IAAK,CAAA,cAAA;AAAA;AACd,EAEQ,WAA4B,GAAA;AAClC,IAAA,MAAM,cAAiB,GAAA,IAAA,CAAK,MAAO,CAAA,WAAA,CAAY,SAAS,CAAA;AACxD,IAAA,IAAI,CAAC,cAAgB,EAAA;AACnB,MAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,CAAI,CAAA,EAAA,SAAS,CAA2B,yBAAA,CAAA,CAAA;AACzD,MAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA;AACtB,MAAA;AAAA;AAEF,IAAI,IAAA,OAAO,mBAAmB,QAAU,EAAA;AACtC,MAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,CAAI,CAAA,EAAA,SAAS,CAAqC,mCAAA,CAAA,CAAA;AACnE,MAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA;AACtB,MAAA;AAAA;AAEF,IAAI,IAAA,EAAE,mBAAmB,cAAiB,CAAA,EAAA;AACxC,MAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,QACV,IAAI,SAAS,CAAA,0DAAA;AAAA,OACf;AACA,MAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA;AACtB,MAAA;AAAA;AAEF,IAAI,IAAA,OAAO,cAAe,CAAA,aAAA,KAAkB,QAAU,EAAA;AACpD,MAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,QACV,IAAI,SAAS,CAAA,gDAAA;AAAA,OACf;AACA,MAAA,IAAA,CAAK,cAAiB,GAAA,KAAA,CAAA;AACtB,MAAA;AAAA;AAGF,IAAA,MAAM,yBAAyBA,eAAK,CAAA,UAAA,CAAW,cAAe,CAAA,aAAa,IACvEA,eAAK,CAAA,OAAA,CAAQ,cAAe,CAAA,aAAa,IACzCA,eAAK,CAAA,OAAA,CAAQ,IAAK,CAAA,aAAA,EAAe,eAAe,aAAa,CAAA;AAEjE,IACE,IAAA,CAACA,eACE,CAAA,OAAA,CAAQ,sBAAsB,CAAA,CAC9B,UAAW,CAAAA,eAAA,CAAK,OAAQ,CAAA,IAAA,CAAK,aAAa,CAAC,CAC9C,EAAA;AACA,MAAM,MAAA,QAAA,GAAW,QAAQ,GAAI,CAAA,SAAA;AAC7B,MAAA,MAAM,uBAAuBA,eAAK,CAAA,OAAA;AAAA,QAChC,IAAK,CAAA,aAAA;AAAA,QACL;AAAA,OACF;AACA,MACE,IAAA,CAAC,QACD,IAAA,CAAC,QAAS,CAAA,KAAA,CAAMA,gBAAK,SAAS,CAAA,CAAE,QAAS,CAAA,oBAAoB,CAC7D,EAAA;AACA,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,uBAAA,EAA0B,sBAAsB,CAAA,sCAAA,EAAyC,oBAAoB,CAAA;AAAA,YAAA,EAC5F,oBAAoB,CAAA,wDAAA;AAAA,SACvC;AAAA;AACF;AAEF,IAAA,IAAI,CAACC,YAAA,CAAU,sBAAsB,CAAA,CAAE,aAAe,EAAA;AACpD,MAAM,MAAA,IAAI,MAAM,iBAAiB,CAAA;AAAA;AAGnC,IAAA,IAAA,CAAK,cAAiB,GAAA,sBAAA;AAAA;AACxB,EAEA,MAAM,QAAsC,GAAA;AAC1C,IAAI,IAAA,CAAC,KAAK,cAAgB,EAAA;AACxB,MAAO,OAAA,EAAE,QAAU,EAAA,EAAG,EAAA;AAAA;AAGxB,IAAA,MAAM,yBAAyB,IAAK,CAAA,cAAA;AACpC,IAAA,MAAM,iBAAyC,EAAC;AAChD,IAAA,KAAA,MAAW,MAAU,IAAA,MAAMC,aAAG,CAAA,OAAA,CAAQ,sBAAwB,EAAA;AAAA,MAC5D,aAAe,EAAA;AAAA,KAChB,CAAG,EAAA;AACF,MAAA,MAAM,SAAY,GAAA,MAAA;AAElB,MAAI,IAAA,SAAA,CAAU,SAAS,YAAc,EAAA;AACnC,QAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,CAAa,UAAA,EAAA,SAAA,CAAU,IAAI,CAAoB,kBAAA,CAAA,CAAA;AACjE,QAAA;AAAA;AAEF,MAAA,MAAM,aAAaF,eAAK,CAAA,SAAA;AAAA,QACtBA,eAAK,CAAA,OAAA,CAAQ,sBAAwB,EAAA,SAAA,CAAU,IAAI;AAAA,OACrD;AACA,MAAI,IAAA,MAAA,CAAO,gBAAkB,EAAA;AAC3B,QAAI,IAAA,CAAA,CAAE,MAAME,aAAA,CAAG,KAAM,CAAA,MAAMA,aAAG,CAAA,QAAA,CAAS,UAAU,CAAC,CAAG,EAAA,WAAA,EAAe,EAAA;AAClE,UAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,YACV,aAAa,UAAU,CAAA,6BAAA;AAAA,WACzB;AACA,UAAA;AAAA;AACF,OACS,MAAA,IAAA,CAAC,MAAO,CAAA,WAAA,EAAe,EAAA;AAChC,QAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,UACV,aAAa,UAAU,CAAA,6BAAA;AAAA,SACzB;AACA,QAAA;AAAA;AAGF,MAAI,IAAA,aAAA;AACJ,MAAI,IAAA;AACF,QAAgB,aAAA,GAAA,MAAM,IAAK,CAAA,OAAA,CAAQ,UAAU,CAAA;AAC7C,QAAI,IAAA,CAAC,aAAc,CAAA,QAAA,CAAS,IAAM,EAAA;AAChC,UAAM,MAAA,IAAI,MAAM,0CAA0C,CAAA;AAAA;AAE5D,QAAA,IAAI,CAAC,aAAA,CAAc,QAAS,CAAA,SAAA,EAAW,IAAM,EAAA;AAC3C,UAAM,MAAA,IAAI,MAAM,oDAAoD,CAAA;AAAA;AACtE,eACO,CAAG,EAAA;AACV,QAAA,IAAI,aAAaC,qBAAgB,EAAA;AAC/B,UAAA,IAAA,CAAK,MAAO,CAAA,KAAA,CAAM,CAAE,CAAA,OAAA,EAAS,EAAE,KAAK,CAAA;AAAA,SAC/B,MAAA;AACL,UAAA,IAAA,CAAK,MAAO,CAAA,KAAA;AAAA,YACV,gDAAgD,UAAU,CAAA,CAAA,CAAA;AAAA,YAC1D;AAAA,WACF;AAAA;AAEF,QAAA;AAAA;AAEF,MAAA,cAAA,CAAe,KAAK,aAAa,CAAA;AAAA;AAEnC,IAAO,OAAA,EAAE,UAAU,cAAe,EAAA;AAAA;AACpC,EAEA,MAAc,QAAQ,UAAmD,EAAA;AACvE,IAAA,MAAM,YAAe,GAAAH,eAAA,CAAK,OAAQ,CAAA,UAAA,EAAY,cAAc,CAAA;AAC5D,IAAA,MAAM,OAAU,GAAA,MAAME,aAAG,CAAA,QAAA,CAAS,YAAY,CAAA;AAC9C,IAAA,MAAM,QAAkC,GAAA,IAAA,CAAK,KAAM,CAAA,OAAA,CAAQ,UAAU,CAAA;AACrE,IAAA,MAAM,oBAA6C,GAAA;AAAA,MACjD,QAAA,EAAUE,cAAI,CAAA,aAAA,CAAc,UAAU,CAAA;AAAA,MACtC;AAAA,KACF;AAEA,IAAA,IAAI,KAAK,WAAa,EAAA;AACpB,MAAA,MAAM,eAAkB,GAAAJ,eAAA,CAAK,OAAQ,CAAA,UAAA,EAAY,OAAO,CAAA;AACxD,MAAI,IAAAK,aAAA,CAAW,eAAe,CAAG,EAAA;AAC/B,QAAA,IAAA,CAAK,MAAMH,aAAG,CAAA,KAAA,CAAM,eAAe,CAAA,EAAG,aAAe,EAAA;AACnD,UAAI,IAAA;AACF,YAAM,MAAA,YAAA,GAAe,MAAMA,aAAG,CAAA,QAAA;AAAA,cAC5BF,eAAA,CAAK,OAAQ,CAAA,eAAA,EAAiB,cAAc;AAAA,aAC9C;AACA,YAAA,oBAAA,CAAqB,gBAAgB,IAAK,CAAA,KAAA;AAAA,cACxC,aAAa,QAAS;AAAA,aACxB;AAAA,mBACO,CAAG,EAAA;AACV,YAAA,MAAM,IAAIG,qBAAA;AAAA,cACR,gDAAgD,UAAU,CAAA,OAAA,CAAA;AAAA,cAC1D;AAAA,aACF;AAAA;AACF,SACK,MAAA;AACL,UAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,YACV,aAAa,eAAe,CAAA,6BAAA;AAAA,WAC9B;AAAA;AACF;AACF;AAGF,IAAO,OAAA,oBAAA;AAAA;AACT,EAEA,MAAM,YAA8B,GAAA;AAClC,IAAA,MAAM,4BAA4B,YAA2B;AAC3D,MAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,QAAI,IAAA,CAAC,KAAK,cAAgB,EAAA;AACxB,UAAQ,OAAA,EAAA;AACR,UAAA;AAAA;AAEF,QAAM,MAAA,eAAA,GAAkBG,0BAAS,MAAM;AACrC,UAAA,IAAA,CAAK,WAAY,CAAA,OAAA,CAAQ,CAAK,CAAA,KAAA,CAAA,EAAG,CAAA;AAAA,WAChC,GAAG,CAAA;AACN,QAAA,IAAI,KAAQ,GAAA,KAAA;AACZ,QAAA,IAAA,CAAK,oBAAuB,GAAAC,mBAAA,CACzB,KAAM,CAAA,IAAA,CAAK,cAAgB,EAAA;AAAA,UAC1B,aAAe,EAAA,IAAA;AAAA,UACf,cAAgB,EAAA,KAAA;AAAA,UAChB,KAAO,EAAA,CAAA;AAAA,UACP,eAAiB,EAAA;AAAA,SAClB,CACA,CAAA,EAAA;AAAA,UACC,KAAA;AAAA,UACA,CACE,KACA,EAAA,SAAA,EACA,CACS,KAAA;AACT,YAAA,IACG,CAAC,QAAA,EAAU,WAAW,CAAA,CAAE,SAAS,KAAK,CAAA,IACrCP,eAAK,CAAA,OAAA,CAAQ,SAAS,CAAM,KAAA,IAAA,CAAK,cAClC,IAAA,CAAC,OAAO,QAAU,EAAA,QAAQ,CAAE,CAAA,QAAA,CAAS,KAAK,CAAA,IACzCA,eAAK,CAAA,OAAA,CAAQA,gBAAK,OAAQ,CAAA,SAAS,CAAC,CAAA,KAClC,KAAK,cACP,IAAAA,eAAA,CAAK,QAAS,CAAA,SAAS,MAAM,cAC/B,EAAA;AACA,cAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,gBACV,CAAA,uBAAA,EAA0B,KAAK,CAAA,GAAA,EAAM,SAAS,CAAA,yBAAA;AAAA,eAChD;AACA,cAAgB,eAAA,EAAA;AAAA,aACX,MAAA;AACL,cAAA,IAAA,CAAK,MAAO,CAAA,KAAA;AAAA,gBACV,CAAA,uBAAA,EAA0B,KAAK,CAAA,GAAA,EAAM,SAAS,CAAA,gCAAA;AAAA,eAChD;AAAA;AACF;AACF,SAED,CAAA,EAAA,CAAG,OAAS,EAAA,CAAC,KAAiB,KAAA;AAC7B,UAAA,IAAA,CAAK,MAAO,CAAA,KAAA;AAAA,YACV,CAAA,sBAAA,EAAyB,KAAK,aAAa,CAAA,CAAA,CAAA;AAAA,YAC3C;AAAA,WACF;AACA,UAAA,IAAI,CAAC,KAAO,EAAA;AACV,YAAA,MAAA,CAAO,KAAK,CAAA;AAAA;AACd,SACD,CAAA,CACA,EAAG,CAAA,OAAA,EAAS,MAAM;AACjB,UAAQ,KAAA,GAAA,IAAA;AACR,UAAQ,OAAA,EAAA;AAAA,SACT,CAAA;AAAA,OACJ,CAAA;AAAA,KACH;AAEA,IAAA,MAAM,yBAA0B,EAAA;AAChC,IAAI,IAAA,IAAA,CAAK,OAAO,SAAW,EAAA;AACzB,MAAA,MAAM,EAAE,WAAY,EAAA,GAAI,IAAK,CAAA,MAAA,CAAO,UAAU,YAA2B;AACvE,QAAA,MAAM,mBAAmB,IAAK,CAAA,cAAA;AAC9B,QAAI,IAAA;AACF,UAAA,IAAA,CAAK,WAAY,EAAA;AAAA,iBACV,CAAG,EAAA;AACV,UAAA,IAAA,CAAK,MAAO,CAAA,KAAA;AAAA,YACV,gDAAA;AAAA,YACA;AAAA,WACF;AAAA;AAEF,QAAI,IAAA,gBAAA,KAAqB,KAAK,cAAgB,EAAA;AAC5C,UAAA,IAAA,CAAK,MAAO,CAAA,IAAA;AAAA,YACV,CAAyC,sCAAA,EAAA,gBAAgB,CAAS,MAAA,EAAA,IAAA,CAAK,cAAc,CAAA,CAAA;AAAA,WACvF;AACA,UAAA,IAAA,CAAK,WAAY,CAAA,OAAA,CAAQ,CAAK,CAAA,KAAA,CAAA,EAAG,CAAA;AACjC,UAAA,IAAI,KAAK,oBAAsB,EAAA;AAC7B,YAAM,MAAA,IAAA,CAAK,qBAAqB,KAAM,EAAA;AAAA;AAExC,UAAA,MAAM,yBAA0B,EAAA;AAAA;AAClC,OACD,CAAA;AACD,MAAA,IAAA,CAAK,iBAAoB,GAAA,WAAA;AAAA;AAC3B;AACF,EAEA,MAAM,cAAiB,GAAA;AACrB,IAAA,IAAI,KAAK,oBAAsB,EAAA;AAC7B,MAAA,IAAA,CAAK,qBAAqB,KAAM,EAAA;AAAA;AAElC,IAAA,IAAI,KAAK,iBAAmB,EAAA;AAC1B,MAAA,IAAA,CAAK,iBAAkB,EAAA;AAAA;AACzB;AACF,EAEA,UAAa,GAAA;AACX,IAAA,IAAA,CAAK,cAAe,EAAA;AAAA;AAExB;;;;;"} -\ No newline at end of file -diff --git a/dist/server/frontendRemotesServer.cjs.js b/dist/server/frontendRemotesServer.cjs.js -index b047f96aa23b39b6ebd723b1eddfad59ff619c10..4a6ad865b8adcca717c2d3663dbc967fb25f0dd9 100644 ---- a/dist/server/frontendRemotesServer.cjs.js -+++ b/dist/server/frontendRemotesServer.cjs.js -@@ -2,7 +2,7 @@ - - var backendPluginApi = require('@backstage/backend-plugin-api'); - var router$1 = require('./router.cjs.js'); --var backendDynamicFeatureService = require('@backstage/backend-dynamic-feature-service'); -+var pluginManager = require('../manager/plugin-manager.cjs.js'); - var router = require('../schema/openapi/generated/router.cjs.js'); - var sdk = require('@module-federation/sdk'); - -@@ -16,7 +16,7 @@ const frontendRemotesServerService = backendPluginApi.createServiceFactory({ - logger: backendPluginApi.coreServices.rootLogger, - rootHttpRouter: backendPluginApi.coreServices.rootHttpRouter, - config: backendPluginApi.coreServices.rootConfig, -- dynamicPlugins: backendDynamicFeatureService.dynamicPluginsServiceRef, -+ dynamicPlugins: pluginManager.dynamicPluginsServiceRef, - lifecycle: backendPluginApi.coreServices.rootLifecycle - }, - async factory({ logger, rootHttpRouter, config, dynamicPlugins, lifecycle }) { -diff --git a/dist/server/frontendRemotesServer.cjs.js.map b/dist/server/frontendRemotesServer.cjs.js.map -index f8dafdd416443310860499f70ec758c63af70ade..1e8b9e99cf3d7d684030638c8acb005f15f2ddc8 100644 ---- a/dist/server/frontendRemotesServer.cjs.js.map -+++ b/dist/server/frontendRemotesServer.cjs.js.map -@@ -1 +1 @@ --{"version":3,"file":"frontendRemotesServer.cjs.js","sources":["../../src/server/frontendRemotesServer.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n coreServices,\n createServiceFactory,\n createServiceRef,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './router';\nimport { dynamicPluginsServiceRef } from '@backstage/backend-dynamic-feature-service';\nimport { spec } from '../schema/openapi';\nimport { ManifestFileName } from '@module-federation/sdk';\nimport { RemoteInfo } from '../schema/openapi/generated/models';\nimport { JsonObject } from '@backstage/types';\n\n/**\n *\n * @public\n * */\nexport type AdditionalRemoteInfo = Omit;\n\n/**\n *\n * @public\n * */\nexport type FrontendRemoteResolver = {\n /**\n * Relative path to the module federation assets folder from the root folder of the plugin package.\n * Default value is `dist`.\n */\n assetsPathFromPackage?: string;\n\n /**\n * File name of the module federation manifest inside the module federation assets folder.\n * Default value is `mf-manifest.json`.\n */\n manifestFileName?: string;\n\n /**\n * Type of the remote entry returned in the RemoteInfo for this remote.\n * Default value is `manifest`.\n */\n getRemoteEntryType?: (\n manifestContent: JsonObject,\n ) => 'manifest' | 'javascript';\n\n /**\n * Additional module federation fields, which might be required if the remote entry type is 'javascript'.\n */\n getAdditionalRemoteInfo?: (\n manifestContent: JsonObject,\n ) => AdditionalRemoteInfo;\n\n /**\n * Additional module federation fields, which might be required if the remote entry type is 'javascript'.\n * @deprecated Use `getAdditionalRemoteInfo` instead.\n */\n getAdditionaRemoteInfo?: (\n manifestContent: JsonObject,\n ) => AdditionalRemoteInfo;\n\n /**\n * Overrides the list of exposed modules. By default the exposed modules are read from the manifest file.\n */\n overrideExposedModules?: (\n exposedModules: string[],\n manifestContent: JsonObject,\n ) => string[];\n\n /**\n * Customizes the manifest before returning it as the remote entry.\n */\n customizeManifest?: (content: JsonObject) => JsonObject;\n};\n\n/**\n *\n * @public\n * */\nexport type FrontendRemoteResolverProvider = {\n for(\n pluginName: string,\n pluginPackagePath: string,\n ): Partial | undefined;\n};\n\n/**\n *\n * @public\n * */\nexport interface DynamicPluginsFrontendRemotesService {\n setResolverProvider(provider: FrontendRemoteResolverProvider): void;\n}\n\n/**\n * A service that serves the frontend module federation remotes,\n * and allows a plugin to customize the way remotes are served,\n * by setting a ResolverProvider.\n *\n * @public\n */\nexport const dynamicPluginsFrontendServiceRef =\n createServiceRef({\n id: 'core.dynamicplugins.frontendRemotes',\n scope: 'root',\n });\n\nexport type FrontendRemoteResolvers = {\n default: FrontendRemoteResolver &\n Required<\n Pick<\n FrontendRemoteResolver,\n 'assetsPathFromPackage' | 'manifestFileName' | 'getRemoteEntryType'\n >\n >;\n provider?: FrontendRemoteResolverProvider;\n};\n\nexport const frontendRemotesServerService = createServiceFactory({\n service: dynamicPluginsFrontendServiceRef,\n deps: {\n logger: coreServices.rootLogger,\n rootHttpRouter: coreServices.rootHttpRouter,\n config: coreServices.rootConfig,\n dynamicPlugins: dynamicPluginsServiceRef,\n lifecycle: coreServices.rootLifecycle,\n },\n async factory({ logger, rootHttpRouter, config, dynamicPlugins, lifecycle }) {\n const resolvers: FrontendRemoteResolvers = {\n default: {\n assetsPathFromPackage: 'dist',\n manifestFileName: ManifestFileName,\n getRemoteEntryType: () => 'manifest',\n },\n provider: undefined,\n };\n\n lifecycle.addStartupHook(async () => {\n rootHttpRouter.use(\n `/${spec.info.title}`,\n await createRouter({\n logger,\n config,\n dynamicPlugins,\n resolvers,\n }),\n );\n });\n\n return {\n setResolverProvider(resolver) {\n logger.info('Setting resolver provider');\n if (resolvers.provider) {\n throw new Error(\n 'Attempted to install a frontend remote resolver provider twice',\n );\n }\n resolvers.provider = resolver;\n },\n };\n },\n});\n"],"names":["createServiceRef","createServiceFactory","coreServices","dynamicPluginsServiceRef","ManifestFileName","spec","createRouter"],"mappings":";;;;;;;;AAiHO,MAAM,mCACXA,iCAAuD,CAAA;AAAA,EACrD,EAAI,EAAA,qCAAA;AAAA,EACJ,KAAO,EAAA;AACT,CAAC;AAaI,MAAM,+BAA+BC,qCAAqB,CAAA;AAAA,EAC/D,OAAS,EAAA,gCAAA;AAAA,EACT,IAAM,EAAA;AAAA,IACJ,QAAQC,6BAAa,CAAA,UAAA;AAAA,IACrB,gBAAgBA,6BAAa,CAAA,cAAA;AAAA,IAC7B,QAAQA,6BAAa,CAAA,UAAA;AAAA,IACrB,cAAgB,EAAAC,qDAAA;AAAA,IAChB,WAAWD,6BAAa,CAAA;AAAA,GAC1B;AAAA,EACA,MAAM,QAAQ,EAAE,MAAA,EAAQ,gBAAgB,MAAQ,EAAA,cAAA,EAAgB,WAAa,EAAA;AAC3E,IAAA,MAAM,SAAqC,GAAA;AAAA,MACzC,OAAS,EAAA;AAAA,QACP,qBAAuB,EAAA,MAAA;AAAA,QACvB,gBAAkB,EAAAE,oBAAA;AAAA,QAClB,oBAAoB,MAAM;AAAA,OAC5B;AAAA,MACA,QAAU,EAAA,KAAA;AAAA,KACZ;AAEA,IAAA,SAAA,CAAU,eAAe,YAAY;AACnC,MAAe,cAAA,CAAA,GAAA;AAAA,QACb,CAAA,CAAA,EAAIC,WAAK,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,QACnB,MAAMC,qBAAa,CAAA;AAAA,UACjB,MAAA;AAAA,UACA,MAAA;AAAA,UACA,cAAA;AAAA,UACA;AAAA,SACD;AAAA,OACH;AAAA,KACD,CAAA;AAED,IAAO,OAAA;AAAA,MACL,oBAAoB,QAAU,EAAA;AAC5B,QAAA,MAAA,CAAO,KAAK,2BAA2B,CAAA;AACvC,QAAA,IAAI,UAAU,QAAU,EAAA;AACtB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA;AAEF,QAAA,SAAA,CAAU,QAAW,GAAA,QAAA;AAAA;AACvB,KACF;AAAA;AAEJ,CAAC;;;;;"} -\ No newline at end of file -+{"version":3,"file":"frontendRemotesServer.cjs.js","sources":["../../src/server/frontendRemotesServer.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n coreServices,\n createServiceFactory,\n createServiceRef,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './router';\nimport { dynamicPluginsServiceRef } from '../manager';\nimport { spec } from '../schema/openapi';\nimport { ManifestFileName } from '@module-federation/sdk';\nimport { RemoteInfo } from '../schema/openapi/generated/models';\nimport { JsonObject } from '@backstage/types';\n\n/**\n *\n * @public\n * */\nexport type AdditionalRemoteInfo = Omit;\n\n/**\n *\n * @public\n * */\nexport type FrontendRemoteResolver = {\n /**\n * Relative path to the module federation assets folder from the root folder of the plugin package.\n * Default value is `dist`.\n */\n assetsPathFromPackage?: string;\n\n /**\n * File name of the module federation manifest inside the module federation assets folder.\n * Default value is `mf-manifest.json`.\n */\n manifestFileName?: string;\n\n /**\n * Type of the remote entry returned in the RemoteInfo for this remote.\n * Default value is `manifest`.\n */\n getRemoteEntryType?: (\n manifestContent: JsonObject,\n ) => 'manifest' | 'javascript';\n\n /**\n * Additional module federation fields, which might be required if the remote entry type is 'javascript'.\n */\n getAdditionalRemoteInfo?: (\n manifestContent: JsonObject,\n ) => AdditionalRemoteInfo;\n\n /**\n * Additional module federation fields, which might be required if the remote entry type is 'javascript'.\n * @deprecated Use `getAdditionalRemoteInfo` instead.\n */\n getAdditionaRemoteInfo?: (\n manifestContent: JsonObject,\n ) => AdditionalRemoteInfo;\n\n /**\n * Overrides the list of exposed modules. By default the exposed modules are read from the manifest file.\n */\n overrideExposedModules?: (\n exposedModules: string[],\n manifestContent: JsonObject,\n ) => string[];\n\n /**\n * Customizes the manifest before returning it as the remote entry.\n */\n customizeManifest?: (content: JsonObject) => JsonObject;\n};\n\n/**\n *\n * @public\n * */\nexport type FrontendRemoteResolverProvider = {\n for(\n pluginName: string,\n pluginPackagePath: string,\n ): Partial | undefined;\n};\n\n/**\n *\n * @public\n * */\nexport interface DynamicPluginsFrontendRemotesService {\n setResolverProvider(provider: FrontendRemoteResolverProvider): void;\n}\n\n/**\n * A service that serves the frontend module federation remotes,\n * and allows a plugin to customize the way remotes are served,\n * by setting a ResolverProvider.\n *\n * @public\n */\nexport const dynamicPluginsFrontendServiceRef =\n createServiceRef({\n id: 'core.dynamicplugins.frontendRemotes',\n scope: 'root',\n });\n\nexport type FrontendRemoteResolvers = {\n default: FrontendRemoteResolver &\n Required<\n Pick<\n FrontendRemoteResolver,\n 'assetsPathFromPackage' | 'manifestFileName' | 'getRemoteEntryType'\n >\n >;\n provider?: FrontendRemoteResolverProvider;\n};\n\nexport const frontendRemotesServerService = createServiceFactory({\n service: dynamicPluginsFrontendServiceRef,\n deps: {\n logger: coreServices.rootLogger,\n rootHttpRouter: coreServices.rootHttpRouter,\n config: coreServices.rootConfig,\n dynamicPlugins: dynamicPluginsServiceRef,\n lifecycle: coreServices.rootLifecycle,\n },\n async factory({ logger, rootHttpRouter, config, dynamicPlugins, lifecycle }) {\n const resolvers: FrontendRemoteResolvers = {\n default: {\n assetsPathFromPackage: 'dist',\n manifestFileName: ManifestFileName,\n getRemoteEntryType: () => 'manifest',\n },\n provider: undefined,\n };\n\n lifecycle.addStartupHook(async () => {\n rootHttpRouter.use(\n `/${spec.info.title}`,\n await createRouter({\n logger,\n config,\n dynamicPlugins,\n resolvers,\n }),\n );\n });\n\n return {\n setResolverProvider(resolver) {\n logger.info('Setting resolver provider');\n if (resolvers.provider) {\n throw new Error(\n 'Attempted to install a frontend remote resolver provider twice',\n );\n }\n resolvers.provider = resolver;\n },\n };\n },\n});\n"],"names":["createServiceRef","createServiceFactory","coreServices","dynamicPluginsServiceRef","ManifestFileName","spec","createRouter"],"mappings":";;;;;;;;AAiHO,MAAM,mCACXA,iCAAuD,CAAA;AAAA,EACrD,EAAI,EAAA,qCAAA;AAAA,EACJ,KAAO,EAAA;AACT,CAAC;AAaI,MAAM,+BAA+BC,qCAAqB,CAAA;AAAA,EAC/D,OAAS,EAAA,gCAAA;AAAA,EACT,IAAM,EAAA;AAAA,IACJ,QAAQC,6BAAa,CAAA,UAAA;AAAA,IACrB,gBAAgBA,6BAAa,CAAA,cAAA;AAAA,IAC7B,QAAQA,6BAAa,CAAA,UAAA;AAAA,IACrB,cAAgB,EAAAC,sCAAA;AAAA,IAChB,WAAWD,6BAAa,CAAA;AAAA,GAC1B;AAAA,EACA,MAAM,QAAQ,EAAE,MAAA,EAAQ,gBAAgB,MAAQ,EAAA,cAAA,EAAgB,WAAa,EAAA;AAC3E,IAAA,MAAM,SAAqC,GAAA;AAAA,MACzC,OAAS,EAAA;AAAA,QACP,qBAAuB,EAAA,MAAA;AAAA,QACvB,gBAAkB,EAAAE,oBAAA;AAAA,QAClB,oBAAoB,MAAM;AAAA,OAC5B;AAAA,MACA,QAAU,EAAA,KAAA;AAAA,KACZ;AAEA,IAAA,SAAA,CAAU,eAAe,YAAY;AACnC,MAAe,cAAA,CAAA,GAAA;AAAA,QACb,CAAA,CAAA,EAAIC,WAAK,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,QACnB,MAAMC,qBAAa,CAAA;AAAA,UACjB,MAAA;AAAA,UACA,MAAA;AAAA,UACA,cAAA;AAAA,UACA;AAAA,SACD;AAAA,OACH;AAAA,KACD,CAAA;AAED,IAAO,OAAA;AAAA,MACL,oBAAoB,QAAU,EAAA;AAC5B,QAAA,MAAA,CAAO,KAAK,2BAA2B,CAAA;AACvC,QAAA,IAAI,UAAU,QAAU,EAAA;AACtB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA;AAEF,QAAA,SAAA,CAAU,QAAW,GAAA,QAAA;AAAA;AACvB,KACF;AAAA;AAEJ,CAAC;;;;;"} -\ No newline at end of file -diff --git a/dist/server/router.cjs.js.map b/dist/server/router.cjs.js.map -index 13debceeac332db88088eb038d27d082a10d4d01..83d9911842800b66ec994900332e6fbed0a0160a 100644 ---- a/dist/server/router.cjs.js.map -+++ b/dist/server/router.cjs.js.map -@@ -1 +1 @@ --{"version":3,"file":"router.cjs.js","sources":["../../src/server/router.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport express from 'express';\nimport { createOpenApiRouter, spec } from '../schema/openapi';\nimport { DynamicPluginProvider } from '@backstage/backend-dynamic-feature-service';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { FrontendRemoteResolvers } from './frontendRemotesServer';\nimport { Remote } from '../schema/openapi/generated/models';\nimport { JsonObject } from '@backstage/types';\n\nexport async function createRouter({\n logger,\n config,\n dynamicPlugins,\n resolvers,\n}: {\n logger: LoggerService;\n config: RootConfigService;\n dynamicPlugins: DynamicPluginProvider;\n resolvers: FrontendRemoteResolvers;\n}): Promise {\n const externalBaseUrl = `${config.getString('backend.baseUrl')}/${\n spec.info.title\n }`;\n\n const typedRouter = await createOpenApiRouter();\n\n const frontendPluginRemotes: Remote[] = [];\n\n const { default: defaultResolver, provider: resolverProvider } = resolvers;\n for (const plugin of dynamicPlugins.frontendPlugins()) {\n try {\n const pluginScannedPackage = dynamicPlugins.getScannedPackage(plugin);\n const pluginScannedPackagePath = path.resolve(\n url.fileURLToPath(pluginScannedPackage.location),\n );\n const providedResolver = resolverProvider?.for(\n plugin.name,\n pluginScannedPackagePath,\n );\n\n const assetsPath = path.resolve(\n pluginScannedPackagePath,\n providedResolver?.assetsPathFromPackage ??\n defaultResolver.assetsPathFromPackage,\n );\n\n const manifestFileName =\n providedResolver?.manifestFileName ?? defaultResolver.manifestFileName;\n const manifestLocation = path.resolve(assetsPath, manifestFileName);\n if (!fs.existsSync(manifestLocation)) {\n logger.error(\n `Could not find manifest '${manifestLocation}' for frontend plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n let manifest: JsonObject;\n try {\n manifest = JSON.parse(fs.readFileSync(manifestLocation).toString());\n } catch (error) {\n logger.error(\n `Dynamic frontend plugin manifest '${manifestLocation}' could not be parsed for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n if (!manifest.name || typeof manifest.name !== 'string') {\n logger.error(\n `Error in manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}: module name not found`,\n );\n continue;\n }\n if (\n !manifest.metaData ||\n typeof manifest.metaData !== 'object' ||\n !('remoteEntry' in manifest.metaData) ||\n !manifest.metaData.remoteEntry ||\n typeof manifest.metaData.remoteEntry !== 'object' ||\n !('name' in manifest.metaData.remoteEntry) ||\n typeof manifest.metaData.remoteEntry.name !== 'string'\n ) {\n logger.error(\n `Could not find remote entry asset in the manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n if (\n !manifest.exposes ||\n !Array.isArray(manifest.exposes) ||\n !manifest.exposes.every<{ name: string }>(\n (i): i is { name: string } =>\n i !== null && typeof i === 'object' && 'name' in i,\n )\n ) {\n logger.error(\n `Could not find the exposes field in the manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n const getAdditionalRemoteInfo =\n providedResolver?.getAdditionalRemoteInfo ??\n providedResolver?.getAdditionaRemoteInfo ??\n defaultResolver.getAdditionalRemoteInfo ??\n defaultResolver?.getAdditionaRemoteInfo;\n const getRemoteEntryType =\n providedResolver?.getRemoteEntryType ??\n defaultResolver.getRemoteEntryType;\n const remoteEntryType = getRemoteEntryType(manifest);\n\n let remoteEntryAsset = manifestFileName;\n if (remoteEntryType === 'javascript') {\n remoteEntryAsset = manifest.metaData.remoteEntry.name;\n }\n\n const remoteEntryAssetLocation = path.resolve(\n assetsPath,\n remoteEntryAsset,\n );\n if (!fs.existsSync(remoteEntryAssetLocation)) {\n logger.error(\n `Could not find remote entry asset '${remoteEntryAssetLocation}' for frontend plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n const remoteAssetsPrefix = `/remotes/${plugin.name}`;\n const remoteEntryPath = `${remoteAssetsPrefix}/${remoteEntryAsset}`;\n\n const overrideExposedModules =\n providedResolver?.overrideExposedModules ??\n defaultResolver.overrideExposedModules;\n\n const exposedModules = manifest.exposes.map(e => e.name);\n\n frontendPluginRemotes.push({\n packageName: plugin.name,\n remoteInfo: {\n name: manifest.name,\n entry: `${externalBaseUrl}${remoteEntryPath}`,\n ...getAdditionalRemoteInfo?.(manifest),\n },\n exposedModules:\n overrideExposedModules?.(exposedModules, manifest) ?? exposedModules,\n });\n\n const customizeManifest =\n providedResolver?.customizeManifest ??\n defaultResolver.customizeManifest;\n if (remoteEntryType === 'manifest' && customizeManifest) {\n const customizedContent = customizeManifest(manifest);\n typedRouter.use(`${remoteEntryPath}`, (_, res) => {\n res.json(customizedContent);\n });\n }\n typedRouter.use(remoteAssetsPrefix, express.static(assetsPath));\n logger.info(\n `Exposed dynamic frontend plugin '${plugin.name}' from '${assetsPath}' `,\n );\n } catch (error) {\n logger.error(\n `Unexpected error when exposing dynamic frontend plugin '${plugin.name}@${plugin.version}'`,\n error,\n );\n continue;\n }\n }\n\n logger.info(`/remotes => ${JSON.stringify(frontendPluginRemotes)}`);\n typedRouter.get('/remotes', (_, res) => {\n res.status(200).json(frontendPluginRemotes);\n });\n\n return typedRouter;\n}\n"],"names":["spec","createOpenApiRouter","path","url","fs","express"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,eAAsB,YAAa,CAAA;AAAA,EACjC,MAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAK4B,EAAA;AAC1B,EAAM,MAAA,eAAA,GAAkB,GAAG,MAAO,CAAA,SAAA,CAAU,iBAAiB,CAAC,CAAA,CAAA,EAC5DA,WAAK,CAAA,IAAA,CAAK,KACZ,CAAA,CAAA;AAEA,EAAM,MAAA,WAAA,GAAc,MAAMC,0BAAoB,EAAA;AAE9C,EAAA,MAAM,wBAAkC,EAAC;AAEzC,EAAA,MAAM,EAAE,OAAA,EAAS,eAAiB,EAAA,QAAA,EAAU,kBAAqB,GAAA,SAAA;AACjE,EAAW,KAAA,MAAA,MAAA,IAAU,cAAe,CAAA,eAAA,EAAmB,EAAA;AACrD,IAAI,IAAA;AACF,MAAM,MAAA,oBAAA,GAAuB,cAAe,CAAA,iBAAA,CAAkB,MAAM,CAAA;AACpE,MAAA,MAAM,2BAA2BC,eAAK,CAAA,OAAA;AAAA,QACpCC,cAAA,CAAI,aAAc,CAAA,oBAAA,CAAqB,QAAQ;AAAA,OACjD;AACA,MAAA,MAAM,mBAAmB,gBAAkB,EAAA,GAAA;AAAA,QACzC,MAAO,CAAA,IAAA;AAAA,QACP;AAAA,OACF;AAEA,MAAA,MAAM,aAAaD,eAAK,CAAA,OAAA;AAAA,QACtB,wBAAA;AAAA,QACA,gBAAA,EAAkB,yBAChB,eAAgB,CAAA;AAAA,OACpB;AAEA,MAAM,MAAA,gBAAA,GACJ,gBAAkB,EAAA,gBAAA,IAAoB,eAAgB,CAAA,gBAAA;AACxD,MAAA,MAAM,gBAAmB,GAAAA,eAAA,CAAK,OAAQ,CAAA,UAAA,EAAY,gBAAgB,CAAA;AAClE,MAAA,IAAI,CAACE,aAAA,CAAG,UAAW,CAAA,gBAAgB,CAAG,EAAA;AACpC,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,4BAA4B,gBAAgB,CAAA,sBAAA,EAAyB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACpG;AACA,QAAA;AAAA;AAGF,MAAI,IAAA,QAAA;AACJ,MAAI,IAAA;AACF,QAAA,QAAA,GAAW,KAAK,KAAM,CAAAA,aAAA,CAAG,aAAa,gBAAgB,CAAA,CAAE,UAAU,CAAA;AAAA,eAC3D,KAAO,EAAA;AACd,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,qCAAqC,gBAAgB,CAAA,iCAAA,EAAoC,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACxH;AACA,QAAA;AAAA;AAGF,MAAA,IAAI,CAAC,QAAS,CAAA,IAAA,IAAQ,OAAO,QAAA,CAAS,SAAS,QAAU,EAAA;AACvD,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,sBAAsB,gBAAgB,CAAA,aAAA,EAAgB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA,uBAAA;AAAA,SACrF;AACA,QAAA;AAAA;AAEF,MAAA,IACE,CAAC,QAAA,CAAS,QACV,IAAA,OAAO,QAAS,CAAA,QAAA,KAAa,QAC7B,IAAA,EAAE,aAAiB,IAAA,QAAA,CAAS,QAC5B,CAAA,IAAA,CAAC,SAAS,QAAS,CAAA,WAAA,IACnB,OAAO,QAAA,CAAS,QAAS,CAAA,WAAA,KAAgB,QACzC,IAAA,EAAE,MAAU,IAAA,QAAA,CAAS,QAAS,CAAA,WAAA,CAAA,IAC9B,OAAO,QAAA,CAAS,QAAS,CAAA,WAAA,CAAY,SAAS,QAC9C,EAAA;AACA,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,sDAAsD,gBAAgB,CAAA,aAAA,EAAgB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACrH;AACA,QAAA;AAAA;AAGF,MACE,IAAA,CAAC,QAAS,CAAA,OAAA,IACV,CAAC,KAAA,CAAM,OAAQ,CAAA,QAAA,CAAS,OAAO,CAAA,IAC/B,CAAC,QAAA,CAAS,OAAQ,CAAA,KAAA;AAAA,QAChB,CAAC,CACC,KAAA,CAAA,KAAM,QAAQ,OAAO,CAAA,KAAM,YAAY,MAAU,IAAA;AAAA,OAErD,EAAA;AACA,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,qDAAqD,gBAAgB,CAAA,aAAA,EAAgB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACpH;AACA,QAAA;AAAA;AAGF,MAAA,MAAM,0BACJ,gBAAkB,EAAA,uBAAA,IAClB,kBAAkB,sBAClB,IAAA,eAAA,CAAgB,2BAChB,eAAiB,EAAA,sBAAA;AACnB,MAAM,MAAA,kBAAA,GACJ,gBAAkB,EAAA,kBAAA,IAClB,eAAgB,CAAA,kBAAA;AAClB,MAAM,MAAA,eAAA,GAAkB,mBAAmB,QAAQ,CAAA;AAEnD,MAAA,IAAI,gBAAmB,GAAA,gBAAA;AACvB,MAAA,IAAI,oBAAoB,YAAc,EAAA;AACpC,QAAmB,gBAAA,GAAA,QAAA,CAAS,SAAS,WAAY,CAAA,IAAA;AAAA;AAGnD,MAAA,MAAM,2BAA2BF,eAAK,CAAA,OAAA;AAAA,QACpC,UAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,IAAI,CAACE,aAAA,CAAG,UAAW,CAAA,wBAAwB,CAAG,EAAA;AAC5C,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,sCAAsC,wBAAwB,CAAA,sBAAA,EAAyB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACtH;AACA,QAAA;AAAA;AAGF,MAAM,MAAA,kBAAA,GAAqB,CAAY,SAAA,EAAA,MAAA,CAAO,IAAI,CAAA,CAAA;AAClD,MAAA,MAAM,eAAkB,GAAA,CAAA,EAAG,kBAAkB,CAAA,CAAA,EAAI,gBAAgB,CAAA,CAAA;AAEjE,MAAM,MAAA,sBAAA,GACJ,gBAAkB,EAAA,sBAAA,IAClB,eAAgB,CAAA,sBAAA;AAElB,MAAA,MAAM,iBAAiB,QAAS,CAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,IAAI,CAAA;AAEvD,MAAA,qBAAA,CAAsB,IAAK,CAAA;AAAA,QACzB,aAAa,MAAO,CAAA,IAAA;AAAA,QACpB,UAAY,EAAA;AAAA,UACV,MAAM,QAAS,CAAA,IAAA;AAAA,UACf,KAAO,EAAA,CAAA,EAAG,eAAe,CAAA,EAAG,eAAe,CAAA,CAAA;AAAA,UAC3C,GAAG,0BAA0B,QAAQ;AAAA,SACvC;AAAA,QACA,cACE,EAAA,sBAAA,GAAyB,cAAgB,EAAA,QAAQ,CAAK,IAAA;AAAA,OACzD,CAAA;AAED,MAAM,MAAA,iBAAA,GACJ,gBAAkB,EAAA,iBAAA,IAClB,eAAgB,CAAA,iBAAA;AAClB,MAAI,IAAA,eAAA,KAAoB,cAAc,iBAAmB,EAAA;AACvD,QAAM,MAAA,iBAAA,GAAoB,kBAAkB,QAAQ,CAAA;AACpD,QAAA,WAAA,CAAY,IAAI,CAAG,EAAA,eAAe,CAAI,CAAA,EAAA,CAAC,GAAG,GAAQ,KAAA;AAChD,UAAA,GAAA,CAAI,KAAK,iBAAiB,CAAA;AAAA,SAC3B,CAAA;AAAA;AAEH,MAAA,WAAA,CAAY,GAAI,CAAA,kBAAA,EAAoBC,wBAAQ,CAAA,MAAA,CAAO,UAAU,CAAC,CAAA;AAC9D,MAAO,MAAA,CAAA,IAAA;AAAA,QACL,CAAoC,iCAAA,EAAA,MAAA,CAAO,IAAI,CAAA,QAAA,EAAW,UAAU,CAAA,EAAA;AAAA,OACtE;AAAA,aACO,KAAO,EAAA;AACd,MAAO,MAAA,CAAA,KAAA;AAAA,QACL,CAA2D,wDAAA,EAAA,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA,CAAA,CAAA;AAAA,QACxF;AAAA,OACF;AACA,MAAA;AAAA;AACF;AAGF,EAAA,MAAA,CAAO,KAAK,CAAe,YAAA,EAAA,IAAA,CAAK,SAAU,CAAA,qBAAqB,CAAC,CAAE,CAAA,CAAA;AAClE,EAAA,WAAA,CAAY,GAAI,CAAA,UAAA,EAAY,CAAC,CAAA,EAAG,GAAQ,KAAA;AACtC,IAAA,GAAA,CAAI,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,qBAAqB,CAAA;AAAA,GAC3C,CAAA;AAED,EAAO,OAAA,WAAA;AACT;;;;"} -\ No newline at end of file -+{"version":3,"file":"router.cjs.js","sources":["../../src/server/router.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport express from 'express';\nimport { createOpenApiRouter, spec } from '../schema/openapi';\nimport { DynamicPluginProvider } from '../manager';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { FrontendRemoteResolvers } from './frontendRemotesServer';\nimport { Remote } from '../schema/openapi/generated/models';\nimport { JsonObject } from '@backstage/types';\n\nexport async function createRouter({\n logger,\n config,\n dynamicPlugins,\n resolvers,\n}: {\n logger: LoggerService;\n config: RootConfigService;\n dynamicPlugins: DynamicPluginProvider;\n resolvers: FrontendRemoteResolvers;\n}): Promise {\n const externalBaseUrl = `${config.getString('backend.baseUrl')}/${\n spec.info.title\n }`;\n\n const typedRouter = await createOpenApiRouter();\n\n const frontendPluginRemotes: Remote[] = [];\n\n const { default: defaultResolver, provider: resolverProvider } = resolvers;\n for (const plugin of dynamicPlugins.frontendPlugins()) {\n try {\n const pluginScannedPackage = dynamicPlugins.getScannedPackage(plugin);\n const pluginScannedPackagePath = path.resolve(\n url.fileURLToPath(pluginScannedPackage.location),\n );\n const providedResolver = resolverProvider?.for(\n plugin.name,\n pluginScannedPackagePath,\n );\n\n const assetsPath = path.resolve(\n pluginScannedPackagePath,\n providedResolver?.assetsPathFromPackage ??\n defaultResolver.assetsPathFromPackage,\n );\n\n const manifestFileName =\n providedResolver?.manifestFileName ?? defaultResolver.manifestFileName;\n const manifestLocation = path.resolve(assetsPath, manifestFileName);\n if (!fs.existsSync(manifestLocation)) {\n logger.error(\n `Could not find manifest '${manifestLocation}' for frontend plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n let manifest: JsonObject;\n try {\n manifest = JSON.parse(fs.readFileSync(manifestLocation).toString());\n } catch (error) {\n logger.error(\n `Dynamic frontend plugin manifest '${manifestLocation}' could not be parsed for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n if (!manifest.name || typeof manifest.name !== 'string') {\n logger.error(\n `Error in manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}: module name not found`,\n );\n continue;\n }\n if (\n !manifest.metaData ||\n typeof manifest.metaData !== 'object' ||\n !('remoteEntry' in manifest.metaData) ||\n !manifest.metaData.remoteEntry ||\n typeof manifest.metaData.remoteEntry !== 'object' ||\n !('name' in manifest.metaData.remoteEntry) ||\n typeof manifest.metaData.remoteEntry.name !== 'string'\n ) {\n logger.error(\n `Could not find remote entry asset in the manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n if (\n !manifest.exposes ||\n !Array.isArray(manifest.exposes) ||\n !manifest.exposes.every<{ name: string }>(\n (i): i is { name: string } =>\n i !== null && typeof i === 'object' && 'name' in i,\n )\n ) {\n logger.error(\n `Could not find the exposes field in the manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n const getAdditionalRemoteInfo =\n providedResolver?.getAdditionalRemoteInfo ??\n providedResolver?.getAdditionaRemoteInfo ??\n defaultResolver.getAdditionalRemoteInfo ??\n defaultResolver?.getAdditionaRemoteInfo;\n const getRemoteEntryType =\n providedResolver?.getRemoteEntryType ??\n defaultResolver.getRemoteEntryType;\n const remoteEntryType = getRemoteEntryType(manifest);\n\n let remoteEntryAsset = manifestFileName;\n if (remoteEntryType === 'javascript') {\n remoteEntryAsset = manifest.metaData.remoteEntry.name;\n }\n\n const remoteEntryAssetLocation = path.resolve(\n assetsPath,\n remoteEntryAsset,\n );\n if (!fs.existsSync(remoteEntryAssetLocation)) {\n logger.error(\n `Could not find remote entry asset '${remoteEntryAssetLocation}' for frontend plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n const remoteAssetsPrefix = `/remotes/${plugin.name}`;\n const remoteEntryPath = `${remoteAssetsPrefix}/${remoteEntryAsset}`;\n\n const overrideExposedModules =\n providedResolver?.overrideExposedModules ??\n defaultResolver.overrideExposedModules;\n\n const exposedModules = manifest.exposes.map(e => e.name);\n\n frontendPluginRemotes.push({\n packageName: plugin.name,\n remoteInfo: {\n name: manifest.name,\n entry: `${externalBaseUrl}${remoteEntryPath}`,\n ...getAdditionalRemoteInfo?.(manifest),\n },\n exposedModules:\n overrideExposedModules?.(exposedModules, manifest) ?? exposedModules,\n });\n\n const customizeManifest =\n providedResolver?.customizeManifest ??\n defaultResolver.customizeManifest;\n if (remoteEntryType === 'manifest' && customizeManifest) {\n const customizedContent = customizeManifest(manifest);\n typedRouter.use(`${remoteEntryPath}`, (_, res) => {\n res.json(customizedContent);\n });\n }\n typedRouter.use(remoteAssetsPrefix, express.static(assetsPath));\n logger.info(\n `Exposed dynamic frontend plugin '${plugin.name}' from '${assetsPath}' `,\n );\n } catch (error) {\n logger.error(\n `Unexpected error when exposing dynamic frontend plugin '${plugin.name}@${plugin.version}'`,\n error,\n );\n continue;\n }\n }\n\n logger.info(`/remotes => ${JSON.stringify(frontendPluginRemotes)}`);\n typedRouter.get('/remotes', (_, res) => {\n res.status(200).json(frontendPluginRemotes);\n });\n\n return typedRouter;\n}\n"],"names":["spec","createOpenApiRouter","path","url","fs","express"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,eAAsB,YAAa,CAAA;AAAA,EACjC,MAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAK4B,EAAA;AAC1B,EAAM,MAAA,eAAA,GAAkB,GAAG,MAAO,CAAA,SAAA,CAAU,iBAAiB,CAAC,CAAA,CAAA,EAC5DA,WAAK,CAAA,IAAA,CAAK,KACZ,CAAA,CAAA;AAEA,EAAM,MAAA,WAAA,GAAc,MAAMC,0BAAoB,EAAA;AAE9C,EAAA,MAAM,wBAAkC,EAAC;AAEzC,EAAA,MAAM,EAAE,OAAA,EAAS,eAAiB,EAAA,QAAA,EAAU,kBAAqB,GAAA,SAAA;AACjE,EAAW,KAAA,MAAA,MAAA,IAAU,cAAe,CAAA,eAAA,EAAmB,EAAA;AACrD,IAAI,IAAA;AACF,MAAM,MAAA,oBAAA,GAAuB,cAAe,CAAA,iBAAA,CAAkB,MAAM,CAAA;AACpE,MAAA,MAAM,2BAA2BC,eAAK,CAAA,OAAA;AAAA,QACpCC,cAAA,CAAI,aAAc,CAAA,oBAAA,CAAqB,QAAQ;AAAA,OACjD;AACA,MAAA,MAAM,mBAAmB,gBAAkB,EAAA,GAAA;AAAA,QACzC,MAAO,CAAA,IAAA;AAAA,QACP;AAAA,OACF;AAEA,MAAA,MAAM,aAAaD,eAAK,CAAA,OAAA;AAAA,QACtB,wBAAA;AAAA,QACA,gBAAA,EAAkB,yBAChB,eAAgB,CAAA;AAAA,OACpB;AAEA,MAAM,MAAA,gBAAA,GACJ,gBAAkB,EAAA,gBAAA,IAAoB,eAAgB,CAAA,gBAAA;AACxD,MAAA,MAAM,gBAAmB,GAAAA,eAAA,CAAK,OAAQ,CAAA,UAAA,EAAY,gBAAgB,CAAA;AAClE,MAAA,IAAI,CAACE,aAAA,CAAG,UAAW,CAAA,gBAAgB,CAAG,EAAA;AACpC,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,4BAA4B,gBAAgB,CAAA,sBAAA,EAAyB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACpG;AACA,QAAA;AAAA;AAGF,MAAI,IAAA,QAAA;AACJ,MAAI,IAAA;AACF,QAAA,QAAA,GAAW,KAAK,KAAM,CAAAA,aAAA,CAAG,aAAa,gBAAgB,CAAA,CAAE,UAAU,CAAA;AAAA,eAC3D,KAAO,EAAA;AACd,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,qCAAqC,gBAAgB,CAAA,iCAAA,EAAoC,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACxH;AACA,QAAA;AAAA;AAGF,MAAA,IAAI,CAAC,QAAS,CAAA,IAAA,IAAQ,OAAO,QAAA,CAAS,SAAS,QAAU,EAAA;AACvD,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,sBAAsB,gBAAgB,CAAA,aAAA,EAAgB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA,uBAAA;AAAA,SACrF;AACA,QAAA;AAAA;AAEF,MAAA,IACE,CAAC,QAAA,CAAS,QACV,IAAA,OAAO,QAAS,CAAA,QAAA,KAAa,QAC7B,IAAA,EAAE,aAAiB,IAAA,QAAA,CAAS,QAC5B,CAAA,IAAA,CAAC,SAAS,QAAS,CAAA,WAAA,IACnB,OAAO,QAAA,CAAS,QAAS,CAAA,WAAA,KAAgB,QACzC,IAAA,EAAE,MAAU,IAAA,QAAA,CAAS,QAAS,CAAA,WAAA,CAAA,IAC9B,OAAO,QAAA,CAAS,QAAS,CAAA,WAAA,CAAY,SAAS,QAC9C,EAAA;AACA,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,sDAAsD,gBAAgB,CAAA,aAAA,EAAgB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACrH;AACA,QAAA;AAAA;AAGF,MACE,IAAA,CAAC,QAAS,CAAA,OAAA,IACV,CAAC,KAAA,CAAM,OAAQ,CAAA,QAAA,CAAS,OAAO,CAAA,IAC/B,CAAC,QAAA,CAAS,OAAQ,CAAA,KAAA;AAAA,QAChB,CAAC,CACC,KAAA,CAAA,KAAM,QAAQ,OAAO,CAAA,KAAM,YAAY,MAAU,IAAA;AAAA,OAErD,EAAA;AACA,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,qDAAqD,gBAAgB,CAAA,aAAA,EAAgB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACpH;AACA,QAAA;AAAA;AAGF,MAAA,MAAM,0BACJ,gBAAkB,EAAA,uBAAA,IAClB,kBAAkB,sBAClB,IAAA,eAAA,CAAgB,2BAChB,eAAiB,EAAA,sBAAA;AACnB,MAAM,MAAA,kBAAA,GACJ,gBAAkB,EAAA,kBAAA,IAClB,eAAgB,CAAA,kBAAA;AAClB,MAAM,MAAA,eAAA,GAAkB,mBAAmB,QAAQ,CAAA;AAEnD,MAAA,IAAI,gBAAmB,GAAA,gBAAA;AACvB,MAAA,IAAI,oBAAoB,YAAc,EAAA;AACpC,QAAmB,gBAAA,GAAA,QAAA,CAAS,SAAS,WAAY,CAAA,IAAA;AAAA;AAGnD,MAAA,MAAM,2BAA2BF,eAAK,CAAA,OAAA;AAAA,QACpC,UAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,IAAI,CAACE,aAAA,CAAG,UAAW,CAAA,wBAAwB,CAAG,EAAA;AAC5C,QAAO,MAAA,CAAA,KAAA;AAAA,UACL,sCAAsC,wBAAwB,CAAA,sBAAA,EAAyB,OAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA;AAAA,SACtH;AACA,QAAA;AAAA;AAGF,MAAM,MAAA,kBAAA,GAAqB,CAAY,SAAA,EAAA,MAAA,CAAO,IAAI,CAAA,CAAA;AAClD,MAAA,MAAM,eAAkB,GAAA,CAAA,EAAG,kBAAkB,CAAA,CAAA,EAAI,gBAAgB,CAAA,CAAA;AAEjE,MAAM,MAAA,sBAAA,GACJ,gBAAkB,EAAA,sBAAA,IAClB,eAAgB,CAAA,sBAAA;AAElB,MAAA,MAAM,iBAAiB,QAAS,CAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,IAAI,CAAA;AAEvD,MAAA,qBAAA,CAAsB,IAAK,CAAA;AAAA,QACzB,aAAa,MAAO,CAAA,IAAA;AAAA,QACpB,UAAY,EAAA;AAAA,UACV,MAAM,QAAS,CAAA,IAAA;AAAA,UACf,KAAO,EAAA,CAAA,EAAG,eAAe,CAAA,EAAG,eAAe,CAAA,CAAA;AAAA,UAC3C,GAAG,0BAA0B,QAAQ;AAAA,SACvC;AAAA,QACA,cACE,EAAA,sBAAA,GAAyB,cAAgB,EAAA,QAAQ,CAAK,IAAA;AAAA,OACzD,CAAA;AAED,MAAM,MAAA,iBAAA,GACJ,gBAAkB,EAAA,iBAAA,IAClB,eAAgB,CAAA,iBAAA;AAClB,MAAI,IAAA,eAAA,KAAoB,cAAc,iBAAmB,EAAA;AACvD,QAAM,MAAA,iBAAA,GAAoB,kBAAkB,QAAQ,CAAA;AACpD,QAAA,WAAA,CAAY,IAAI,CAAG,EAAA,eAAe,CAAI,CAAA,EAAA,CAAC,GAAG,GAAQ,KAAA;AAChD,UAAA,GAAA,CAAI,KAAK,iBAAiB,CAAA;AAAA,SAC3B,CAAA;AAAA;AAEH,MAAA,WAAA,CAAY,GAAI,CAAA,kBAAA,EAAoBC,wBAAQ,CAAA,MAAA,CAAO,UAAU,CAAC,CAAA;AAC9D,MAAO,MAAA,CAAA,IAAA;AAAA,QACL,CAAoC,iCAAA,EAAA,MAAA,CAAO,IAAI,CAAA,QAAA,EAAW,UAAU,CAAA,EAAA;AAAA,OACtE;AAAA,aACO,KAAO,EAAA;AACd,MAAO,MAAA,CAAA,KAAA;AAAA,QACL,CAA2D,wDAAA,EAAA,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA,CAAA,CAAA;AAAA,QACxF;AAAA,OACF;AACA,MAAA;AAAA;AACF;AAGF,EAAA,MAAA,CAAO,KAAK,CAAe,YAAA,EAAA,IAAA,CAAK,SAAU,CAAA,qBAAqB,CAAC,CAAE,CAAA,CAAA;AAClE,EAAA,WAAA,CAAY,GAAI,CAAA,UAAA,EAAY,CAAC,CAAA,EAAG,GAAQ,KAAA;AACtC,IAAA,GAAA,CAAI,MAAO,CAAA,GAAG,CAAE,CAAA,IAAA,CAAK,qBAAqB,CAAA;AAAA,GAC3C,CAAA;AAED,EAAO,OAAA,WAAA;AACT;;;;"} -\ No newline at end of file diff --git a/OWNERS b/OWNERS index cdcea7fec6..14e45eb74f 100644 --- a/OWNERS +++ b/OWNERS @@ -2,7 +2,6 @@ approvers: - 04kash - albarbaro - christoph-jerolimov - - coreydaley - davidfestal - debsmita1 - divyanshiGupta @@ -19,7 +18,6 @@ approvers: - rm3l - schultzp2020 - subhashkhileri + - Zaperex reviewers: - - dzemanov - - its-mitesh-kumar \ No newline at end of file diff --git a/README.md b/README.md index f4d9a441c5..8744f57d9e 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ We also welcome non code contributions in the form of bug reporting and document ## Community, Discussion, and Support -[Bugs](https://issues.redhat.com/projects/RHIDP) should be filled out here on RHIDP Jira. +[Bugs](https://issues.redhat.com/projects/RHDHBUGS) should be filled out here on RHDHBUGS Jira. ## Resources diff --git a/backstage.json b/backstage.json index 7a266655ed..6c12971cc4 100644 --- a/backstage.json +++ b/backstage.json @@ -1,3 +1,3 @@ { - "version": "1.39.1" + "version": "1.42.5" } diff --git a/catalog-entities/marketplace/README.md b/catalog-entities/marketplace/README.md index 6b697d4073..ba5e0c8760 100644 --- a/catalog-entities/marketplace/README.md +++ b/catalog-entities/marketplace/README.md @@ -83,8 +83,8 @@ metadata: - apis # The description below is used in the Extension plugin's "Tile" view as the plugin description. Keep it to a few lines (short description) description: | - 3scale provides a comprehensive API management solution, enabling organizations to secure, manage, and monetize APIs. - Key features include access control, usage analytics, and policy enforcement. + 3scale provides a comprehensive API management solution, enabling organizations to secure, manage, and monetize APIs. + Key features include access control, usage analytics, and policy enforcement. The 3scale plugin synchronizes your 3scale content into the software catalog. spec: # Custom information processed by the Extensions plugin author: Red Hat # The Author of the plugin @@ -94,7 +94,7 @@ spec: # Custom information processed by the Extensions plugin # The long description below is used in the Extension plugin's "Expanded Info" view as the plugin's long description. You should include information here about the the purpose of the plugin and how it integrates with RHDH. The description here uses Markdown fomat, but DON'T include images - they won't load if you do. description: | - The 3scale Backstage plugin... + The 3scale Backstage plugin... (add further text here to really describe to the user what your plugin is for and how it integrates with RHDH's frontend/backend). * Use bullets if you need to @@ -165,9 +165,9 @@ catalog: ``` -In `docker-compose.yaml` do this: +In `compose.yaml` do this: -```yaml:docker-compose.yaml +```yaml:compose.yaml services: rhdh: volumes: @@ -197,7 +197,7 @@ docker compose restart rhdh # or podman-compose restart rhdh ### Catalog stops loading or refreshing Sometimes you might make a mistake with a plugin yaml file. If that happens you can use commenting of lines in the `plugins/all.yaml` -to stop certain plugins from being loaded into the catalog. You can allso search for `all.yaml` in the RHDH logs to see if you can +to stop certain plugins from being loaded into the catalog. You can allso search for `all.yaml` in the RHDH logs to see if you can find a clue as to what caused the catalog entries to stop loading. For example: ```bash @@ -210,7 +210,7 @@ You can trace packages back to plugin entries using the VS Code "Find In Folder. 1. Given the plugin ID `@backstage-community/plugin-quay` (replace with the plugin ID you need) 1. Do a "Find in Folder..." search for the `package/` file that contains this entry. -1. The `/packages/backstage-community-plugin-quay.yaml` contains this entry. +1. The `/packages/backstage-community-plugin-quay.yaml` contains this entry. 1. Open this file and look for the `metadata.name` (`backstage-community-plugin-quay`). 1. Now do a search in the plugins folder for the text `backstage-community-plugin-quay`. 1. The `plugins/backstage-community-plugin-quay.yaml` contains this text. diff --git a/catalog-entities/marketplace/packages/all.yaml b/catalog-entities/marketplace/packages/all.yaml index 93c029adca..4961f8150d 100644 --- a/catalog-entities/marketplace/packages/all.yaml +++ b/catalog-entities/marketplace/packages/all.yaml @@ -5,6 +5,8 @@ metadata: name: packages spec: targets: + - ./aws-amazon-ecs-plugin-for-backstage-backend.yaml + - ./aws-amazon-ecs-plugin-for-backstage.yaml - ./backstage-plugin-scaffolder-backend-module-github.yaml - ./backstage-plugin-catalog-backend-module-github.yaml - ./backstage-plugin-catalog-backend-module-github-org.yaml @@ -27,9 +29,11 @@ spec: - ./backstage-plugin-scaffolder-backend-module-azure.yaml - ./backstage-community-plugin-azure-devops-backend.yaml - ./backstage-community-plugin-azure-devops.yaml - - ./parfuemerie-douglas-scaffolder-backend-module-azure-repositorie.yaml + - ./parfuemerie-douglas-scaffolder-backend-module-azure-repositories.yaml - ./backstage-community-plugin-jenkins-backend.yaml - ./backstage-community-plugin-jenkins.yaml + - ./backstage-community-plugin-mcp-chat.yaml + - ./backstage-community-plugin-mcp-chat-backend.yaml - ./backstage-plugin-notifications.yaml - ./backstage-plugin-notifications-backend.yaml - ./backstage-plugin-notifications-backend-module-email.yaml @@ -37,6 +41,7 @@ spec: - ./backstage-plugin-signals.yaml - ./backstage-community-plugin-sonarqube-backend.yaml - ./backstage-community-plugin-sonarqube.yaml + # https://issues.redhat.com/browse/RHDHPLAN-265 - OCM is deprecated in 1.8; will be removed in 1.10 - ./backstage-community-plugin-ocm-backend.yaml - ./backstage-community-plugin-ocm.yaml - ./red-hat-developer-hub-backstage-plugin-bulk-import-backend.yaml @@ -56,6 +61,8 @@ spec: - ./backstage-community-plugin-scaffolder-backend-module-quay.yaml - ./backstage-community-plugin-scaffolder-backend-module-regex.yaml - ./backstage-community-plugin-rbac.yaml + - ./backstage-community-plugin-servicenow.yaml + - ./backstage-community-plugin-servicenow-backend.yaml - ./backstage-community-plugin-scaffolder-backend-module-servicenow.yaml - ./backstage-community-plugin-scaffolder-backend-module-sonarqube.yaml - ./backstage-community-plugin-3scale-backend.yaml @@ -75,6 +82,8 @@ spec: - ./backstage-community-plugin-lighthouse.yaml - ./backstage-community-plugin-tech-radar.yaml - ./backstage-community-plugin-tech-radar-backend.yaml + - ./backstage-community-plugin-todo-backend.yaml + - ./backstage-community-plugin-todo.yaml - ./backstage-community-plugin-analytics-provider-segment.yaml - ./backstage-community-plugin-catalog-backend-module-scaffolder-re.yaml - ./backstage-plugin-catalog-backend-module-msgraph.yaml @@ -86,8 +95,22 @@ spec: - ./redhat-backstage-plugin-orchestrator-backend.yaml - ./redhat-backstage-plugin-orchestrator.yaml - ./redhat-backstage-plugin-scaffolder-backend-module-orchestrator.yaml + - ./redhat-backstage-plugin-orchestrator-form-widgets.yaml - ./dynatrace-backstage-plugin-dql.yaml - ./dynatrace-backstage-plugin-dql-backend.yaml - ./rhdh-backstage-plugin-adoption-insights.yaml - ./rhdh-backstage-plugin-adoption-insights-backend.yaml - ./rhdh-backstage-plugin-analytics-module-adoption-insights.yaml + - ./rhdh-backstage-plugin-quickstart.yaml + - ./rhdh-backstage-plugin-scorecard-backend-module-github.yaml + - ./rhdh-backstage-plugin-scorecard-backend-module-jira.yaml + - ./rhdh-backstage-plugin-scorecard-backend.yaml + - ./rhdh-backstage-plugin-scorecard.yaml + - ./red-hat-developer-hub-backstage-plugin-lightspeed.yaml + - ./red-hat-developer-hub-backstage-plugin-lightspeed-backend.yaml + - ./apic-backstage-plugin.yaml + - ./backstage-plugin-mcp-actions-backend.yaml + - ./red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool.yaml + - ./red-hat-developer-hub-backstage-plugin-techdocs-mcp-tool.yaml + - ./backstage-plugin-catalog-backend-module-model-catalog.yaml + - ./backstage-plugin-catalog-techdoc-url-reader-backend.yaml diff --git a/catalog-entities/marketplace/packages/apic-backstage-plugin.yaml b/catalog-entities/marketplace/packages/apic-backstage-plugin.yaml new file mode 100644 index 0000000000..252f83c68f --- /dev/null +++ b/catalog-entities/marketplace/packages/apic-backstage-plugin.yaml @@ -0,0 +1,46 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: apic-backstage + namespace: apiconnect + title: "APIC" + links: + - url: https://github.com/ibm-apiconnect/backstage/blob/main/plugins/apic-backstage/README.md + title: Plugin Overview (README) + - title: Source Code + url: https://github.com/ibm-apiconnect/backstage/tree/main/plugins/apic-backstage + annotations: + backstage.io/source-location: url + https://github.com/ibm-apiconnect/backstage + tags: [] +spec: + packageName: "apic-backstage" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/apic-backstage:bs_1.42.5__1.0.0!apic-backstage + version: 1.0.0 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: IBM + support: production + lifecycle: active + partOf: + - apic-backstage + + appConfigExamples: + - title: Plugin configuration + content: + ibm: + schedule: '* * * * *' + apic: + - name: apic-instance-1 + url: ${APIC_API_URL} + clientId: ${APIC_CLIENT_ID} + clientSecret: ${APIC_SECRET} + username: ${PORG_USERNAME} + password: ${PORG_PASSWORD} + identityProvider: 'default-idp-2' # Default Local User Registry + - name: apic-instance-2 + url: ${APIC_API_URL} + clientId: ${APIC_CLIENT_ID} + clientSecret: ${APIC_SECRET} + apiKey: ${APIC_API_KEY} # OIDC Registry diff --git a/catalog-entities/marketplace/packages/aws-amazon-ecs-plugin-for-backstage-backend.yaml b/catalog-entities/marketplace/packages/aws-amazon-ecs-plugin-for-backstage-backend.yaml new file mode 100644 index 0000000000..7ee41f2a02 --- /dev/null +++ b/catalog-entities/marketplace/packages/aws-amazon-ecs-plugin-for-backstage-backend.yaml @@ -0,0 +1,36 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: aws-amazon-ecs-plugin-for-backstage-backend + namespace: community + title: "@aws/amazon-ecs-plugin-for-backstage-backend" + links: + - url: https://github.com/awslabs/backstage-plugins-for-aws + title: Homepage + - url: https://github.com/awslabs/backstage-plugins-for-aws/issues + title: Bugs + - title: Source Code + url: https://github.com/awslabs/backstage-plugins-for-aws/tree/main/plugins/ecs/backend + annotations: + backstage.io/source-location: url:https://github.com/awslabs/backstage-plugins-for-aws/tree/main/plugins/ecs/backend + tags: [] +spec: + packageName: "@aws/amazon-ecs-plugin-for-backstage-backend" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/aws-amazon-ecs-plugin-for-backstage-backend:bs_1.42.5__0.8.0!aws-amazon-ecs-plugin-for-backstage-backend + version: 0.8.0 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: AWS + support: community + lifecycle: active + partOf: + - aws-ecs + appConfigExamples: + - title: AWS Credentials Configuration + content: | + # Backend plugin uses AWS SDK credential chain + # Configure via environment variables: + AWS_REGION: us-east-1 + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} diff --git a/catalog-entities/marketplace/packages/aws-amazon-ecs-plugin-for-backstage.yaml b/catalog-entities/marketplace/packages/aws-amazon-ecs-plugin-for-backstage.yaml new file mode 100644 index 0000000000..ce518f3189 --- /dev/null +++ b/catalog-entities/marketplace/packages/aws-amazon-ecs-plugin-for-backstage.yaml @@ -0,0 +1,54 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: aws-amazon-ecs-plugin-for-backstage + namespace: community + title: "@aws/amazon-ecs-plugin-for-backstage" + links: + - url: https://github.com/awslabs/backstage-plugins-for-aws + title: Homepage + - url: https://github.com/awslabs/backstage-plugins-for-aws/issues + title: Bugs + - title: Source Code + url: https://github.com/awslabs/backstage-plugins-for-aws/tree/main/plugins/ecs/frontend + annotations: + backstage.io/source-location: url:https://github.com/awslabs/backstage-plugins-for-aws/tree/main/plugins/ecs/frontend + tags: [] +spec: + packageName: "@aws/amazon-ecs-plugin-for-backstage" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/aws-amazon-ecs-plugin-for-backstage:bs_1.42.5__0.6.0!aws-amazon-ecs-plugin-for-backstage + version: 0.6.0 + backstage: + role: frontend-plugin + supportedVersions: 1.42.5 + author: AWS + support: community + lifecycle: active + partOf: + - aws-ecs + + appConfigExamples: + - title: Default configuration + content: + dynamicPlugins: + frontend: + aws.amazon-ecs-plugin-for-backstage: + # Entity tab for ECS services (main plugin functionality) + entityTabs: + - path: /amazon-ecs + title: Amazon ECS + mountPoint: entity.page.amazon-ecs + + # ECS services content in the entity tab + mountPoints: + - mountPoint: entity.page.amazon-ecs/cards + importName: EntityAmazonEcsServicesContent + config: + layout: + gridColumn: "1 / -1" + if: + anyOf: + # Show for entities with ECS service tags + - hasAnnotation: aws.amazon.com/amazon-ecs-service-tags + # Show for entities with specific ECS service ARN + - hasAnnotation: aws.amazon.com/amazon-ecs-service-arn diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-3scale-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-3scale-backend.yaml index 27a7bff74c..bb6edfa3b6 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-3scale-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-3scale-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-3scale-backend namespace: rhdh - title: "@backstage-community/plugin-3scale-backend" + title: "3Scale" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-3scale-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-3scale-backend-dynamic - version: 3.6.1 + version: 3.8.0 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-acr.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-acr.yaml index 0543597ed3..f778a66fb7 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-acr.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-acr.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-acr namespace: rhdh - title: "@backstage-community/plugin-acr" + title: "ACR" links: - url: https://red.ht/rhdh title: Homepage @@ -18,15 +18,15 @@ metadata: spec: packageName: "@backstage-community/plugin-acr" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-acr - version: 1.15.1 + version: 1.17.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active partOf: - - acr + - azure-container-registry appConfigExamples: - title: Default configuration content: diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-analytics-provider-segment.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-analytics-provider-segment.yaml index fb7350245e..fa39ec5950 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-analytics-provider-segment.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-analytics-provider-segment.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-analytics-provider-segment namespace: rhdh - title: "@backstage-community/plugin-analytics-provider-segment" + title: "Analytics Provider Segment" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-analytics-provider-segment" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment - version: 1.16.0 + version: 1.19.1 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active @@ -47,3 +47,5 @@ spec: writeKey: ${SEGMENT_WRITE_KEY} maskIP: true testMode: ${SEGMENT_TEST_MODE} + appVersion: ${RHDH_VERSION} + backstageVersion: ${BACKSTAGE_VERSION} diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-azure-devops-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-azure-devops-backend.yaml index 5edb0a751a..b35786e619 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-azure-devops-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-azure-devops-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-azure-devops-backend namespace: rhdh - title: "@backstage-community/plugin-azure-devops-backend" + title: "Azure DevOps Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-azure-devops-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-azure-devops-backend-dynamic - version: 0.17.1 + version: 0.19.0 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-azure-devops.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-azure-devops.yaml index a5cef444b5..f54e40dfd7 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-azure-devops.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-azure-devops.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-azure-devops namespace: rhdh - title: "@backstage-community/plugin-azure-devops" + title: "Azure DevOps Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-azure-devops" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-azure-devops - version: 0.16.1 + version: 0.18.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-keycloak.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-keycloak.yaml index 18f97ea0ce..8683b1e6df 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-keycloak.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-keycloak.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-catalog-backend-module-keycloak namespace: rhdh - title: "@backstage-community/plugin-catalog-backend-module-keycloak" + title: "Catalog Backend Module Keycloak" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage-community/plugin-catalog-backend-module-keycloak" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-keycloak-dynamic - version: 3.12.1 + version: 3.14.2 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-pingidentity.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-pingidentity.yaml index 1150fa3579..70a1eef549 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-pingidentity.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-pingidentity.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-catalog-backend-module-pingidentity namespace: rhdh - title: "@backstage-community/plugin-catalog-backend-module-pingidentity" + title: "Catalog Backend Module PingIdentity" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage-community/plugin-catalog-backend-module-pingidentity" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic - version: 0.5.0 + version: 0.7.0 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-scaffolder-re.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-scaffolder-re.yaml index 7d28d90900..d2918ef3da 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-scaffolder-re.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-catalog-backend-module-scaffolder-re.yaml @@ -3,8 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-catalog-backend-module-scaffolder-re namespace: rhdh - title: "@backstage-community/plugin-catalog-backend-module-scaffolder-relation-\ - processor" + title: "Catalog Backend Module Scaffolder Re" links: - url: https://red.ht/rhdh title: Homepage @@ -21,10 +20,10 @@ spec: packageName: "@backstage-community/plugin-catalog-backend-module-scaffolder-rel\ ation-processor" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic - version: 2.5.0 + version: 2.8.0 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-dynatrace.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-dynatrace.yaml index aed44872d7..1f813d9c2e 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-dynatrace.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-dynatrace.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-dynatrace namespace: rhdh - title: "@backstage-community/plugin-dynatrace" + title: "Dynatrace" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-dynatrace" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-dynatrace - version: 10.6.0 + version: 10.8.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-github-actions.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-github-actions.yaml index 81fd0cfcb8..8a16352fc9 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-github-actions.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-github-actions.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-github-actions namespace: rhdh - title: "@backstage-community/plugin-github-actions" + title: "GitHub Actions" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-github-actions" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-github-actions - version: 0.11.1 + version: 0.14.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-github-issues.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-github-issues.yaml index 7679e1a7d4..c41c2f91c7 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-github-issues.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-github-issues.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-github-issues namespace: rhdh - title: "@backstage-community/plugin-github-issues" + title: "GitHub Issues" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-github-issues" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-github-issues - version: 0.10.0 + version: 0.13.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-jenkins-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-jenkins-backend.yaml index cb6cf954ca..f0734ff600 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-jenkins-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-jenkins-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-jenkins-backend namespace: rhdh - title: "@backstage-community/plugin-jenkins-backend" + title: "Jenkins Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-jenkins-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-jenkins-backend-dynamic - version: 0.15.0 + version: 0.17.0 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-jenkins.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-jenkins.yaml index 8c6634ca2e..4134697ac0 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-jenkins.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-jenkins.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-jenkins namespace: rhdh - title: "@backstage-community/plugin-jenkins" + title: "Jenkins Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-jenkins" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-jenkins - version: 0.20.0 + version: 0.22.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-jfrog-artifactory.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-jfrog-artifactory.yaml index bd5a82d1ad..db3de76c36 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-jfrog-artifactory.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-jfrog-artifactory.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-jfrog-artifactory namespace: rhdh - title: "@backstage-community/plugin-jfrog-artifactory" + title: "JFrog Artifactory" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-jfrog-artifactory" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-jfrog-artifactory - version: 1.15.3 + version: 1.18.2 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-lighthouse.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-lighthouse.yaml index 612e6a8b1c..79fb9c6c51 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-lighthouse.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-lighthouse.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-lighthouse namespace: rhdh - title: "@backstage-community/plugin-lighthouse" + title: "Lighthouse" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-lighthouse" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-lighthouse - version: 0.10.0 + version: 0.12.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-mcp-chat-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-mcp-chat-backend.yaml new file mode 100644 index 0000000000..ad955cc15b --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-mcp-chat-backend.yaml @@ -0,0 +1,52 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/packages.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-community-plugin-mcp-chat-backend + namespace: rhdh + title: "@backstage-community/plugin-mcp-chat-backend" + links: + - url: https://github.com/backstage/community-plugins/blob/main/workspaces/mcp-chat/plugins/mcp-chat-backend/README.md + title: Plugin Overview (README) + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend + annotations: + backstage.io/source-location: url:https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend + tags: [] +spec: + packageName: "@backstage-community/plugin-mcp-chat-backend" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-mcp-chat-backend:next__0.1.0!backstage-community-plugin-mcp-chat-backend + version: 0.1.0 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: Backstage Community + support: community + lifecycle: active + partOf: + - mcp-chat + appConfigExamples: + - title: Default configuration with Gemini provider + content: + mcpChat: + # Configure AI providers + providers: + - id: gemini + token: ${GEMINI_API_KEY} + model: gemini-2.5-flash + # Optional: Configure MCP servers + mcpServers: + - id: github-server + name: Github Server + url: 'https://api.githubcopilot.com/mcp' + headers: + Authorization: 'Bearer ${GITHUB_TOKEN}' + # Optional: Customize the system prompt + systemPrompt: "You are a helpful assistant. When using tools, provide a clear, readable summary of the results rather than showing raw data. Focus on answering the user's question with the information gathered." + # Configure quick prompts + quickPrompts: + - title: 'List all repositories' + description: 'List all repositories in a given organization' + prompt: 'List all repositories in the organization Backstage' + category: GitHub + diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-mcp-chat.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-mcp-chat.yaml new file mode 100644 index 0000000000..409bcd3a00 --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-mcp-chat.yaml @@ -0,0 +1,39 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/packages.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-community-plugin-mcp-chat + namespace: rhdh + title: "@backstage-community/plugin-mcp-chat" + links: + - url: https://github.com/backstage/community-plugins/blob/main/workspaces/mcp-chat/plugins/mcp-chat/README.md + title: Plugin Overview (README) + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat + annotations: + backstage.io/source-location: url:https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat + tags: [] +spec: + packageName: "@backstage-community/plugin-mcp-chat" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-mcp-chat:next__0.1.0!backstage-community-plugin-mcp-chat + version: 0.1.0 + backstage: + role: frontend-plugin + supportedVersions: 1.42.5 + author: Backstage Community + support: community + lifecycle: active + partOf: + - mcp-chat + appConfigExamples: + - title: Default configuration + content: + dynamicPlugins: + frontend: + backstage-community.plugin-mcp-chat: + dynamicRoutes: + - path: /mcp-chat + importName: McpChatPage + menuItem: + icon: MCPChatIcon + text: MCP Chat diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-nexus-repository-manager.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-nexus-repository-manager.yaml index 4610ba9e81..55ddb55d4a 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-nexus-repository-manager.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-nexus-repository-manager.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-nexus-repository-manager namespace: rhdh - title: "@backstage-community/plugin-nexus-repository-manager" + title: "Nexus Repository Manager" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-nexus-repository-manager" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-nexus-repository-manager - version: 1.14.1 + version: 1.16.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-ocm-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-ocm-backend.yaml index 924544a100..62b4ce8b8f 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-ocm-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-ocm-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-ocm-backend namespace: rhdh - title: "@backstage-community/plugin-ocm-backend" + title: "OCM Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,13 +18,14 @@ metadata: spec: packageName: "@backstage-community/plugin-ocm-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-ocm-backend-dynamic - version: 5.7.0 + version: 5.9.1 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production - lifecycle: active + # https://issues.redhat.com/browse/RHDHPLAN-265 - OCM is deprecated in 1.8; will be removed in 1.10 + lifecycle: deprecated partOf: - openshift-cluster-manager appConfigExamples: diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-ocm.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-ocm.yaml index 09bbfe3cd0..7a16009582 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-ocm.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-ocm.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-ocm namespace: rhdh - title: "@backstage-community/plugin-ocm" + title: "OCM Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,13 +18,14 @@ metadata: spec: packageName: "@backstage-community/plugin-ocm" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-ocm - version: 5.6.0 + version: 5.8.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production - lifecycle: active + # https://issues.redhat.com/browse/RHDHPLAN-265 - OCM is deprecated in 1.8; will be removed in 1.10 + lifecycle: deprecated partOf: - openshift-cluster-manager appConfigExamples: diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-quay.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-quay.yaml index 9d757955aa..425c87b681 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-quay.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-quay.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-quay namespace: rhdh - title: "@backstage-community/plugin-quay" + title: "Quay" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-quay" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-quay - version: 1.21.1 + version: 1.24.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-rbac.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-rbac.yaml index 0d3d814e83..3f3247ebfd 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-rbac.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-rbac.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-rbac namespace: rhdh - title: "@backstage-community/plugin-rbac" + title: "RBAC" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-rbac" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-rbac - version: 1.42.0 + version: 1.45.1 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-redhat-argocd.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-redhat-argocd.yaml index d3367cb3be..f00b442b32 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-redhat-argocd.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-redhat-argocd.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-redhat-argocd namespace: rhdh - title: "@backstage-community/plugin-redhat-argocd" + title: "Red Hat ArgoCD" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-redhat-argocd" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-redhat-argocd - version: 1.21.2 + version: 2.0.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-kubernetes.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-kubernetes.yaml index c350cfab83..67d4e4fc52 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-kubernetes.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-kubernetes.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-scaffolder-backend-module-kubernetes namespace: rhdh - title: "@backstage-community/plugin-scaffolder-backend-module-kubernetes" + title: "Scaffolder Backend Module Kubernetes" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage-community/plugin-scaffolder-backend-module-kubernetes" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-kubernetes-dynamic - version: 2.8.1 + version: 2.10.1 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-quay.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-quay.yaml index b33d881f8f..42101132dc 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-quay.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-quay.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-scaffolder-backend-module-quay namespace: rhdh - title: "@backstage-community/plugin-scaffolder-backend-module-quay" + title: "Scaffolder Backend Module Quay" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage-community/plugin-scaffolder-backend-module-quay" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-quay-dynamic - version: 2.9.1 + version: 2.11.0 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-regex.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-regex.yaml index aa4bb53302..22bcba0cd6 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-regex.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-regex.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-scaffolder-backend-module-regex namespace: rhdh - title: "@backstage-community/plugin-scaffolder-backend-module-regex" + title: "Scaffolder Backend Module Regex" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage-community/plugin-scaffolder-backend-module-regex" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-regex-dynamic - version: 2.7.0 + version: 2.8.0 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-servicenow.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-servicenow.yaml index 0975673473..bc9764bd06 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-servicenow.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-servicenow.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-scaffolder-backend-module-servicenow namespace: rhdh - title: "@backstage-community/plugin-scaffolder-backend-module-servicenow" + title: "Scaffolder Backend Module ServiceNow" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage-community/plugin-scaffolder-backend-module-servicenow" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic - version: 2.7.0 + version: 2.8.1 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-sonarqube.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-sonarqube.yaml index c6897f294e..c4b2eb2e7a 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-sonarqube.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-scaffolder-backend-module-sonarqube.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-scaffolder-backend-module-sonarqube namespace: rhdh - title: "@backstage-community/plugin-scaffolder-backend-module-sonarqube" + title: "Scaffolder Backend Module SonarQube" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage-community/plugin-scaffolder-backend-module-sonarqube" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic - version: 2.7.1 + version: 2.8.0 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-servicenow-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-servicenow-backend.yaml new file mode 100644 index 0000000000..37db7be783 --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-servicenow-backend.yaml @@ -0,0 +1,37 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-community-plugin-servicenow-backend + namespace: rhdh + title: "ServiceNow Backend" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHBUGS + title: Bugs + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/servicenow/plugins/servicenow-backend + annotations: + backstage.io/source-location: url + https://github.com/backstage/community-plugins/tree/main/workspaces/servicenow/plugins/servicenow-backend + tags: [] +spec: + packageName: "@backstage-community/plugin-servicenow-backend" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-servicenow-backend:bs_1.39.1__1.0.0!backstage-community-plugin-servicenow-backend + version: 1.0.0 + backstage: + role: backend-plugin + supportedVersions: 1.39.1 + author: Red Hat + support: dev-preview + lifecycle: active + partOf: + - servicenow + appConfigExamples: + - title: Default configuration + content: + servicenow: + instanceUrl: ${SERVICENOW_BASE_URL} + basicAuth: + username: ${SERVICENOW_USERNAME} + password: ${SERVICENOW_PASSWORD} diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-servicenow.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-servicenow.yaml new file mode 100644 index 0000000000..d6ea7eaa24 --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-servicenow.yaml @@ -0,0 +1,62 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-community-plugin-servicenow + namespace: rhdh + title: "ServiceNow Frontend" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHBUGS + title: Bugs + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/servicenow/plugins/servicenow + annotations: + backstage.io/source-location: url + https://github.com/backstage/community-plugins/tree/main/workspaces/servicenow/plugins/servicenow + tags: [] +spec: + packageName: "@backstage-community/plugin-servicenow" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-servicenow:bs_1.39.1__1.0.0!backstage-community-plugin-servicenow + version: 1.0.0 + backstage: + role: frontend-plugin + supportedVersions: 1.39.1 + author: Red Hat + support: dev-preview + lifecycle: active + partOf: + - servicenow + appConfigExamples: + - title: Default configuration + content: + dynamicPlugins: + frontend: + backstage-community.plugin-servicenow: + entityTabs: + - path: /servicenow + title: ServiceNow + mountPoint: entity.page.servicenow + - path: /my-servicenow + title: My ServiceNow tickets + mountPoint: entity.page.my-servicenow + mountPoints: + - mountPoint: entity.page.servicenow/cards + importName: ServicenowPage + config: + layout: + gridColumn: 1 / -1 + height: 75vh + if: + anyOf: + - hasAnnotation: servicenow.com/entity-id + - mountPoint: entity.page.my-servicenow/cards + importName: ServicenowPage + config: + layout: + gridColumn: 1 / -1 + height: 75vh + if: + allOf: + - isKind: user + - isMyProfile diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-sonarqube-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-sonarqube-backend.yaml index af04b7e59b..5a676babcd 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-sonarqube-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-sonarqube-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-sonarqube-backend namespace: rhdh - title: "@backstage-community/plugin-sonarqube-backend" + title: "SonarQube Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-sonarqube-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-sonarqube-backend-dynamic - version: 0.9.2 + version: 0.12.0 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-sonarqube.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-sonarqube.yaml index 3a2a9e7b2c..15674343cb 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-sonarqube.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-sonarqube.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-sonarqube namespace: rhdh - title: "@backstage-community/plugin-sonarqube" + title: "SonarQube Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-sonarqube" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-sonarqube - version: 0.13.0 + version: 0.18.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-tech-radar-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-tech-radar-backend.yaml index d48407c9ea..bfb494bec3 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-tech-radar-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-tech-radar-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-tech-radar-backend namespace: rhdh - title: "@backstage-community/plugin-tech-radar-backend" + title: "Tech Radar Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-tech-radar-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-tech-radar-backend-dynamic - version: 1.6.0 + version: 1.10.0 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-tech-radar.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-tech-radar.yaml index 0b7c65a55c..b0e90de5cc 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-tech-radar.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-tech-radar.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-tech-radar namespace: rhdh - title: "@backstage-community/plugin-tech-radar" + title: "Tech Radar Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-tech-radar" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-tech-radar - version: 1.7.0 + version: 1.11.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-tekton.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-tekton.yaml index 860f9bf052..d1212c099c 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-tekton.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-tekton.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-tekton namespace: rhdh - title: "@backstage-community/plugin-tekton" + title: "Tekton" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-tekton" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-tekton - version: 3.26.2 + version: 3.29.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-todo-backend.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-todo-backend.yaml new file mode 100644 index 0000000000..7a020bf28a --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-todo-backend.yaml @@ -0,0 +1,27 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/packages.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-community-plugin-todo-backend + namespace: rhdh + title: "@backstage-community/plugin-todo-backend" + links: + - url: https://github.com/backstage/community-plugins/blob/main/workspaces/todo/plugins/todo-backend/README.md + title: Plugin Overview (README) + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/todo/plugins/todo-backend + annotations: + backstage.io/source-location: url:https://github.com/backstage/community-plugins/tree/main/workspaces/todo + tags: [] +spec: + packageName: "@backstage-community/plugin-todo-backend" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-todo-backend:bs_1.42.5__0.13.0!backstage-community-plugin-todo-backend + version: 0.13.0 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: Backstage Community + support: community + lifecycle: active + partOf: + - todo diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-todo.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-todo.yaml new file mode 100644 index 0000000000..54b4727ff3 --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-todo.yaml @@ -0,0 +1,39 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/packages.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-community-plugin-todo + namespace: rhdh + title: "@backstage-community/plugin-todo" + links: + - url: https://github.com/backstage/community-plugins/blob/main/workspaces/todo/plugins/todo/README.md + title: Plugin Overview (README) + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/todo/plugins/todo + annotations: + backstage.io/source-location: url:https://github.com/backstage/community-plugins/tree/main/workspaces/todo + tags: [] +spec: + packageName: "@backstage-community/plugin-todo" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-todo:bs_1.42.5__0.12.0!backstage-community-plugin-todo + version: 0.12.0 + backstage: + role: frontend-plugin + supportedVersions: 1.42.5 + author: Backstage Community + support: community + lifecycle: active + partOf: + - todo + appConfigExamples: + - title: Default configuration + content: + dynamicPlugins: + frontend: + backstage-community.plugin-todo: + mountPoints: + - mountPoint: entity.page.overview/cards + importName: EntityTodoContent + config: + layout: + gridColumn: 1 / -1 diff --git a/catalog-entities/marketplace/packages/backstage-community-plugin-topology.yaml b/catalog-entities/marketplace/packages/backstage-community-plugin-topology.yaml index efa486e435..1cf9109fe1 100644 --- a/catalog-entities/marketplace/packages/backstage-community-plugin-topology.yaml +++ b/catalog-entities/marketplace/packages/backstage-community-plugin-topology.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-community-plugin-topology namespace: rhdh - title: "@backstage-community/plugin-topology" + title: "Topology" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage-community/plugin-topology" dynamicArtifact: ./dynamic-plugins/dist/backstage-community-plugin-topology - version: 2.2.2 + version: 2.7.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-bitbucket-cloud.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-bitbucket-cloud.yaml index 5cb2107a6d..c0d42852ee 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-bitbucket-cloud.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-bitbucket-cloud.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-catalog-backend-module-bitbucket-cloud namespace: rhdh - title: "@backstage/plugin-catalog-backend-module-bitbucket-cloud" + title: "Catalog Backend Module Bitbucket Cloud" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-catalog-backend-module-bitbucket-cloud" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic - version: 0.4.8 + version: 0.5.2 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-bitbucket-server.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-bitbucket-server.yaml index 9f5d9c44ed..86a203a387 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-bitbucket-server.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-bitbucket-server.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-catalog-backend-module-bitbucket-server namespace: rhdh - title: "@backstage/plugin-catalog-backend-module-bitbucket-server" + title: "Catalog Backend Module Bitbucket Server" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-catalog-backend-module-bitbucket-server" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic - version: 0.4.1 + version: 0.5.2 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-github-org.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-github-org.yaml index 3dd1a460b7..29cb292221 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-github-org.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-github-org.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-catalog-backend-module-github-org namespace: rhdh - title: "@backstage/plugin-catalog-backend-module-github-org" + title: "Catalog Backend Module GitHub Organization" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-catalog-backend-module-github-org" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org-dynamic - version: 0.3.10 + version: 0.3.13 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-github.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-github.yaml index 5c475f2414..cddbeac915 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-github.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-github.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-catalog-backend-module-github namespace: rhdh - title: "@backstage/plugin-catalog-backend-module-github" + title: "Catalog Backend Module GitHub" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-catalog-backend-module-github" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic - version: 0.9.0 + version: 0.10.2 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-gitlab-org.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-gitlab-org.yaml index 860503007a..72cff21c25 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-gitlab-org.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-gitlab-org.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-catalog-backend-module-gitlab-org namespace: rhdh - title: "@backstage/plugin-catalog-backend-module-gitlab-org" + title: "Catalog Backend Module GitLab Organization" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-catalog-backend-module-gitlab-org" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-gitlab-org-dynamic - version: 0.2.9 + version: 0.2.12 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-gitlab.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-gitlab.yaml index 71ec19f04a..f2730fd2a1 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-gitlab.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-gitlab.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-catalog-backend-module-gitlab namespace: rhdh - title: "@backstage/plugin-catalog-backend-module-gitlab" + title: "Catalog Backend Module GitLab" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-catalog-backend-module-gitlab" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-gitlab-dynamic - version: 0.6.6 + version: 0.7.2 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-ldap.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-ldap.yaml index 13b713c62b..86bbf3ff33 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-ldap.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-ldap.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-catalog-backend-module-ldap namespace: rhdh - title: "@backstage/plugin-catalog-backend-module-ldap" + title: "Catalog Backend Module LDAP" links: - url: https://red.ht/rhdh title: Homepage @@ -19,12 +19,12 @@ metadata: spec: packageName: "@backstage/plugin-catalog-backend-module-ldap" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-ldap-dynamic - version: 0.11.5 + version: 0.11.8 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat - support: tech-preview + support: production lifecycle: active partOf: - ldap-catalog-integration diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-model-catalog.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-model-catalog.yaml new file mode 100644 index 0000000000..8eeddd40a1 --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-model-catalog.yaml @@ -0,0 +1,37 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-plugin-catalog-backend-module-model-catalog + namespace: rhdh + title: "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-model-catalog" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHBUGS + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog + tags: [] +spec: + packageName: "@backstage/catalog-backend-module-model-catalog" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog:next__0.6.0!red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog + version: 0.6.0 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: Backstage + support: dev-preview + lifecycle: active + partOf: + - ai-integrations + appConfigExamples: + - title: Default configuration + content: + catalog: + providers: + modelCatalog: + developement: + baseUrl: http://localhost:9090 diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-msgraph.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-msgraph.yaml index 398b9cd4e7..9fe0c6a877 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-msgraph.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-backend-module-msgraph.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-catalog-backend-module-msgraph namespace: rhdh - title: "@backstage/plugin-catalog-backend-module-msgraph" + title: "Catalog Backend Module MS Graph" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-catalog-backend-module-msgraph" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-msgraph-dynamic - version: 0.7.0 + version: 0.7.3 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-catalog-techdoc-url-reader-backend.yaml b/catalog-entities/marketplace/packages/backstage-plugin-catalog-techdoc-url-reader-backend.yaml new file mode 100644 index 0000000000..fee6628277 --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-plugin-catalog-techdoc-url-reader-backend.yaml @@ -0,0 +1,37 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-plugin-catalog-techdoc-url-reader-backend + namespace: rhdh + title: "@red-hat-developer-hub/backstage-plugin-catalog-techdoc-url-reader-backend" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHBUGS + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/ai-integrations/plugins/catalog-techdoc-url-reader-backend + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/ai-integrations/plugins/catalog-techdoc-url-reader-backend + tags: [] +spec: + packageName: "@backstage/catalog-techdoc-url-reader-backend" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-backend:next__0.3.0!red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-backend + version: 0.3.0 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: Backstage + support: dev-preview + lifecycle: active + partOf: + - ai-integrations + appConfigExamples: + - title: Default configuration + content: + catalog: + providers: + modelCatalog: + developement: + baseUrl: http://localhost:9090 diff --git a/catalog-entities/marketplace/packages/backstage-plugin-kubernetes-backend.yaml b/catalog-entities/marketplace/packages/backstage-plugin-kubernetes-backend.yaml index fc3c8102ce..42241d6f57 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-kubernetes-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-kubernetes-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-kubernetes-backend namespace: rhdh - title: "@backstage/plugin-kubernetes-backend" + title: "Kubernetes Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-kubernetes-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-kubernetes-backend-dynamic - version: 0.19.6 + version: 0.20.1 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-kubernetes.yaml b/catalog-entities/marketplace/packages/backstage-plugin-kubernetes.yaml index 4f08c6e2fc..f813e31c5f 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-kubernetes.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-kubernetes.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-kubernetes namespace: rhdh - title: "@backstage/plugin-kubernetes" + title: "Kubernetes Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-kubernetes" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-kubernetes - version: 0.12.7 + version: 0.12.10 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-mcp-actions-backend.yaml b/catalog-entities/marketplace/packages/backstage-plugin-mcp-actions-backend.yaml new file mode 100644 index 0000000000..c40fb62ab2 --- /dev/null +++ b/catalog-entities/marketplace/packages/backstage-plugin-mcp-actions-backend.yaml @@ -0,0 +1,39 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: backstage-plugin-mcp-actions-backend + namespace: rhdh + title: "@backstage/plugin-mcp-actions-backend" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHBUGS + title: Bugs + - title: Source Code + url: https://github.com/backstage/backstage/tree/master/plugins/mcp-actions-backend + annotations: + backstage.io/source-location: url + https://github.com/backstage/backstage/tree/master/plugins/mcp-actions-backend + tags: [] +spec: + packageName: "@backstage/plugin-mcp-actions-backend" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-plugin-mcp-actions-backend:bs_1.42.5__0.1.2!backstage-plugin-mcp-actions-backend + version: 0.1.2 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: Backstage + support: dev-preview + lifecycle: active + partOf: + - mcp-tools + appConfigExamples: + - title: Default configuration + content: + backend: + auth: + externalAccess: + - type: static + options: + token: ${MCP_TOKEN} + subject: mcp-clients diff --git a/catalog-entities/marketplace/packages/backstage-plugin-notifications-backend-module-email.yaml b/catalog-entities/marketplace/packages/backstage-plugin-notifications-backend-module-email.yaml index 27c1b7aa25..f284ebee0c 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-notifications-backend-module-email.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-notifications-backend-module-email.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-notifications-backend-module-email namespace: rhdh - title: "@backstage/plugin-notifications-backend-module-email" + title: "Notifications Backend Module Email" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-notifications-backend-module-email" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-notifications-backend-module-email-dynamic - version: 0.3.9 + version: 0.3.12 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-notifications-backend.yaml b/catalog-entities/marketplace/packages/backstage-plugin-notifications-backend.yaml index 9cbfd12081..b0fb940776 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-notifications-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-notifications-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-notifications-backend namespace: rhdh - title: "@backstage/plugin-notifications-backend" + title: "Notifications Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-notifications-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-notifications-backend-dynamic - version: 0.5.6 + version: 0.5.9 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-notifications.yaml b/catalog-entities/marketplace/packages/backstage-plugin-notifications.yaml index 69ea08a44c..43f85c79df 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-notifications.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-notifications.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-notifications namespace: rhdh - title: "@backstage/plugin-notifications" + title: "Notifications Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-notifications" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-notifications - version: 0.5.5 + version: 0.5.9 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-azure.yaml b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-azure.yaml index 56d23f3665..21d560c98d 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-azure.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-azure.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-scaffolder-backend-module-azure namespace: rhdh - title: "@backstage/plugin-scaffolder-backend-module-azure" + title: "Scaffolder Backend Module Azure" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-scaffolder-backend-module-azure" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-azure-dynamic - version: 0.2.9 + version: 0.2.12 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-bitbucket-cloud.yaml b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-bitbucket-cloud.yaml index f90c03628a..ab24dd9301 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-bitbucket-cloud.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-bitbucket-cloud.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-scaffolder-backend-module-bitbucket-cloud namespace: rhdh - title: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud" + title: "Scaffolder Backend Module Bitbucket Cloud" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic - version: 0.2.9 + version: 0.2.12 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-bitbucket-server.yaml b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-bitbucket-server.yaml index 51f5408a4a..6006da9a23 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-bitbucket-server.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-bitbucket-server.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-scaffolder-backend-module-bitbucket-server namespace: rhdh - title: "@backstage/plugin-scaffolder-backend-module-bitbucket-server" + title: "Scaffolder Backend Module Bitbucket Server" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-scaffolder-backend-module-bitbucket-server" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic - version: 0.2.9 + version: 0.2.12 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-gerrit.yaml b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-gerrit.yaml index 21cc2fa575..7e1d23b95e 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-gerrit.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-gerrit.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-scaffolder-backend-module-gerrit namespace: rhdh - title: "@backstage/plugin-scaffolder-backend-module-gerrit" + title: "Scaffolder Backend Module Gerrit" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-scaffolder-backend-module-gerrit" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-gerrit-dynamic - version: 0.2.9 + version: 0.2.12 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-github.yaml b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-github.yaml index 944c9c6e6e..a7a397ecc9 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-github.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-github.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-scaffolder-backend-module-github namespace: rhdh - title: "@backstage/plugin-scaffolder-backend-module-github" + title: "Scaffolder Backend Module GitHub" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-scaffolder-backend-module-github" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-github-dynamic - version: 0.7.1 + version: 0.8.2 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-gitlab.yaml b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-gitlab.yaml index 38f9af1f62..20664c295c 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-gitlab.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-scaffolder-backend-module-gitlab.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-scaffolder-backend-module-gitlab namespace: rhdh - title: "@backstage/plugin-scaffolder-backend-module-gitlab" + title: "Scaffolder Backend Module GitLab" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@backstage/plugin-scaffolder-backend-module-gitlab" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-gitlab-dynamic - version: 0.9.1 + version: 0.9.4 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-signals-backend.yaml b/catalog-entities/marketplace/packages/backstage-plugin-signals-backend.yaml index 2b8e0d240b..afcf5668dd 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-signals-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-signals-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-signals-backend namespace: rhdh - title: "@backstage/plugin-signals-backend" + title: "Signals Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-signals-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-signals-backend-dynamic - version: 0.3.4 + version: 0.3.7 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-signals.yaml b/catalog-entities/marketplace/packages/backstage-plugin-signals.yaml index c98ad37871..c2146f71f4 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-signals.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-signals.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-signals namespace: rhdh - title: "@backstage/plugin-signals" + title: "Signals Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-signals" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-signals - version: 0.0.19 + version: 0.0.22 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-techdocs-backend.yaml b/catalog-entities/marketplace/packages/backstage-plugin-techdocs-backend.yaml index ec2cd8d684..2ec4c8c83d 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-techdocs-backend.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-techdocs-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-techdocs-backend namespace: rhdh - title: "@backstage/plugin-techdocs-backend" + title: "TechDocs Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-techdocs-backend" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-techdocs-backend-dynamic - version: 2.0.2 + version: 2.0.5 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/backstage-plugin-techdocs-module-addons-contrib.yaml b/catalog-entities/marketplace/packages/backstage-plugin-techdocs-module-addons-contrib.yaml index bafb723ee9..dcf982cb81 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-techdocs-module-addons-contrib.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-techdocs-module-addons-contrib.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-techdocs-module-addons-contrib namespace: rhdh - title: "@backstage/plugin-techdocs-module-addons-contrib" + title: "TechDocs Add-ons Contrib" links: - url: https://red.ht/rhdh title: Homepage @@ -18,15 +18,15 @@ metadata: spec: packageName: "@backstage/plugin-techdocs-module-addons-contrib" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-techdocs-module-addons-contrib - version: 1.1.24 + version: 1.1.27 backstage: role: frontend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active partOf: - contrib-techdocs-addons + - contrib-techdocs-addons appConfigExamples: - title: Default configuration content: diff --git a/catalog-entities/marketplace/packages/backstage-plugin-techdocs.yaml b/catalog-entities/marketplace/packages/backstage-plugin-techdocs.yaml index 83ebea70c6..87862ba86e 100644 --- a/catalog-entities/marketplace/packages/backstage-plugin-techdocs.yaml +++ b/catalog-entities/marketplace/packages/backstage-plugin-techdocs.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: backstage-plugin-techdocs namespace: rhdh - title: "@backstage/plugin-techdocs" + title: "TechDocs Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@backstage/plugin-techdocs" dynamicArtifact: ./dynamic-plugins/dist/backstage-plugin-techdocs - version: 1.12.6 + version: 1.14.1 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/dynatrace-backstage-plugin-dql-backend.yaml b/catalog-entities/marketplace/packages/dynatrace-backstage-plugin-dql-backend.yaml index e3b2bfe724..d24ceb41ea 100644 --- a/catalog-entities/marketplace/packages/dynatrace-backstage-plugin-dql-backend.yaml +++ b/catalog-entities/marketplace/packages/dynatrace-backstage-plugin-dql-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: dynatrace-backstage-plugin-dql-backend namespace: dynatrace - title: "@dynatrace/backstage-plugin-dql-backend" + title: "DQL Backend" links: - url: https://www.dynatrace.com/ title: Homepage @@ -17,11 +17,11 @@ metadata: tags: [] spec: packageName: "@dynatrace/backstage-plugin-dql-backend" - #dynamicArtifact: ./dynamic-plugins/dist/dynatrace-backstage-plugin-dql-backend - version: 2.1.5 + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/dynatrace-backstage-plugin-dql-backend:bs_1.42.5__2.3.0!dynatrace-backstage-plugin-dql-backend + version: 2.3.0 backstage: role: backend-plugin - supportedVersions: 1.35.1 + supportedVersions: 1.42.5 author: Dynatrace support: production lifecycle: active @@ -30,4 +30,11 @@ spec: appConfigExamples: - title: Default configuration content: - dynamicPlugins: + dynatrace: + environments: + - name: ${DYNATRACE_NAME} + url: ${DYNATRACE_URL} + tokenUrl: ${DYNATRACE_TOKEN_URL} + accountUrn: ${DYNATRACE_ACCOUNT_URN} + clientId: ${DYNATRACE_CLIENT_ID} + clientSecret: ${DYNATRACE_CLIENT_SECRET} diff --git a/catalog-entities/marketplace/packages/dynatrace-backstage-plugin-dql.yaml b/catalog-entities/marketplace/packages/dynatrace-backstage-plugin-dql.yaml index 4b60aeb77a..41bb5d1019 100644 --- a/catalog-entities/marketplace/packages/dynatrace-backstage-plugin-dql.yaml +++ b/catalog-entities/marketplace/packages/dynatrace-backstage-plugin-dql.yaml @@ -4,7 +4,7 @@ kind: Package metadata: name: dynatrace-backstage-plugin-dql namespace: dynatrace - title: "@dynatrace/backstage-plugin-dql" + title: "DQL Frontend" links: - url: https://www.dynatrace.com/ title: Homepage @@ -18,11 +18,11 @@ metadata: tags: [] spec: packageName: "@dynatrace/backstage-plugin-dql" - #dynamicArtifact: ./dynamic-plugins/dist/dynatrace-backstage-plugin-dql - version: 2.1.5 + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/dynatrace-backstage-plugin-dql:bs_1.42.5__2.3.0!dynatrace-backstage-plugin-dql + version: 2.3.0 backstage: role: frontend-plugin - supportedVersions: 1.35.1 + supportedVersions: 1.42.5 author: Dynatrace support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/immobiliarelabs-backstage-plugin-gitlab-backend.yaml b/catalog-entities/marketplace/packages/immobiliarelabs-backstage-plugin-gitlab-backend.yaml index 8fe5e72b16..f28b08ec25 100644 --- a/catalog-entities/marketplace/packages/immobiliarelabs-backstage-plugin-gitlab-backend.yaml +++ b/catalog-entities/marketplace/packages/immobiliarelabs-backstage-plugin-gitlab-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: immobiliarelabs-backstage-plugin-gitlab-backend namespace: rhdh - title: "@immobiliarelabs/backstage-plugin-gitlab-backend" + title: "GitLab Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@immobiliarelabs/backstage-plugin-gitlab-backend" dynamicArtifact: ./dynamic-plugins/dist/immobiliarelabs-backstage-plugin-gitlab-backend-dynamic - version: 6.12.0 + version: 6.13.0 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/immobiliarelabs-backstage-plugin-gitlab.yaml b/catalog-entities/marketplace/packages/immobiliarelabs-backstage-plugin-gitlab.yaml index e64cf42986..8389958758 100644 --- a/catalog-entities/marketplace/packages/immobiliarelabs-backstage-plugin-gitlab.yaml +++ b/catalog-entities/marketplace/packages/immobiliarelabs-backstage-plugin-gitlab.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: immobiliarelabs-backstage-plugin-gitlab namespace: rhdh - title: "@immobiliarelabs/backstage-plugin-gitlab" + title: "GitLab Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@immobiliarelabs/backstage-plugin-gitlab" dynamicArtifact: ./dynamic-plugins/dist/immobiliarelabs-backstage-plugin-gitlab - version: 6.12.0 + version: 6.13.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/pagerduty-backstage-plugin-backend.yaml b/catalog-entities/marketplace/packages/pagerduty-backstage-plugin-backend.yaml index 633798fd06..7aa7c079e2 100644 --- a/catalog-entities/marketplace/packages/pagerduty-backstage-plugin-backend.yaml +++ b/catalog-entities/marketplace/packages/pagerduty-backstage-plugin-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: pagerduty-backstage-plugin-backend namespace: rhdh - title: "@pagerduty/backstage-plugin-backend" + title: "PagerDuty Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@pagerduty/backstage-plugin-backend" dynamicArtifact: ./dynamic-plugins/dist/pagerduty-backstage-plugin-backend-dynamic - version: 0.9.6 + version: 0.9.11 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/pagerduty-backstage-plugin.yaml b/catalog-entities/marketplace/packages/pagerduty-backstage-plugin.yaml index f92fbf43ab..5055302bd5 100644 --- a/catalog-entities/marketplace/packages/pagerduty-backstage-plugin.yaml +++ b/catalog-entities/marketplace/packages/pagerduty-backstage-plugin.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: pagerduty-backstage-plugin namespace: rhdh - title: "@pagerduty/backstage-plugin" + title: "PagerDuty Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@pagerduty/backstage-plugin" dynamicArtifact: ./dynamic-plugins/dist/pagerduty-backstage-plugin - version: 0.15.5 + version: 0.16.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/parfuemerie-douglas-scaffolder-backend-module-azure-repositorie.yaml b/catalog-entities/marketplace/packages/parfuemerie-douglas-scaffolder-backend-module-azure-repositories.yaml similarity index 90% rename from catalog-entities/marketplace/packages/parfuemerie-douglas-scaffolder-backend-module-azure-repositorie.yaml rename to catalog-entities/marketplace/packages/parfuemerie-douglas-scaffolder-backend-module-azure-repositories.yaml index 8d583e3978..2d5e1a5d11 100644 --- a/catalog-entities/marketplace/packages/parfuemerie-douglas-scaffolder-backend-module-azure-repositorie.yaml +++ b/catalog-entities/marketplace/packages/parfuemerie-douglas-scaffolder-backend-module-azure-repositories.yaml @@ -1,9 +1,9 @@ apiVersion: extensions.backstage.io/v1alpha1 kind: Package metadata: - name: parfuemerie-douglas-scaffolder-backend-module-azure-repositorie + name: parfuemerie-douglas-scaffolder-backend-module-azure-repositories namespace: rhdh - title: "@parfuemerie-douglas/scaffolder-backend-module-azure-repositories" + title: "Scaffolder Backend Module Azure Repositories" links: - url: https://red.ht/rhdh title: Homepage @@ -22,7 +22,7 @@ spec: version: 0.3.0 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-bulk-import-backend.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-bulk-import-backend.yaml index f3cd236cff..8d61563947 100644 --- a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-bulk-import-backend.yaml +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-bulk-import-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: red-hat-developer-hub-backstage-plugin-bulk-import-backend namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-bulk-import-backend" + title: "Bulk Import Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,7 +18,7 @@ metadata: spec: packageName: "@red-hat-developer-hub/backstage-plugin-bulk-import-backend" dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic - version: 6.1.3 + version: 6.5.1 backstage: role: backend-plugin supportedVersions: 1.39.1 diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-bulk-import.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-bulk-import.yaml index 83f5617c5b..84628969dc 100644 --- a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-bulk-import.yaml +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-bulk-import.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: red-hat-developer-hub-backstage-plugin-bulk-import namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-bulk-import" + title: "Bulk Import Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,7 +18,7 @@ metadata: spec: packageName: "@red-hat-developer-hub/backstage-plugin-bulk-import" dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import - version: 1.13.3 + version: 1.18.1 backstage: role: frontend-plugin supportedVersions: 1.39.1 diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-catalog-backend-module-m.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-catalog-backend-module-m.yaml index 258b44944a..e61ce7b77f 100644 --- a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-catalog-backend-module-m.yaml +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-catalog-backend-module-m.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: red-hat-developer-hub-backstage-plugin-catalog-backend-module-m namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace" + title: "Catalog Backend Module M" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace" dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic - version: 0.3.3 + version: 0.7.1 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-dynamic-home-page.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-dynamic-home-page.yaml index fd806067f8..01d83a45da 100644 --- a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-dynamic-home-page.yaml +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-dynamic-home-page.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: red-hat-developer-hub-backstage-plugin-dynamic-home-page namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-dynamic-home-page" + title: "Dynamic Home Page" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@red-hat-developer-hub/backstage-plugin-dynamic-home-page" dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page - version: 1.5.0 + version: 1.9.2 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-global-floating-action-b.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-global-floating-action-b.yaml index ca4fe1075a..c799f19fcb 100644 --- a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-global-floating-action-b.yaml +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-global-floating-action-b.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: red-hat-developer-hub-backstage-plugin-global-floating-action-b namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-global-floating-action-button" + title: "Global Floating Action B" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@red-hat-developer-hub/backstage-plugin-global-floating-action-button" dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button - version: 1.2.0 + version: 1.5.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-global-header.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-global-header.yaml index 88c569515a..67735df34a 100644 --- a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-global-header.yaml +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-global-header.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: red-hat-developer-hub-backstage-plugin-global-header namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-global-header" + title: "Global Header" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@red-hat-developer-hub/backstage-plugin-global-header" dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header - version: 1.13.0 + version: 1.18.1 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active @@ -40,7 +40,7 @@ spec: default.main-menu-items: menuItems: default.create: - title: "" + title: "Global Header" red-hat-developer-hub.backstage-plugin-global-header: mountPoints: - mountPoint: application/header @@ -131,6 +131,7 @@ spec: priority: 90 props: title: My profile + type: myProfile icon: account - mountPoint: global.header/profile importName: LogoutButton diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-lightspeed-backend.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-lightspeed-backend.yaml new file mode 100644 index 0000000000..62225fbd02 --- /dev/null +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-lightspeed-backend.yaml @@ -0,0 +1,48 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: red-hat-developer-hub-backstage-plugin-lightspeed-backend + namespace: rhdh + title: "Lightspeed Backend" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHPAI + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/lightspeed/plugins/lightspeed-backend + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/lightspeed/plugins/lightspeed-backend + tags: [] +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-lightspeed-backend" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-lightspeed-backend:bs_1.39.1__0.5.7!red-hat-developer-hub-backstage-plugin-lightspeed-backend + version: 0.5.7 + backstage: + role: backend-plugin + supportedVersions: 1.39.1 + author: Red Hat + support: dev-preview + lifecycle: active + partOf: + - lightspeed + appConfigExamples: + - title: Default configuration + content: | + lightspeed: + # REQUIRED: Configure LLM servers with OpenAI API compatibility + servers: + - id: ${LIGHTSPEED_SERVER_ID} + url: ${LIGHTSPEED_SERVER_URL} + token: ${LIGHTSPEED_SERVER_TOKEN} + + # OPTIONAL: Enable/disable question validation (default: true) + # When enabled, restricts questions to RHDH-related topics for better security + questionValidation: true + + # OPTIONAL: Port for lightspeed service (default: 8080) + # servicePort: ${LIGHTSPEED_SERVICE_PORT} + + # OPTIONAL: Override default RHDH system prompt + # systemPrompt: "You are a helpful assistant focused on Red Hat Developer Hub development." \ No newline at end of file diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-lightspeed.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-lightspeed.yaml new file mode 100644 index 0000000000..5ace80392f --- /dev/null +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-lightspeed.yaml @@ -0,0 +1,52 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: red-hat-developer-hub-backstage-plugin-lightspeed + namespace: rhdh + title: "Lightspeed Frontend" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHPAI + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/lightspeed/plugins/lightspeed + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/lightspeed/plugins/lightspeed + tags: [] +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-lightspeed" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-lightspeed:bs_1.39.1__0.5.7!red-hat-developer-hub-backstage-plugin-lightspeed + version: 0.5.7 + backstage: + role: frontend-plugin + supportedVersions: 1.39.1 + author: Red Hat + support: dev-preview + lifecycle: active + partOf: + - lightspeed + appConfigExamples: + - title: Default configuration + content: | + lightspeed: + # OPTIONAL: Custom users prompts displayed to users + # If not provided, the plugin uses built-in default prompts + prompts: + - title: 'Getting Started with Red Hat Developer Hub' + message: Can you guide me through the first steps to start using Developer Hub as a developer, like exploring the Software Catalog and adding my service? + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-lightspeed: + appIcons: + - name: LightspeedIcon + module: LightspeedPlugin + importName: LightspeedIcon + dynamicRoutes: + - path: /lightspeed + importName: LightspeedPage + module: LightspeedPlugin + menuItem: + icon: LightspeedIcon + text: Lightspeed diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-marketplace-backend.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-marketplace-backend.yaml index f6b7301808..5733dec93a 100644 --- a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-marketplace-backend.yaml +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-marketplace-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: red-hat-developer-hub-backstage-plugin-marketplace-backend namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-marketplace-backend" + title: "Marketplace Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@red-hat-developer-hub/backstage-plugin-marketplace-backend" dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic - version: 0.6.0 + version: 0.11.0 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-marketplace.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-marketplace.yaml index 4e69fe398b..3d4d7ba84c 100644 --- a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-marketplace.yaml +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-marketplace.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: red-hat-developer-hub-backstage-plugin-marketplace namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-marketplace" + title: "Marketplace Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@red-hat-developer-hub/backstage-plugin-marketplace" dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace - version: 0.7.0 + version: 0.11.4 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool.yaml new file mode 100644 index 0000000000..eb7dc9c107 --- /dev/null +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool.yaml @@ -0,0 +1,36 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: red-hat-developer-hub-plugin-software-catalog-mcp-tool + namespace: rhdh + title: "@red-hat-developer-hub/backstage-plugin-software-catalog-mcp-tool" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHPAI + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/mcp-integrations/plugins/software-catalog-mcp-tool + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/mcp-integrations/plugins/software-catalog-mcp-tool + tags: [] +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-software-catalog-mcp-tool" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool:bs_1.42.5__0.2.2!red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool + version: 0.2.1 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: Red Hat + support: dev-preview + lifecycle: active + partOf: + - mcp-tools + appConfigExamples: + - title: Default configuration + content: + backend: + actions: + pluginSources: + - 'software-catalog-mcp-tool' \ No newline at end of file diff --git a/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-techdocs-mcp-tool.yaml b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-techdocs-mcp-tool.yaml new file mode 100644 index 0000000000..3e56dcea38 --- /dev/null +++ b/catalog-entities/marketplace/packages/red-hat-developer-hub-backstage-plugin-techdocs-mcp-tool.yaml @@ -0,0 +1,36 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: red-hat-developer-hub-plugin-techdocs-mcp-tool + namespace: rhdh + title: "@red-hat-developer-hub/backstage-plugin-techdocs-mcp-tool" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHDHPAI + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/mcp-integrations/plugins/techdocs-mcp-tool + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/mcp-integrations/plugins/techdocs-mcp-tool + tags: [] +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-techdocs-mcp-tool" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-techdocs-mcp-tool:bs_1.42.5__0.2.1!red-hat-developer-hub-backstage-plugin-techdocs-mcp-tool + version: 0.2.0 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: Red Hat + support: dev-preview + lifecycle: active + partOf: + - mcp-tools + appConfigExamples: + - title: Default configuration + content: + backend: + actions: + pluginSources: + - 'techdocs-mcp-tool' \ No newline at end of file diff --git a/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator-backend.yaml b/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator-backend.yaml index be531d3c43..a11dd77e03 100644 --- a/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator-backend.yaml +++ b/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: redhat-backstage-plugin-orchestrator-backend namespace: rhdh - title: "@redhat/backstage-plugin-orchestrator-backend" + title: "Orchestrator Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,8 +18,8 @@ metadata: - automation spec: packageName: "@redhat/backstage-plugin-orchestrator-backend" - dynamicArtifact: "@redhat/backstage-plugin-orchestrator-backend-dynamic@1.5.1" - version: 1.5.1 + dynamicArtifact: "@redhat/backstage-plugin-orchestrator-backend-dynamic@1.7.1" + version: 1.7.1 backstage: role: backend-plugin supportedVersions: 1.39.1 diff --git a/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator-form-widgets.yaml b/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator-form-widgets.yaml new file mode 100644 index 0000000000..238243f038 --- /dev/null +++ b/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator-form-widgets.yaml @@ -0,0 +1,36 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: redhat-backstage-plugin-orchestrator-form-widgets + namespace: rhdh + title: "Orchestrator Form Widgets" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHIDP + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/orchestrator/plugins/orchestrator-form-widgets + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/orchestrator/plugins/orchestrator-form-widgets + tags: + - automation +spec: + packageName: "@redhat/backstage-plugin-orchestrator-form-widgets" + dynamicArtifact: "@redhat/backstage-plugin-orchestrator-form-widgets@1.7.1" + version: 1.7.1 + backstage: + role: backend-plugin + supportedVersions: 1.39.1 + author: Red Hat + support: tech-preview + lifecycle: active + partOf: + - orchestrator + appConfigExamples: + - title: Default configuration + content: + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-orchestrator-form-widgets: { } diff --git a/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator.yaml b/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator.yaml index c5c747ba1a..682c6f4cc8 100644 --- a/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator.yaml +++ b/catalog-entities/marketplace/packages/redhat-backstage-plugin-orchestrator.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: redhat-backstage-plugin-orchestrator namespace: rhdh - title: "@redhat/backstage-plugin-orchestrator" + title: "Orchestrator Frontend" links: - url: https://red.ht/rhdh title: Homepage @@ -18,13 +18,13 @@ metadata: - automation spec: packageName: "@redhat/backstage-plugin-orchestrator" - dynamicArtifact: "@redhat/backstage-plugin-orchestrator@1.5.1" - version: 1.5.1 + dynamicArtifact: "@redhat/backstage-plugin-orchestrator@1.7.1" + version: 1.7.1 backstage: role: frontend-plugin supportedVersions: 1.39.1 author: Red Hat - support: tech-preview + support: production lifecycle: active partOf: - orchestrator @@ -45,3 +45,16 @@ spec: text: Orchestrator module: OrchestratorPlugin path: /orchestrator + entityTabs: + - path: /workflows + title: Workflows + mountPoint: entity.page.workflows + mountPoints: + - mountPoint: entity.page.workflows/cards + importName: OrchestratorCatalogTab + config: + layout: + gridColumn: '1 / -1' + if: + anyOf: + - IsOrchestratorCatalogTabAvailable diff --git a/catalog-entities/marketplace/packages/redhat-backstage-plugin-scaffolder-backend-module-orchestrator.yaml b/catalog-entities/marketplace/packages/redhat-backstage-plugin-scaffolder-backend-module-orchestrator.yaml index 93ed265977..63cd1dc083 100644 --- a/catalog-entities/marketplace/packages/redhat-backstage-plugin-scaffolder-backend-module-orchestrator.yaml +++ b/catalog-entities/marketplace/packages/redhat-backstage-plugin-scaffolder-backend-module-orchestrator.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: redhat-backstage-plugin-scaffolder-backend-module-orchestrator namespace: rhdh - title: "@redhat/backstage-plugin-scaffolder-backend-module-orchestrator" + title: "Scaffolder Backend Module Orchestrator" links: - url: https://red.ht/rhdh title: Homepage @@ -19,13 +19,13 @@ metadata: - automation spec: packageName: "@redhat/backstage-plugin-scaffolder-backend-module-orchestrator" - dynamicArtifact: "@redhat/backstage-plugin-scaffolder-backend-module-orchestrator-dynamic@1.5.1" - version: 1.5.1 + dynamicArtifact: "@redhat/backstage-plugin-scaffolder-backend-module-orchestrator-dynamic@1.7.1" + version: 1.7.1 backstage: role: backend-plugin-module supportedVersions: 1.39.1 author: Red Hat - support: tech-preview + support: production lifecycle: active partOf: - orchestrator-scaffolder-actions diff --git a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-adoption-insights-backend.yaml b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-adoption-insights-backend.yaml index c369baadab..f0f9340bed 100644 --- a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-adoption-insights-backend.yaml +++ b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-adoption-insights-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: rhdh-backstage-plugin-adoption-insights-backend namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-adoption-insights-backend" + title: "Adoption Insights Backend" links: - url: https://red.ht/rhdh title: Homepage @@ -23,7 +23,7 @@ spec: role: backend-plugin supportedVersions: 1.39.1 author: Red Hat - support: tech-preview + support: production lifecycle: active partOf: - adoption-insights diff --git a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-adoption-insights.yaml b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-adoption-insights.yaml index bd09db8033..07616c35f6 100644 --- a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-adoption-insights.yaml +++ b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-adoption-insights.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: rhdh-backstage-plugin-adoption-insights namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-adoption-insights" + title: "Adoption Insights Frontend" links: - url: https://red.ht/rhdh title: Homepage diff --git a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-analytics-module-adoption-insights.yaml b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-analytics-module-adoption-insights.yaml index 6dfe45ef4d..5478f8e907 100644 --- a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-analytics-module-adoption-insights.yaml +++ b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-analytics-module-adoption-insights.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: rhdh-backstage-plugin-analytics-module-adoption-insights namespace: rhdh - title: "@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights" + title: "Analytics Module Adoption Insights" links: - url: https://red.ht/rhdh title: Homepage @@ -23,7 +23,7 @@ spec: role: frontend-plugin-module supportedVersions: 1.39.1 author: Red Hat - support: tech-preview + support: production lifecycle: active partOf: - adoption-insights diff --git a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-quickstart.yaml b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-quickstart.yaml new file mode 100644 index 0000000000..ab95ff3d8e --- /dev/null +++ b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-quickstart.yaml @@ -0,0 +1,71 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: rhdh-backstage-plugin-quickstart + namespace: rhdh + title: "Quickstart" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHIDP + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh/tree/main/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh/tree/main/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-quickstart" + dynamicArtifact: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-quickstart + version: 1.6.2 + backstage: + role: frontend-plugin + supportedVersions: 1.42.5 + author: Red Hat + support: production + lifecycle: active + partOf: + - quickstart + appConfigExamples: + - title: Default configuration + content: + app: + quickstart: + - title: Set up authentication + icon: Admin + description: Set up secure login credentials to protect your account from + unauthorized access. + cta: + text: Learn more + link: https://docs.redhat.com/en/documentation/red_hat_developer_hub/latest/html/authentication_in_red_hat_developer_hub/ + - title: Configure RBAC + icon: Rbac + description: Assign roles and permissions to control who can view, create, or + edit resources, ensuring secure and efficient collaboration. + cta: + text: Manage access + link: /rbac + - title: Configure Git + icon: Git + description: Connect your Git providers, such as GitHub to manage code, automate + workflows, and integrate with platform features. + cta: + text: Learn more + link: https://docs.redhat.com/en/documentation/red_hat_developer_hub/latest/html/integrating_red_hat_developer_hub_with_github/ + - title: Manage plugins + icon: Plugins + description: Browse and install extensions to add features, connect with + external tools, and customize your experience. + cta: + text: Explore plugins + link: /extensions + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-quickstart: + mountPoints: + - mountPoint: application/provider + importName: QuickstartDrawerProvider + - mountPoint: global.header/help + importName: QuickstartButton + config: + priority: 100 \ No newline at end of file diff --git a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend-module-github.yaml b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend-module-github.yaml new file mode 100644 index 0000000000..1bf624a06f --- /dev/null +++ b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend-module-github.yaml @@ -0,0 +1,68 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: rhdh-backstage-plugin-scorecard-backend-module-github + namespace: rhdh + title: "Scorecard Backend Module GitHub" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHIDP + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/scorecard/plugins/scorecard-backend-module-github + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/scorecard/plugins/scorecard-backend-module-github + tags: + - analytics +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-scorecard-backend-module-github" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github:bs_1.42.5__1.0.0!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github + version: 1.0.0 + backstage: + role: backend-plugin-module + supportedVersions: 1.42.5 + author: Red Hat + support: tech-preview + lifecycle: active + partOf: + - scorecard + appConfigExamples: + - title: Default configuration + content: + integrations: + github: + - host: ${GITHUB_HOST} + apps: + - appId: ${GITHUB_APP_APP_ID} + clientId: ${GITHUB_APP_CLIENT_ID} + clientSecret: ${GITHUB_APP_CLIENT_SECRET} + webhookUrl: ${GITHUB_APP_WEBHOOK_URL} + webhookSecret: ${GITHUB_APP_WEBHOOK_SECRET} + privateKey: | + ${GITHUB_APP_PRIVATE_KEY} + - title: Token configuration + content: + integrations: + github: + - host: ${GITHUB_HOST} + token: ${GITHUB_TOKEN} + - title: Threshold configuration (optional) + content: + integrations: + github: + - host: ${GITHUB_HOST} + token: ${GITHUB_TOKEN} + scorecard: + plugins: + github: + open_prs: + thresholds: + rules: + - key: success + expression: '<50' + - key: warning + expression: '50-100' + - key: error + expression: '>100' diff --git a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend-module-jira.yaml b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend-module-jira.yaml new file mode 100644 index 0000000000..7fecc067da --- /dev/null +++ b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend-module-jira.yaml @@ -0,0 +1,93 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: rhdh-backstage-plugin-scorecard-backend-module-jira + namespace: rhdh + title: "Scorecard Backend Module Jira" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHIDP + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/scorecard/plugins/scorecard-backend-module-jira + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/scorecard/plugins/scorecard-backend-module-jira + tags: + - analytics +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-scorecard-backend-module-jira" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira:bs_1.42.5__1.0.1!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira + version: 1.0.1 + backstage: + role: backend-plugin-module + supportedVersions: 1.42.5 + author: Red Hat + support: tech-preview + lifecycle: active + partOf: + - scorecard + appConfigExamples: + - title: Default configuration + content: + jira: + product: cloud + proxyPath: /jira/api + proxy: + endpoints: + '/jira/api': + target: ${JIRA_URL} + headers: + Accept: 'application/json' + Content-Type: 'application/json' + X-Atlassian-Token: 'no-check' + # Required: (For cloud use 'Basic email:tokenInBase64', for datacenter use 'Bearer YourJiraToken') + Authorization: ${JIRA_TOKEN} + - title: Direct cloud configuration + content: + jira: + product: cloud + baseUrl: ${JIRA_URL} + # Required: Use prepared "email:tokenInBase64" string (No need for adding Basic) + token: ${JIRA_TOKEN} + - title: Direct datacenter configuration + content: + jira: + product: datacenter + baseUrl: ${JIRA_URL} + # Required: Use directly your Jira token (No need for adding Bearer) + token: ${JIRA_TOKEN} + - title: Jira filter configuration (optional) + content: + jira: + product: cloud + baseUrl: ${JIRA_URL} + token: ${JIRA_TOKEN} + scorecard: + plugins: + jira: + open_issues: + options: + # Optional: use mandatoryFilter to replace the default filter "type = Bug AND resolution = Unresolved" + mandatoryFilter: type = Task AND resolution = Unresolved + # Optional: use to specify global customFilter, the entity annotation `jira/custom-filter` can replace it + customFilter: priority in ("Critical", "Blocker") + - title: Threshold configuration (optional) + content: + jira: + product: cloud + baseUrl: ${JIRA_URL} + token: ${JIRA_TOKEN} + scorecard: + plugins: + jira: + open_issues: + thresholds: + rules: + - key: success + expression: '<50' + - key: warning + expression: '50-100' + - key: error + expression: '>100' diff --git a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend.yaml b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend.yaml new file mode 100644 index 0000000000..9939aca975 --- /dev/null +++ b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard-backend.yaml @@ -0,0 +1,31 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: rhdh-backstage-plugin-scorecard-backend + namespace: rhdh + title: "Scorecard Backend" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHIDP + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/scorecard/plugins/scorecard-backend + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/scorecard/plugins/scorecard-backend + tags: + - analytics +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-scorecard-backend" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend:bs_1.42.5__1.0.0!red-hat-developer-hub-backstage-plugin-scorecard-backend + version: 1.0.0 + backstage: + role: backend-plugin + supportedVersions: 1.42.5 + author: Red Hat + support: tech-preview + lifecycle: active + partOf: + - scorecard + appConfigExamples: [] diff --git a/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard.yaml b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard.yaml new file mode 100644 index 0000000000..d908466813 --- /dev/null +++ b/catalog-entities/marketplace/packages/rhdh-backstage-plugin-scorecard.yaml @@ -0,0 +1,49 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Package +metadata: + name: rhdh-backstage-plugin-scorecard + namespace: rhdh + title: "Scorecard" + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHIDP + title: Bugs + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/scorecard/plugins/scorecard + annotations: + backstage.io/source-location: url + https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/scorecard/plugins/scorecard + tags: + - analytics +spec: + packageName: "@red-hat-developer-hub/backstage-plugin-scorecard" + dynamicArtifact: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard:bs_1.42.5__1.0.0!red-hat-developer-hub-backstage-plugin-scorecard + version: 1.0.0 + backstage: + role: frontend-plugin + supportedVersions: 1.42.5 + author: Red Hat + support: tech-preview + lifecycle: active + partOf: + - scorecard + appConfigExamples: + - title: Default configuration + content: + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-scorecard: + entityTabs: + - path: '/scorecard' + title: Scorecard + mountPoint: entity.page.scorecard + mountPoints: + - mountPoint: entity.page.scorecard/cards + importName: EntityScorecardContent + config: + layout: + gridColumn: 1 / -1 + if: + allOf: + - isKind: component diff --git a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-argo-cd-backend.yaml b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-argo-cd-backend.yaml index 7ec6f41a66..8e05e4495f 100644 --- a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-argo-cd-backend.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-argo-cd-backend.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-backstage-plugin-argo-cd-backend namespace: rhdh - title: "@roadiehq/backstage-plugin-argo-cd-backend" + title: "ArgoCD" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@roadiehq/backstage-plugin-argo-cd-backend" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-backstage-plugin-argo-cd-backend-dynamic - version: 4.3.1 + version: 4.4.2 backstage: role: backend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: production lifecycle: active diff --git a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-datadog.yaml b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-datadog.yaml index f6275a5a49..a0aae5e14f 100644 --- a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-datadog.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-datadog.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-backstage-plugin-datadog namespace: rhdh - title: "@roadiehq/backstage-plugin-datadog" + title: "Datadog" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@roadiehq/backstage-plugin-datadog" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-backstage-plugin-datadog - version: 2.4.3 + version: 2.5.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-github-insights.yaml b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-github-insights.yaml index e1bdf53ff7..3c8e180964 100644 --- a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-github-insights.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-github-insights.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-backstage-plugin-github-insights namespace: rhdh - title: "@roadiehq/backstage-plugin-github-insights" + title: "GitHub Insights" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@roadiehq/backstage-plugin-github-insights" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-backstage-plugin-github-insights - version: 3.1.4 + version: 3.2.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-github-pull-requests.yaml b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-github-pull-requests.yaml index 2e3632b942..9a8f9677fc 100644 --- a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-github-pull-requests.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-github-pull-requests.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-backstage-plugin-github-pull-requests namespace: rhdh - title: "@roadiehq/backstage-plugin-github-pull-requests" + title: "GitHub Pull Requests" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@roadiehq/backstage-plugin-github-pull-requests" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-backstage-plugin-github-pull-requests - version: 3.4.2 + version: 3.5.2 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-jira.yaml b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-jira.yaml index 38294f13db..e19e0876ee 100644 --- a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-jira.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-jira.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-backstage-plugin-jira namespace: rhdh - title: "@roadiehq/backstage-plugin-jira" + title: "Jira" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@roadiehq/backstage-plugin-jira" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-backstage-plugin-jira - version: 2.9.0 + version: 2.13.1 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-security-insights.yaml b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-security-insights.yaml index 8bf46f280b..fb87e4a4b3 100644 --- a/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-security-insights.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-backstage-plugin-security-insights.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-backstage-plugin-security-insights namespace: rhdh - title: "@roadiehq/backstage-plugin-security-insights" + title: "Security Insights" links: - url: https://red.ht/rhdh title: Homepage @@ -18,10 +18,10 @@ metadata: spec: packageName: "@roadiehq/backstage-plugin-security-insights" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-backstage-plugin-security-insights - version: 3.1.3 + version: 3.2.0 backstage: role: frontend-plugin - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-argocd.yaml b/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-argocd.yaml index 858f284a62..e05a932883 100644 --- a/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-argocd.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-argocd.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-scaffolder-backend-argocd namespace: rhdh - title: "@roadiehq/scaffolder-backend-argocd" + title: "Scaffolder Backend ArgoCD" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@roadiehq/scaffolder-backend-argocd" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-scaffolder-backend-argocd-dynamic - version: 1.6.0 + version: 1.7.1 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-module-http-request.yaml b/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-module-http-request.yaml index 9eee1312b3..86583f6eed 100644 --- a/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-module-http-request.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-module-http-request.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-scaffolder-backend-module-http-request namespace: rhdh - title: "@roadiehq/scaffolder-backend-module-http-request" + title: "Scaffolder Backend Module HTTP Request" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@roadiehq/scaffolder-backend-module-http-request" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-scaffolder-backend-module-http-request-dynamic - version: 5.3.3 + version: 5.4.2 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-module-utils.yaml b/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-module-utils.yaml index d74d4d7c90..3d7bb4fe47 100644 --- a/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-module-utils.yaml +++ b/catalog-entities/marketplace/packages/roadiehq-scaffolder-backend-module-utils.yaml @@ -3,7 +3,7 @@ kind: Package metadata: name: roadiehq-scaffolder-backend-module-utils namespace: rhdh - title: "@roadiehq/scaffolder-backend-module-utils" + title: "Scaffolder Backend Module Utils" links: - url: https://red.ht/rhdh title: Homepage @@ -19,10 +19,10 @@ metadata: spec: packageName: "@roadiehq/scaffolder-backend-module-utils" dynamicArtifact: ./dynamic-plugins/dist/roadiehq-scaffolder-backend-module-utils-dynamic - version: 3.5.0 + version: 4.0.3 backstage: role: backend-plugin-module - supportedVersions: 1.39.1 + supportedVersions: 1.42.5 author: Red Hat support: tech-preview lifecycle: active diff --git a/catalog-entities/marketplace/plugins/1-boilerplate.yaml.sample b/catalog-entities/marketplace/plugins/1-boilerplate.yaml.sample index 20e0498845..0353131cbb 100644 --- a/catalog-entities/marketplace/plugins/1-boilerplate.yaml.sample +++ b/catalog-entities/marketplace/plugins/1-boilerplate.yaml.sample @@ -24,7 +24,9 @@ metadata: This is the description text used for the Tile view - keep it short. spec: author: Red Hat - support: tech-preview # production, tech-preview, dev-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/3scale.yaml b/catalog-entities/marketplace/plugins/3scale.yaml index d09804a918..882f1d2cf9 100644 --- a/catalog-entities/marketplace/plugins/3scale.yaml +++ b/catalog-entities/marketplace/plugins/3scale.yaml @@ -24,7 +24,9 @@ metadata: The 3scale plugin synchronizes your 3scale content into the software catalog. spec: author: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/adoption-insights.yaml b/catalog-entities/marketplace/plugins/adoption-insights.yaml index f23f94f7aa..f0524ae547 100644 --- a/catalog-entities/marketplace/plugins/adoption-insights.yaml +++ b/catalog-entities/marketplace/plugins/adoption-insights.yaml @@ -23,7 +23,9 @@ metadata: url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/adoption-insights/plugins/adoption-insights spec: - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active author: Red Hat publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/ai-model-catalog.yaml b/catalog-entities/marketplace/plugins/ai-model-catalog.yaml new file mode 100644 index 0000000000..3192efd590 --- /dev/null +++ b/catalog-entities/marketplace/plugins/ai-model-catalog.yaml @@ -0,0 +1,338 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: ai-integrations + namespace: rhdh + title: AI Model Catalog + annotations: + extensions.backstage.io/pre-installed: 'true' # Plugin is automatically listed in the catalog. + links: + - title: Homepage + url: https://red.ht/rhdh + - title: Bugs + url: https://issues.redhat.com/browse/RHDHPAI + - title: Documentation for Red Hat Developer Hub + url: https://docs.redhat.com/en/documentation/red_hat_developer_hub + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/ai-integrations + tags: + - rhoai + - developer-tools + - ai + - software-catalog + - techdocs + description: | + Backend plugins that integrates with Red Hat OpenShift AI to map AI Models and Model Servers from Red Hat OpenShift AI as Component, Resourece, and API entities. The plugins also facilitate + creating TechDocs for the Components and Resources from the Model Cards for the AI Models +spec: + author: Red Hat + support: dev-preview + lifecycle: active + publisher: Red Hat + + + highlights: + - Integrations with the software catalog and techdocs for AI Models and Model Servers + - Provides information on specific models and model servers needed to build AI applications + - Assists in the construction of AI application related Templates + + + description: | + # AI Model Catalog Plugins + + + Red Hat Developer Hub provides a collection of plugins and sidecar containers that can be used to import metadata AI Models and Model Servers hosted in Red Hat OpenShift AI. + + + Details on the specific components: + + + - **AI Model Catalog Plugins** (`@red-hat-developer/hub-backstage-plugin-catalog-backend-module-model-catalog` and `@red-hat-developer/hub-backstage-plugin-catalog-techdoc-url-reader-backend`) + - **AI Model Catalog Bridge sidecar containers** (three sidecar containers are added to the Red Hat Developer Hub Pod) + + + ### Key Features + + + - **Red Hat OpenShift AI Integration**: Query Red Hat OpenShift AI to fetch AI Models and Model Servers metadata. + - **Integrations with the Software Catalog**: Normalize the AI Model and Model Server metadata to the Software Catalog entity types. + - **Integrations with Techdocs**: Import the AI Model and Model Server Model Cards Red Hat Developer Hub TechDocs. + + + ## Support + + + - **Backend Plugin**: [Backend README](https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/ai-integrations/README.md) + - **Sidecar Containers**: [Sidecar Containers README](https://github.com/redhat-ai-dev/model-catalog-bridge/blob/main/README.md) + - **Issues**: [Jira Issues](https://issues.redhat.com/browse/RHDHBUGS) + + + packages: # link to the name used in the associated package documents in ../packages + - red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog + - red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-backend + + + installation: | + ## Installation + + + ### Dynamic Plugin Installation for Red Hat Developer Hub + + + Add the following configuration to your dynamic plugin yaml: + + + ```yaml + includes: + - dynamic-plugins.default.yaml + plugins: + # AI Model Catalog plugins + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog:next__0.6.0!red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog + disabled: false + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-backend:next__0.3.0!red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-backend + + ``` + + + ## RHDH Configuration + + + ### Plugin Configuration Reference + + + Register the AI Model Catalog Entity provider in your App Config: + ```yaml + catalog: + providers: + modelCatalog: + developement: + baseUrl: http://localhost:9090 + ``` + + ### Sidecar Related Configuration + + The configuration changes needed to enable the sidecar containers fall into two categories: + + - **RBAC to access the OpenShift AI Model Registry** + - **The specification of the sidecard containers in the Red Hat Developer Hub Pod** + + Here is an example configuration for the RBAC if RHDH is deployed in the 'ai-rhdh' namespace and the OpenShift AI Model Registry is deployed in the 'rhoai-model-registries' namespace: + + ```yaml + --- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: rhdh-rhoai-bridge + namespace: ai-rhdh + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: rhdh-rhoai-bridge + annotations: + argocd.argoproj.io/sync-wave: "0" + rules: + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - get + - list + - watch + - apiGroups: [""] + resources: + - serviceaccounts + - services + verbs: + - get + - list + - watch + + - apiGroups: ["serving.kserve.io"] + resources: ["inferenceservices"] + verbs: ["get", "list", "watch"] + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: rhdh-rhoai-bridge + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: rhdh-rhoai-bridge + subjects: + - kind: ServiceAccount + name: rhdh-rhoai-bridge + namespace: ai-rhdh + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: rhdh-rhoai-dashboard-permissions + namespace: rhoai-model-registries + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: registry-user-modelregistry-public + subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:serviceaccounts:ai-rhdh + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: rhdh-rhoai-bridge + namespace: ai-rhdh + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: rhdh-rhoai-bridge + subjects: + - kind: ServiceAccount + name: rhdh-rhoai-bridge + namespace: ai-rhdh + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: rhdh-rhoai-bridge + namespace: ai-rhdh + rules: + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + --- + apiVersion: v1 + kind: Secret + metadata: + name: rhdh-rhoai-bridge-token + namespace: ai-rhdh + annotations: + kubernetes.io/service-account.name: rhdh-rhoai-bridge + type: kubernetes.io/service-account-token + ``` + + Here is the example YAML for adding the three sidecard containers as part of a `Backstage` Custom Resource instance: + + ```yaml + spec: + application: + extraFiles: + mountPath: /opt/app-root/src + secrets: + - key: token + mountPath: /opt/app-root/src + name: rhdh-rhoai-bridge-token + deployment: + patch: + spec: + template: + spec: + containers: + - name: backstage-backend + - env: + - name: NORMALIZER_FORMAT + value: JsonArrayFormat + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + envFrom: + - secretRef: + name: rhdh-rhoai-bridge-token + - secretRef: + name: ai-rh-developer-hub-env + image: quay.io/redhat-ai-dev/model-catalog-location-service:latest + imagePullPolicy: Always + name: location + ports: + - containerPort: 9090 + name: location + protocol: TCP + volumeMounts: + - mountPath: /opt/app-root/src/dynamic-plugins-root + name: dynamic-plugins-root + workingDir: /opt/app-root/src + - env: + - name: NORMALIZER_FORMAT + value: JsonArrayFormat + - name: STORAGE_TYPE + value: ConfigMap + - name: BRIDGE_URL + value: http://localhost:9090 + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + envFrom: + - secretRef: + name: rhdh-rhoai-bridge-token + - secretRef: + name: ai-rh-developer-hub-env + image: quay.io/redhat-ai-dev/model-catalog-storage-rest:latest + imagePullPolicy: Always + name: storage-rest + ports: + - containerPort: 9090 + name: location + protocol: TCP + volumeMounts: + - mountPath: /opt/app-root/src/dynamic-plugins-root + name: dynamic-plugins-root + workingDir: /opt/app-root/src + - env: + - name: NORMALIZER_FORMAT + value: JsonArrayFormat + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + envFrom: + - secretRef: + name: rhdh-rhoai-bridge-token + - secretRef: + name: ai-rh-developer-hub-env + image: quay.io/redhat-ai-dev/model-catalog-rhoai-normalizer:latest + imagePullPolicy: Always + name: rhoai-normalizer + ports: + - containerPort: 9090 + name: location + protocol: TCP + volumeMounts: + - mountPath: /opt/app-root/src/dynamic-plugins-root + name: dynamic-plugins-root + workingDir: /opt/app-root/src + replicas: 1 + + ``` + + ## OpenShift AI Configuration + + Documentation on the OpenShift AI Model Registry configuration can be found [here](https://docs.redhat.com/en/documentation/red_hat_openshift_ai_self-managed/2.23/html/working_with_model_registries/index) + + + + diff --git a/catalog-entities/marketplace/plugins/all.yaml b/catalog-entities/marketplace/plugins/all.yaml index e51ca0a8bb..cdb75dfd71 100644 --- a/catalog-entities/marketplace/plugins/all.yaml +++ b/catalog-entities/marketplace/plugins/all.yaml @@ -7,6 +7,7 @@ spec: targets: - ./3scale.yaml - ./adoption-insights.yaml + - ./aws-ecs.yaml - ./analytics-provider-segment.yaml - ./ansible-plugin.yaml - ./argocd-scaffolder-actions.yaml @@ -18,7 +19,6 @@ spec: - ./bitbucket-cloud-catalog-integration.yaml - ./bitbucket-server-catalog-integration.yaml - ./bulk-import.yaml - - ./catalog-integrations.yaml - ./contrib-techdocs-addons.yaml - ./datadog.yaml - ./dynatrace-commercial.yaml @@ -49,6 +49,7 @@ spec: - ./kubernetes-backend.yaml - ./ldap-catalog-integration.yaml - ./lighthouse.yaml + - ./mcp-chat.yaml - ./microsoft-graph-catalog-integration.yaml - ./nexus-repository-manager.yaml - ./notifications.yaml @@ -62,11 +63,13 @@ spec: - ./rbac.yaml - ./redhat-argocd.yaml - ./regex-scaffolder-actions.yaml + - ./quickstart.yaml - ./roadie-argocd.yaml - ./roadie-scaffolder-util-actions.yaml - - ./scaffolder-integrations.yaml - ./scaffolder-relation-processor-catalog-integration.yaml + - ./scorecard.yaml - ./security-insights.yaml + - ./servicenow.yaml - ./servicenow-scaffolder-actions.yaml - ./signals.yaml - ./signals-backend.yaml @@ -75,4 +78,9 @@ spec: - ./tech-radar.yaml - ./techdocs.yaml - ./tekton.yaml + - ./todo.yaml - ./topology.yaml + - ./lightspeed.yaml + - ./ibm-apiconnect-backstage.yaml + - ./mcp-tools.yaml + - ./ai-model-catalog.yaml diff --git a/catalog-entities/marketplace/plugins/analytics-provider-segment.yaml b/catalog-entities/marketplace/plugins/analytics-provider-segment.yaml index 4737f354c3..d964430a73 100644 --- a/catalog-entities/marketplace/plugins/analytics-provider-segment.yaml +++ b/catalog-entities/marketplace/plugins/analytics-provider-segment.yaml @@ -26,7 +26,9 @@ spec: - Analytics author: Red Hat publisher: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active description: | This plugin ships as enabled by default in Red Hat Developer Hub. @@ -84,6 +86,9 @@ spec: # highlight-start writeKey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx maskIP: true # prevents IP addresses from being sent if true + testMode: false # prevents data from being sent if true + appVersion: ${RHDH_VERSION} # RHDH application version + backstageVersion: ${BACKSTAGE_VERSION} # Backstage version # highlight-end ``` diff --git a/catalog-entities/marketplace/plugins/ansible-plugin.yaml b/catalog-entities/marketplace/plugins/ansible-plugin.yaml index a22cfaaa7f..4ca945976c 100644 --- a/catalog-entities/marketplace/plugins/ansible-plugin.yaml +++ b/catalog-entities/marketplace/plugins/ansible-plugin.yaml @@ -28,7 +28,9 @@ metadata: spec: author: Red Hat - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/argocd-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/argocd-scaffolder-actions.yaml index c53ebc100f..888dc5839a 100644 --- a/catalog-entities/marketplace/plugins/argocd-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/argocd-scaffolder-actions.yaml @@ -25,7 +25,9 @@ metadata: spec: author: Roadie publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: - CI/CD diff --git a/catalog-entities/marketplace/plugins/aws-ecs.yaml b/catalog-entities/marketplace/plugins/aws-ecs.yaml new file mode 100644 index 0000000000..953f44e637 --- /dev/null +++ b/catalog-entities/marketplace/plugins/aws-ecs.yaml @@ -0,0 +1,126 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: aws-ecs + namespace: community + title: Amazon ECS + annotations: + extensions.backstage.io/pre-installed: 'true' # Plugin is automatically listed in the catalog. + description: | + View and manage Amazon Elastic Container Service (ECS) resources directly from your Backstage catalog. + Monitor ECS services, tasks, and deployments with real-time status information. + tags: + - aws + - cloud + - containers + - ecs + links: + - url: https://github.com/awslabs/backstage-plugins-for-aws + title: Homepage + - url: https://github.com/awslabs/backstage-plugins-for-aws/issues + title: Bugs + - title: Source Code + url: https://github.com/awslabs/backstage-plugins-for-aws/tree/main/plugins/ecs + - title: Documentation + url: https://github.com/awslabs/backstage-plugins-for-aws/blob/main/plugins/ecs/README.md +spec: + authors: + - name: AWS + url: https://aws.amazon.com/ + + publisher: AWS + support: + provider: Community + level: community + lifecycle: active + categories: + - Cloud + + highlights: + - Real-time ECS service status monitoring + - View ECS tasks and deployments + - Service-level metrics and insights + - Tag-based or ARN-based service discovery + - Integration with AWS SDK credential chain + + description: | + The Amazon ECS plugin for Backstage enables developers to view and monitor their Amazon Elastic Container Service (ECS) + resources directly within the Backstage developer portal. This integration provides a unified view of your ECS services, + tasks, and deployments alongside your service catalog entities. + + ## Key Features + + * **Service Monitoring**: View real-time status of ECS services including running tasks, desired count, and deployment status + * **Task Information**: Access detailed information about ECS tasks, including container status and health + * **Flexible Discovery**: Find ECS services using either specific ARNs or tag-based queries + * **AWS Integration**: Seamlessly integrates with AWS SDK credential chain for authentication + * **Entity Annotations**: Link Backstage catalog entities to ECS services using simple annotations + + ## Adding The Plugin To Red Hat Developer Hub + + This plugin consists of both frontend and backend components that work together to provide ECS integration. + + See the [Red Hat Developer Hub documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) + for further instructions on how to add, enable, configure, and remove plugins in your instance. + + ## Configuring The Plugin + + The AWS ECS plugin requires AWS credentials to be configured. The backend plugin uses the AWS SDK credential chain, + which supports multiple authentication methods including environment variables, IAM roles, and AWS profiles. + + ### Backend Configuration + + Configure AWS credentials via environment variables: + + ```bash + AWS_REGION=us-east-1 + AWS_ACCESS_KEY_ID=your-access-key-id + AWS_SECRET_ACCESS_KEY=your-secret-access-key + ``` + + For production deployments, using IAM roles for service accounts (IRSA) or EC2 instance profiles is recommended + for better security. + + ### Entity Annotations + + Add ECS service information to your catalog entities using annotations: + + ```yaml + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: my-service + annotations: + # Option 1: Specific service ARN + aws.amazon.com/amazon-ecs-service-arn: arn:aws:ecs:us-east-1:123456789012:service/my-cluster/my-service + + # Option 2: Tag-based discovery + # aws.amazon.com/amazon-ecs-service-tags: component=my-app,environment=production + spec: + type: service + lifecycle: production + owner: platform-team + ``` + + The frontend plugin will automatically display an "Amazon ECS" tab on catalog entities with these annotations, + showing the associated ECS service information. + + ## Prerequisites + + * AWS account with ECS services + * AWS credentials configured with appropriate IAM permissions + * IAM permissions required: + * `ecs:DescribeServices` + * `ecs:DescribeTasks` + * `ecs:ListTasks` + * Additional permissions may be required based on your configuration + + For more detailed configuration instructions, see the [plugin documentation](https://github.com/awslabs/backstage-plugins-for-aws/blob/main/plugins/ecs/README.md). + + packages: + - aws-amazon-ecs-plugin-for-backstage + - aws-amazon-ecs-plugin-for-backstage-backend + + history: + added: '2025-10-08' diff --git a/catalog-entities/marketplace/plugins/azure-container-registry.yaml b/catalog-entities/marketplace/plugins/azure-container-registry.yaml index 8f86f29cfe..6e1d4bae75 100644 --- a/catalog-entities/marketplace/plugins/azure-container-registry.yaml +++ b/catalog-entities/marketplace/plugins/azure-container-registry.yaml @@ -21,7 +21,9 @@ metadata: spec: author: Red Hat publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: diff --git a/catalog-entities/marketplace/plugins/azure-devops.yaml b/catalog-entities/marketplace/plugins/azure-devops.yaml index 39268fd3c7..937eb5c0b7 100644 --- a/catalog-entities/marketplace/plugins/azure-devops.yaml +++ b/catalog-entities/marketplace/plugins/azure-devops.yaml @@ -26,7 +26,9 @@ metadata: spec: author: Backstage Community publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: diff --git a/catalog-entities/marketplace/plugins/azure-repositories.yaml b/catalog-entities/marketplace/plugins/azure-repositories.yaml index 76d35344df..1b49446772 100644 --- a/catalog-entities/marketplace/plugins/azure-repositories.yaml +++ b/catalog-entities/marketplace/plugins/azure-repositories.yaml @@ -29,7 +29,9 @@ metadata: spec: author: Parfümerie Douglas publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: @@ -164,4 +166,4 @@ spec: for further details on the configuration required. packages: - - parfuemerie-douglas-scaffolder-backend-module-azure-repositorie + - parfuemerie-douglas-scaffolder-backend-module-azure-repositories diff --git a/catalog-entities/marketplace/plugins/azure-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/azure-scaffolder-actions.yaml index d9ebb16eb4..ae4d00156e 100644 --- a/catalog-entities/marketplace/plugins/azure-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/azure-scaffolder-actions.yaml @@ -22,7 +22,9 @@ metadata: url: https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-azure spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat description: | diff --git a/catalog-entities/marketplace/plugins/backstage-community-plugin-quay.yaml b/catalog-entities/marketplace/plugins/backstage-community-plugin-quay.yaml index 8da20c58f2..8330305ac6 100644 --- a/catalog-entities/marketplace/plugins/backstage-community-plugin-quay.yaml +++ b/catalog-entities/marketplace/plugins/backstage-community-plugin-quay.yaml @@ -24,7 +24,9 @@ metadata: about the containers associated with the compenents in your software catalog. spec: author: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/bitbucket-cloud-catalog-integration.yaml b/catalog-entities/marketplace/plugins/bitbucket-cloud-catalog-integration.yaml index e43800d72f..d4c0251e7c 100644 --- a/catalog-entities/marketplace/plugins/bitbucket-cloud-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/bitbucket-cloud-catalog-integration.yaml @@ -25,7 +25,9 @@ spec: publisher: Red Hat author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active description: | diff --git a/catalog-entities/marketplace/plugins/bitbucket-cloud-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/bitbucket-cloud-scaffolder-actions.yaml index a76231c201..ef653a2a1f 100644 --- a/catalog-entities/marketplace/plugins/bitbucket-cloud-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/bitbucket-cloud-scaffolder-actions.yaml @@ -25,7 +25,9 @@ spec: publisher: Red Hat author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active description: | diff --git a/catalog-entities/marketplace/plugins/bitbucket-server-catalog-integration.yaml b/catalog-entities/marketplace/plugins/bitbucket-server-catalog-integration.yaml index c1a782f2cd..2f1532fd20 100644 --- a/catalog-entities/marketplace/plugins/bitbucket-server-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/bitbucket-server-catalog-integration.yaml @@ -25,7 +25,9 @@ spec: publisher: Red Hat author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active description: | diff --git a/catalog-entities/marketplace/plugins/bitbucket-server-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/bitbucket-server-scaffolder-actions.yaml index 771e8c3044..d9bdd36056 100644 --- a/catalog-entities/marketplace/plugins/bitbucket-server-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/bitbucket-server-scaffolder-actions.yaml @@ -25,7 +25,9 @@ spec: publisher: Red Hat author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active description: | diff --git a/catalog-entities/marketplace/plugins/bulk-import.yaml b/catalog-entities/marketplace/plugins/bulk-import.yaml index c00fe131d2..f39980f855 100644 --- a/catalog-entities/marketplace/plugins/bulk-import.yaml +++ b/catalog-entities/marketplace/plugins/bulk-import.yaml @@ -27,7 +27,9 @@ metadata: spec: author: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/catalog-integrations.yaml b/catalog-entities/marketplace/plugins/catalog-integrations.yaml deleted file mode 100644 index 30fd650bc7..0000000000 --- a/catalog-entities/marketplace/plugins/catalog-integrations.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json -apiVersion: extensions.backstage.io/v1alpha1 -kind: Plugin -metadata: - name: catalog-integrations - namespace: rhdh - title: Software Catalog Integrations - description: | - A list of common Backstage Software Catalog extensions. - annotations: - extensions.backstage.io/pre-installed: 'true' - tags: - - software-catalog -spec: - description: | - A grouping of common Backstage Software Catalog extensions. These extensions are used to integrate with various - systems and services to provide a more complete view of your software ecosystem. - - packages: - - backstage-community-plugin-catalog-backend-module-keycloak - - backstage-community-plugin-catalog-backend-module-pingidentity - - backstage-community-plugin-catalog-backend-module-scaffolder-re - - backstage-plugin-catalog-backend-module-bitbucket-cloud - - backstage-plugin-catalog-backend-module-bitbucket-server - - backstage-plugin-catalog-backend-module-github-org - - backstage-plugin-catalog-backend-module-github - - backstage-plugin-catalog-backend-module-gitlab-org - - backstage-plugin-catalog-backend-module-gitlab - - backstage-plugin-catalog-backend-module-ldap - - backstage-plugin-catalog-backend-module-msgraph diff --git a/catalog-entities/marketplace/plugins/contrib-techdocs-addons.yaml b/catalog-entities/marketplace/plugins/contrib-techdocs-addons.yaml index 15bea6867e..da78dbc857 100644 --- a/catalog-entities/marketplace/plugins/contrib-techdocs-addons.yaml +++ b/catalog-entities/marketplace/plugins/contrib-techdocs-addons.yaml @@ -23,7 +23,9 @@ metadata: url: https://github.com/backstage/backstage/tree/master/plugins/techdocs-module-addons-contrib spec: author: Backstage Community - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat categories: diff --git a/catalog-entities/marketplace/plugins/datadog.yaml b/catalog-entities/marketplace/plugins/datadog.yaml index a9882e65fe..8e1a9e9802 100644 --- a/catalog-entities/marketplace/plugins/datadog.yaml +++ b/catalog-entities/marketplace/plugins/datadog.yaml @@ -25,7 +25,9 @@ spec: authors: - name: Roadie url: https://roadie.io/ - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat categories: diff --git a/catalog-entities/marketplace/plugins/dynatrace-commercial.yaml b/catalog-entities/marketplace/plugins/dynatrace-commercial.yaml index 802201b7da..716d13ca89 100644 --- a/catalog-entities/marketplace/plugins/dynatrace-commercial.yaml +++ b/catalog-entities/marketplace/plugins/dynatrace-commercial.yaml @@ -26,7 +26,9 @@ metadata: spec: author: Dynatrace - support: production + support: + provider: Dynatrace + level: generally-available lifecycle: active publisher: Dynatrace diff --git a/catalog-entities/marketplace/plugins/dynatrace-community.yaml b/catalog-entities/marketplace/plugins/dynatrace-community.yaml index 981102ee93..6ebc96ee97 100644 --- a/catalog-entities/marketplace/plugins/dynatrace-community.yaml +++ b/catalog-entities/marketplace/plugins/dynatrace-community.yaml @@ -24,7 +24,9 @@ metadata: spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/extensions.yaml b/catalog-entities/marketplace/plugins/extensions.yaml index 2a27bfdd1c..f5a8805438 100644 --- a/catalog-entities/marketplace/plugins/extensions.yaml +++ b/catalog-entities/marketplace/plugins/extensions.yaml @@ -25,7 +25,9 @@ metadata: spec: author: Red Hat publisher: Red Hat - support: dev-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: diff --git a/catalog-entities/marketplace/plugins/gerrit-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/gerrit-scaffolder-actions.yaml index 22bb13f4a9..ea2d49fdff 100644 --- a/catalog-entities/marketplace/plugins/gerrit-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/gerrit-scaffolder-actions.yaml @@ -27,7 +27,9 @@ spec: - name: Backstage Community publisher: Red Hat lifecycle: active - support: tech-preview + support: + provider: Red Hat + level: tech-preview description: | This plugin contains a collection of actions for working with Gerrit diff --git a/catalog-entities/marketplace/plugins/github-actions.yaml b/catalog-entities/marketplace/plugins/github-actions.yaml index c83fa0cb01..54f30aaec9 100644 --- a/catalog-entities/marketplace/plugins/github-actions.yaml +++ b/catalog-entities/marketplace/plugins/github-actions.yaml @@ -21,7 +21,9 @@ metadata: url: https://github.com/backstage/community-plugins/tree/main/workspaces/github-actions/plugins/github-actions spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat categories: diff --git a/catalog-entities/marketplace/plugins/github-catalog-integration.yaml b/catalog-entities/marketplace/plugins/github-catalog-integration.yaml index 3a327e8f8c..0da113fc13 100644 --- a/catalog-entities/marketplace/plugins/github-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/github-catalog-integration.yaml @@ -29,7 +29,9 @@ metadata: spec: author: Backstage Community - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/github-insights.yaml b/catalog-entities/marketplace/plugins/github-insights.yaml index 41114d13af..89785d1f7c 100644 --- a/catalog-entities/marketplace/plugins/github-insights.yaml +++ b/catalog-entities/marketplace/plugins/github-insights.yaml @@ -24,7 +24,9 @@ spec: authors: - name: Roadie url: https://roadie.io/ - support: production + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat categories: diff --git a/catalog-entities/marketplace/plugins/github-issues.yaml b/catalog-entities/marketplace/plugins/github-issues.yaml index 5964ce028a..1c22e5c2dd 100644 --- a/catalog-entities/marketplace/plugins/github-issues.yaml +++ b/catalog-entities/marketplace/plugins/github-issues.yaml @@ -24,7 +24,9 @@ spec: - Code Quality author: Backstage Community - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat highlights: diff --git a/catalog-entities/marketplace/plugins/github-org-catalog-integration.yaml b/catalog-entities/marketplace/plugins/github-org-catalog-integration.yaml index 7c11cb5736..8d6367d7f0 100644 --- a/catalog-entities/marketplace/plugins/github-org-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/github-org-catalog-integration.yaml @@ -27,7 +27,9 @@ metadata: spec: author: Backstage Community - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/github-pull-requests.yaml b/catalog-entities/marketplace/plugins/github-pull-requests.yaml index 13a09310ba..0ef9d27596 100644 --- a/catalog-entities/marketplace/plugins/github-pull-requests.yaml +++ b/catalog-entities/marketplace/plugins/github-pull-requests.yaml @@ -25,7 +25,9 @@ spec: authors: - name: Roadie url: https://roadie.io/ - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/github-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/github-scaffolder-actions.yaml index b2fe260085..5da052f6f5 100644 --- a/catalog-entities/marketplace/plugins/github-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/github-scaffolder-actions.yaml @@ -14,7 +14,9 @@ spec: categories: - Scaffolder author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/gitlab-catalog-cards.yaml b/catalog-entities/marketplace/plugins/gitlab-catalog-cards.yaml index d8a7c68275..fbb081b29c 100644 --- a/catalog-entities/marketplace/plugins/gitlab-catalog-cards.yaml +++ b/catalog-entities/marketplace/plugins/gitlab-catalog-cards.yaml @@ -21,7 +21,9 @@ metadata: spec: author: ImmobiliareLabs publisher: Red Hat - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: diff --git a/catalog-entities/marketplace/plugins/gitlab-catalog-integration.yaml b/catalog-entities/marketplace/plugins/gitlab-catalog-integration.yaml index 1bea814c7a..cb6d5ed3bb 100644 --- a/catalog-entities/marketplace/plugins/gitlab-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/gitlab-catalog-integration.yaml @@ -28,7 +28,9 @@ spec: author: Backstage Community publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: - Software Catalog diff --git a/catalog-entities/marketplace/plugins/gitlab-org-catalog-integration.yaml b/catalog-entities/marketplace/plugins/gitlab-org-catalog-integration.yaml index d93358d096..286669f120 100644 --- a/catalog-entities/marketplace/plugins/gitlab-org-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/gitlab-org-catalog-integration.yaml @@ -27,7 +27,9 @@ spec: author: Backstage Community publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: - Software Catalog diff --git a/catalog-entities/marketplace/plugins/gitlab-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/gitlab-scaffolder-actions.yaml index be8b7aff06..030df0d5b2 100644 --- a/catalog-entities/marketplace/plugins/gitlab-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/gitlab-scaffolder-actions.yaml @@ -24,7 +24,9 @@ metadata: url: https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-gitlab spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat categories: diff --git a/catalog-entities/marketplace/plugins/global-floating-action-button.yaml b/catalog-entities/marketplace/plugins/global-floating-action-button.yaml index 9e4f554342..1015a43f25 100644 --- a/catalog-entities/marketplace/plugins/global-floating-action-button.yaml +++ b/catalog-entities/marketplace/plugins/global-floating-action-button.yaml @@ -22,7 +22,9 @@ metadata: url: https://github.com/redhat-developer/rhdh/tree/main/dynamic-plugins/wrappers/ spec: author: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/global-header.yaml b/catalog-entities/marketplace/plugins/global-header.yaml index fbe46ef742..0decc422dd 100644 --- a/catalog-entities/marketplace/plugins/global-header.yaml +++ b/catalog-entities/marketplace/plugins/global-header.yaml @@ -25,7 +25,9 @@ metadata: spec: author: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/home-page.yaml b/catalog-entities/marketplace/plugins/home-page.yaml index 08d3eae232..9b3e57b936 100644 --- a/catalog-entities/marketplace/plugins/home-page.yaml +++ b/catalog-entities/marketplace/plugins/home-page.yaml @@ -23,7 +23,9 @@ metadata: url: https://github.com/redhat-developer/rhdh/tree/main/dynamic-plugins/wrappers/ spec: author: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/http-request-scaffolder-action.yaml b/catalog-entities/marketplace/plugins/http-request-scaffolder-action.yaml index fdbb0e7051..22944355e2 100644 --- a/catalog-entities/marketplace/plugins/http-request-scaffolder-action.yaml +++ b/catalog-entities/marketplace/plugins/http-request-scaffolder-action.yaml @@ -25,7 +25,9 @@ metadata: spec: author: Roadie publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: diff --git a/catalog-entities/marketplace/plugins/ibm-apiconnect-backstage.yaml b/catalog-entities/marketplace/plugins/ibm-apiconnect-backstage.yaml new file mode 100644 index 0000000000..7bfd73f04a --- /dev/null +++ b/catalog-entities/marketplace/plugins/ibm-apiconnect-backstage.yaml @@ -0,0 +1,52 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: apic-backstage + namespace: apiconnect + title: API Connect Backstage Plugin + annotations: + extensions.backstage.io/pre-installed: 'true' # this means the plugin yaml is preinstalled, not the plugin itself + extensions.backstage.io/certified-by: Red Hat # For certified plugins + links: + - title: Plugin Overview (README) + url: https://github.com/ibm-apiconnect/backstage/blob/main/plugins/apic-backstage/README.md + - title: Documentation for Red Hat Developer Hub + url: https://www.ibm.com/docs/en/api-connect/10.0.x_cd?topic=uacbpi-enabling-api-connect-plug-in-red-hat-developer-hub + - title: Source Code + url: https://github.com/ibm-apiconnect/backstage/tree/main/plugins/apic-backstage + tags: + - apis + - apiconnect # Used for filtering + description: | + The single page view of all APIs in an enterprise estate for quick discovery and easy navigation of API assets within Backstage. +spec: + author: IBM + support: + provider: IBM + level: generally-available + lifecycle: active + publisher: IBM + + categories: + - API Management # One category will show up on the tile view + + description: | + The API Connect plug-in consolidates all your API Connect instances into a single location. By using the provider API, the plug-in groups data from each instance and displays it in a centralized dashboard. This grouping of data provides a clear overview of data distribution between different API Connect instances. + The plug-in is valid for IBM® API Connect version 10.0.8.0 and later. + + ## Adding The Plugin To Red Hat Developer Hub + + See the [IBM API Connect documentation](https://www.ibm.com/docs/en/api-connect/10.0.x_cd?topic=uacbpi-enabling-api-connect-plug-in-red-hat-developer-hub) + for further instructions on how to add, enable, configure, and remove plugins in your instance. + + ## Configuring The Plugin ## + + See [APIC Backstage Plugin ](https://github.com/ibm-apiconnect/backstage/blob/main/plugins/apic-backstage/README.md) for configuration details. + + + icon: data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzIgMzIiPgogIDxkZWZzPgogICAgPHN0eWxlPgogICAgICAuY2xzLTEgewogICAgICAgIGZpbGw6IHVybCgjbGluZWFyLWdyYWRpZW50KTsKICAgICAgfQoKICAgICAgLmNscy0yIHsKICAgICAgICBtYXNrOiB1cmwoI21hc2spOwogICAgICB9CgogICAgICAuY2xzLTMgewogICAgICAgIGZpbGw6ICNmNGY0ZjQ7CiAgICAgIH0KCiAgICAgIC5jbHMtNCB7CiAgICAgICAgZmlsbDogI2ZmZjsKICAgICAgfQoKICAgICAgLmNscy01IHsKICAgICAgICBmaWxsOiB1cmwoI2xpbmVhci1ncmFkaWVudC0zKTsKICAgICAgfQoKICAgICAgLmNscy02IHsKICAgICAgICBmaWxsOiB1cmwoI2xpbmVhci1ncmFkaWVudC0yKTsKICAgICAgfQogICAgPC9zdHlsZT4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0ibGluZWFyLWdyYWRpZW50IiB4MT0iMjYuNSIgeTE9IjMwIiB4Mj0iMjYuNSIgeTI9IjgiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KICAgICAgPHN0b3Agb2Zmc2V0PSIuMyIgc3RvcC1jb2xvcj0iIzAwMCIvPgogICAgICA8c3RvcCBvZmZzZXQ9Ii45NSIgc3RvcC1jb2xvcj0iIzAwMCIgc3RvcC1vcGFjaXR5PSIwIi8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPGxpbmVhckdyYWRpZW50IGlkPSJsaW5lYXItZ3JhZGllbnQtMiIgeDE9IjY3My41IiB5MT0iNDAiIHgyPSI2NzMuNSIgeTI9IjE4IiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKC02NjggLTE2KSIgeGxpbms6aHJlZj0iI2xpbmVhci1ncmFkaWVudCIvPgogICAgPG1hc2sgaWQ9Im1hc2siIHg9IjEiIHk9IjIiIHdpZHRoPSIzMCIgaGVpZ2h0PSIyOCIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgICAgIDxnPgogICAgICAgIDxnPgogICAgICAgICAgPHBhdGggY2xhc3M9ImNscy00IiBkPSJNMjQuNTIsMjcuMTFjNS4wMi0zLjg1LDYuODMtMTAuNjIsNC40MS0xNi40N0MyNS45OCwzLjUxLDE3Ljc3LC4xMSwxMC42NCwzLjA3bC43NywxLjg1YzYuMTEtMi41MywxMy4xNSwuMzgsMTUuNjgsNi40OSwyLjA4LDUuMDEsLjUyLDEwLjgyLTMuNzgsMTQuMTFsMS4yMiwxLjU5WiIvPgogICAgICAgICAgPHBhdGggY2xhc3M9ImNscy00IiBkPSJNMTAuNjUsMjguOTNjMy4zMSwxLjM3LDcuMTUsMS40OCwxMC43MSwwbC0uNzctMS44NWMtNi4xMSwyLjUzLTEzLjE1LS4zOC0xNS42OC02LjQ5LTIuMDgtNS4wMS0uNTItMTAuODIsMy43OC0xNC4xMWwtMS4yMi0xLjU5QzIuNDYsOC43NCwuNjQsMTUuNTEsMy4wNywyMS4zNmMxLjQ4LDMuNTcsNC4yNyw2LjIsNy41OCw3LjU3WiIvPgogICAgICAgIDwvZz4KICAgICAgICA8cmVjdCBjbGFzcz0iY2xzLTEiIHg9IjIyIiB5PSI4IiB3aWR0aD0iOSIgaGVpZ2h0PSIyMiIvPgogICAgICAgIDxyZWN0IGNsYXNzPSJjbHMtNiIgeD0iMSIgeT0iMiIgd2lkdGg9IjkiIGhlaWdodD0iMjIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExIDI2KSByb3RhdGUoMTgwKSIvPgogICAgICA8L2c+CiAgICA8L21hc2s+CiAgICA8bGluZWFyR3JhZGllbnQgaWQ9ImxpbmVhci1ncmFkaWVudC0zIiB4MT0iMCIgeTE9IjMyIiB4Mj0iMzIiIHkyPSIwIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgICAgIDxzdG9wIG9mZnNldD0iLjEiIHN0b3AtY29sb3I9IiMzZGRiZDkiLz4KICAgICAgPHN0b3Agb2Zmc2V0PSIuOSIgc3RvcC1jb2xvcj0iIzQ1ODlmZiIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICA8L2RlZnM+CiAgPGcgaWQ9IkJ1aWxkX2ljb25faGVyZSIgZGF0YS1uYW1lPSJCdWlsZCBpY29uIGhlcmUiPgogICAgPGc+CiAgICAgIDxnIGNsYXNzPSJjbHMtMiI+CiAgICAgICAgPHJlY3QgY2xhc3M9ImNscy01IiB3aWR0aD0iMzIiIGhlaWdodD0iMzIiLz4KICAgICAgPC9nPgogICAgICA8cGF0aCBjbGFzcz0iY2xzLTMiIGQ9Ik0yNSwyM2MtMS4xMiwwLTIsLjg4LTIsMnMuODgsMiwyLDIsMi0uODgsMi0yLS44OC0yLTItMloiLz4KICAgICAgPHBhdGggY2xhc3M9ImNscy0zIiBkPSJNNyw1Yy0xLjEyLDAtMiwuODgtMiwycy44OCwyLDIsMiwyLS44OCwyLTItLjg4LTItMi0yWiIvPgogICAgICA8cGF0aCBjbGFzcz0iY2xzLTMiIGQ9Ik0yMiwxMmMtMS4xNCwwLTIuMTYsLjQ4LTIuODksMS4yNWwtMy4xNi0xLjc2Yy4wMy0uMTYsLjA1LS4zMywuMDUtLjUsMC0xLjY1LTEuMzUtMy0zLTNzLTMsMS4zNS0zLDNjMCwxLjA5LC41OSwyLjA0LDEuNDcsMi41N2wtLjksNC40OGMtMS40NSwuMjEtMi41NywxLjQ1LTIuNTcsMi45NiwwLDEuNjUsMS4zNSwzLDMsM3MzLTEuMzUsMy0zYzAtLjA5LS4wMi0uMTctLjAzLS4yNWw0LjkzLTIuMjRjLjczLC45LDEuODQsMS41LDMuMDksMS41LDIuMjEsMCw0LTEuNzksNC00cy0xLjc5LTQtNC00Wm0tOS0yYy41NSwwLDEsLjQ1LDEsMXMtLjQ1LDEtMSwxLTEtLjQ1LTEtMSwuNDUtMSwxLTFabS0yLDEyYy0uNTUsMC0xLS40NS0xLTFzLjQ1LTEsMS0xYy40MSwwLC43NywuMjUsLjkyLC42MWgwYy4wNSwuMTIsLjA4LC4yNSwuMDgsLjM5LDAsLjU1LS40NSwxLTEsMVptMi4xNi0zLjA4Yy0uMTgtLjE5LS4zOS0uMzUtLjYyLS40OWwuOS00LjQ4Yy41OS0uMDksMS4xMi0uMzQsMS41NS0uNzJsMy4xNywxLjc2Yy0uMDgsLjMyLS4xNCwuNjUtLjE0LDEsMCwuMjQsLjAzLC40NiwuMDcsLjY5bC00LjkxLDIuMjNabTguODQtLjkyYy0xLjEsMC0yLS45LTItMnMuOS0yLDItMiwyLC45LDIsMi0uOSwyLTIsMloiLz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPg== + + + packages: # link to the name used in the associated package documents in ../packages + - apic-backstage \ No newline at end of file diff --git a/catalog-entities/marketplace/plugins/jenkins.yaml b/catalog-entities/marketplace/plugins/jenkins.yaml index c9694079aa..6fc3b02b09 100644 --- a/catalog-entities/marketplace/plugins/jenkins.yaml +++ b/catalog-entities/marketplace/plugins/jenkins.yaml @@ -25,7 +25,9 @@ spec: authors: - name: '@timja' url: https://github.com/timja - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat categories: diff --git a/catalog-entities/marketplace/plugins/jfrog-artifactory.yaml b/catalog-entities/marketplace/plugins/jfrog-artifactory.yaml index ed783848d7..7b2fe35945 100644 --- a/catalog-entities/marketplace/plugins/jfrog-artifactory.yaml +++ b/catalog-entities/marketplace/plugins/jfrog-artifactory.yaml @@ -16,7 +16,9 @@ metadata: - url: https://issues.redhat.com/browse/RHIDP title: Bugs spec: - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat author: Red Hat diff --git a/catalog-entities/marketplace/plugins/jira.yaml b/catalog-entities/marketplace/plugins/jira.yaml index b18b17541c..0ac1701371 100644 --- a/catalog-entities/marketplace/plugins/jira.yaml +++ b/catalog-entities/marketplace/plugins/jira.yaml @@ -23,7 +23,9 @@ spec: url: https://roadie.io/ publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: - Planning diff --git a/catalog-entities/marketplace/plugins/keycloak-catalog-integration.yaml b/catalog-entities/marketplace/plugins/keycloak-catalog-integration.yaml index b9a08b4c84..e05dbe03e0 100644 --- a/catalog-entities/marketplace/plugins/keycloak-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/keycloak-catalog-integration.yaml @@ -28,7 +28,9 @@ metadata: spec: author: Red Hat publisher: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active categories: diff --git a/catalog-entities/marketplace/plugins/kubernetes-backend.yaml b/catalog-entities/marketplace/plugins/kubernetes-backend.yaml index 695bd4dec0..ad1d003957 100644 --- a/catalog-entities/marketplace/plugins/kubernetes-backend.yaml +++ b/catalog-entities/marketplace/plugins/kubernetes-backend.yaml @@ -22,7 +22,9 @@ metadata: spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/kubernetes-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/kubernetes-scaffolder-actions.yaml index 3a34d88d1a..62aa2380fb 100644 --- a/catalog-entities/marketplace/plugins/kubernetes-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/kubernetes-scaffolder-actions.yaml @@ -24,7 +24,9 @@ metadata: spec: author: Backstage Community - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/kubernetes.yaml b/catalog-entities/marketplace/plugins/kubernetes.yaml index 028015931a..a148e47d43 100644 --- a/catalog-entities/marketplace/plugins/kubernetes.yaml +++ b/catalog-entities/marketplace/plugins/kubernetes.yaml @@ -22,7 +22,9 @@ metadata: spec: author: Backstage Community - support: tech-preview # The frontend is tech-preview for RHDH + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/ldap-catalog-integration.yaml b/catalog-entities/marketplace/plugins/ldap-catalog-integration.yaml index 5df779797a..b0aa590036 100644 --- a/catalog-entities/marketplace/plugins/ldap-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/ldap-catalog-integration.yaml @@ -27,7 +27,9 @@ metadata: spec: author: Backstage Community - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/lighthouse.yaml b/catalog-entities/marketplace/plugins/lighthouse.yaml index 777b80b8c1..80506b1809 100644 --- a/catalog-entities/marketplace/plugins/lighthouse.yaml +++ b/catalog-entities/marketplace/plugins/lighthouse.yaml @@ -26,7 +26,9 @@ metadata: spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/lightspeed.yaml b/catalog-entities/marketplace/plugins/lightspeed.yaml new file mode 100644 index 0000000000..d4eb4d8c6f --- /dev/null +++ b/catalog-entities/marketplace/plugins/lightspeed.yaml @@ -0,0 +1,424 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: lightspeed + namespace: rhdh + title: Red Hat Developer Lightspeed for Red Hat Developer Hub + annotations: + extensions.backstage.io/pre-installed: 'true' # For plugins contained in the RHDH image + links: + - title: Homepage + url: https://red.ht/rhdh + - title: Bugs + url: https://issues.redhat.com/browse/RHDHPAI + - title: Documentation for Red Hat Developer Hub + url: https://docs.redhat.com/en/documentation/red_hat_developer_hub + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/lightspeed/plugins + tags: + - ai-assistant + - developer-tools + description: | + Red Hat Developer Lightspeed for Red Hat Developer Hub is a virtual assistant powered by generative AI that offers in-depth insights into RHDH, including its wide range of capabilities. You can interact with this assistant to explore and learn more about RHDH in greater detail. +spec: + author: Red Hat + support: + provider: Red Hat + level: dev-preview + lifecycle: active + publisher: Red Hat + + categories: + - AI Assistant + highlights: + - Generative AI-Powered Virtual Assistant + - Deep Insight into RHDH and OpenShift + - Start new chats, view chat history, and delete chats + - Allows users to change the underlying LLM model for responses + - Generates responses based on comprehensive documentation for RHDH + + + description: | + # Developer Lightspeed + + Red Hat Developer Lightspeed for Red Hat Developer Hub is a virtual assistant powered by generative AI that offers in-depth insights into Red Hat Developer Hub, including its wide range of capabilities. You can interact with this assistant to explore and learn more about Red Hat Developer Hub in greater detail. + + Developer Lightspeed for Developer Hub provides a natural language interface within the Red Hat Developer Hub console, helping you easily find information about the product, understand its features, and get answers to your questions as they come up. + + Developer Lightspeed for Developer Hub consists of two main components: + + - **Frontend Plugin** (`@red-hat-developer-hub/backstage-plugin-lightspeed`): Provides the user interface and chat experience + - **Backend Plugin** (`@red-hat-developer-hub/backstage-plugin-lightspeed-backend`): Handles server-side logic, communication with the service sidecar, and API endpoints + + ### Key Features + + - 🤖 **LLM Integration**: Connect to any LLM server with OpenAI API compatibility (by configuring the sidecar server) + - 🔒 **Security**: Built-in question validation to restrict chats to Red Hat Developer Hub related topics + - 💬 **Conversational Interface**: Chat-based interaction with AI assistance + - 🎯 **Custom Prompts**: Configurable sample and system prompts for better user experience + - 🔐 **Permission Framework**: Full RBAC support for access control + - 📊 **Session Management**: Handle user conversations and history + + ## Usage + + + ### For Administrators + + 1. **LLM Server Configuration**: Configure the LLM servers with OpenAI API compatibility in the backend plugin configuration + 2. **Configurable Prompts**: Administrators can customize the welcome prompts to guide users with specific tasks or questions and system prompts to set the context for the AI assistant + + ### For End Users + + 1. **Access the Plugin**: Navigate to your Red Hat developer Hub portal and click on the "Lightspeed" item in the navigation sidebar + 2. **Start Chatting**: Begin asking questions about Red Hat Developer hub, or other development topics (depending on your question validation configuration choice) + 4. **Manage Chats**: Your chat history is maintained for the session, you can start new chats, view history, and delete chats as needed. + + ### Supported Topics + + When question validation is enabled (default), the plugin is optimized for: + - Red Hat Developer Hub (RHDH) + + ## Support + + - **Documentation**: [Red Hat Developer Hub Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) + - **Frontend Plugin**: [Frontend README](https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/lightspeed/plugins/lightspeed/README.md) + - **Backend Plugin**: [Backend README](https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/lightspeed/plugins/lightspeed-backend/README.md) + - **Issues**: [Jira Issues](https://issues.redhat.com/browse/RHDHBUGS) + + # Images are base 64 encoded SVGs (below is a blank square from the mockup) + icon: data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIGlkPSJ1dWlkLTQ2NzAxNDY4LTY2NDEtNDhjYi05ODdhLWFkOGFhYWE0Y2M1NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMzggMzgiPjxkZWZzPjxzdHlsZT4udXVpZC0wNWM4ZjUzZC0zOTZhLTRhNzctYjYxMC00Y2FlMTYwN2IzN2Z7ZmlsbDojZTAwO30udXVpZC0wNThiNjM1ZC1iNjFjLTQ2ZjQtOTgyYS1hOTFkNmEyMjYzZWJ7ZmlsbDojZmZmO30udXVpZC0wMTY4MTg4Yy1kMGE2LTQ5NmUtYTJkOC01Y2Q2ZWUzMGRjYjJ7ZmlsbDojZTBlMGUwO308L3N0eWxlPjwvZGVmcz48cGF0aCBjbGFzcz0idXVpZC0wNThiNjM1ZC1iNjFjLTQ2ZjQtOTgyYS1hOTFkNmEyMjYzZWIiIGQ9Im0yOCwxSDEwQzUuMDI5NDQsMSwxLDUuMDI5NDQsMSwxMHYxOGMwLDQuOTcwNTcsNC4wMjk0NCw5LDksOWgxOGM0Ljk3MDU2LDAsOS00LjAyOTQzLDktOVYxMGMwLTQuOTcwNTYtNC4wMjk0NC05LTktOWgwWiIvPjxwYXRoIGNsYXNzPSJ1dWlkLTAxNjgxODhjLWQwYTYtNDk2ZS1hMmQ4LTVjZDZlZTMwZGNiMiIgZD0ibTI4LDIuMjVjNC4yNzMzMiwwLDcuNzUsMy40NzY2NCw3Ljc1LDcuNzV2MThjMCw0LjI3MzM2LTMuNDc2NjgsNy43NS03Ljc1LDcuNzVIMTBjLTQuMjczMzIsMC03Ljc1LTMuNDc2NjQtNy43NS03Ljc1VjEwYzAtNC4yNzMzNiwzLjQ3NjY4LTcuNzUsNy43NS03Ljc1aDE4bTAtMS4yNUgxMEM1LjAyOTQyLDEsMSw1LjAyOTQ0LDEsMTB2MThjMCw0Ljk3MDU3LDQuMDI5NDIsOSw5LDloMThjNC45NzA1OCwwLDktNC4wMjk0Myw5LTlWMTBjMC00Ljk3MDU2LTQuMDI5NDItOS05LTloMFoiLz48cGF0aCBjbGFzcz0idXVpZC0wNWM4ZjUzZC0zOTZhLTRhNzctYjYxMC00Y2FlMTYwN2IzN2YiIGQ9Im0yMCwxNS42MjVjLS4zNDQ3MywwLS42MjUtLjI4MDI3LS42MjUtLjYyNXYtN2MwLS4zNDQ3My4yODAyNy0uNjI1LjYyNS0uNjI1cy42MjUuMjgwMjcuNjI1LjYyNXY3YzAsLjM0NDczLS4yODAyNy42MjUtLjYyNS42MjVaIi8+PHBhdGggY2xhc3M9InV1aWQtMDVjOGY1M2QtMzk2YS00YTc3LWI2MTAtNGNhZTE2MDdiMzdmIiBkPSJtMTYsMTkuNjI1aC03Yy0uMzQ0NzMsMC0uNjI1LS4yODAyNy0uNjI1LS42MjVzLjI4MDI3LS42MjUuNjI1LS42MjVoN2MuMzQ0NzMsMCwuNjI1LjI4MDI3LjYyNS42MjVzLS4yODAyNy42MjUtLjYyNS42MjVaIi8+PHBhdGggY2xhc3M9InV1aWQtMDVjOGY1M2QtMzk2YS00YTc3LWI2MTAtNGNhZTE2MDdiMzdmIiBkPSJtMjAsMzAuNjI1Yy0uMzQ0NzMsMC0uNjI1LS4yODAyNy0uNjI1LS42MjV2LTdjMC0uMzQ0NzMuMjgwMjctLjYyNS42MjUtLjYyNXMuNjI1LjI4MDI3LjYyNS42MjV2N2MwLC4zNDQ3My0uMjgwMjcuNjI1LS42MjUuNjI1WiIvPjxwYXRoIGQ9Im0zMC41NzY1NCwxOS4yMzk0NGMuMDI3OTUtLjA2NzY5LjAzOTU1LS4xMzk0Ny4wNDI4NS0uMjExNDkuMDAwNDktLjAwOTgzLjAwNTYyLS4wMTgwNy4wMDU2Mi0uMDI3OTVzLS4wMDUxMy0uMDE4MTMtLjAwNTYyLS4wMjc5NWMtLjAwMzMtLjA3MjAyLS4wMTQ4OS0uMTQzOC0uMDQyODUtLjIxMTQ5LS4wMjAwMi0uMDQ3OTEtLjA1MzgzLS4wODY2Ny0uMDg0NDctLjEyNzc1LS4wMTgwNy0uMDI0NDgtLjAyNzU5LS4wNTMwNC0uMDQ5NjgtLjA3NTJsLTItMmMtLjI0NDE0LS4yNDQxNC0uNjQwNjItLjI0NDE0LS44ODQ3NywwLS4yNDMxNi4yNDQxNC0uMjQzMTYuNjQwNjIsMCwuODg0NzdsLjkzMzIzLjkzMjYyaC05LjQ5MDg0Yy0uMzQ0NzMsMC0uNjI1LjI4MDI3LS42MjUuNjI1cy4yODAyNy42MjUuNjI1LjYyNWg5LjQ5MDg0bC0uOTMzMjMuOTMyNjJjLS4yNDMxNi4yNDQxNC0uMjQzMTYuNjQwNjIsMCwuODg0NzcuMTIyMDcuMTIyMDcuMjgyMjMuMTgyNjIuNDQyMzguMTgyNjJzLjMyMDMxLS4wNjA1NS40NDIzOC0uMTgyNjJsMi0yYy4wMjIwOS0uMDIyMTYuMDMxNjItLjA1MDcyLjA0OTY4LS4wNzUyLjAzMDY0LS4wNDEwOC4wNjQ0NS0uMDc5ODMuMDg0NDctLjEyNzc1WiIvPjxwYXRoIGQ9Im0xNywxNi42MjVjLS4xNjAxNiwwLS4zMjAzMS0uMDYwNTUtLjQ0MjM4LS4xODI2MmwtNC00Yy0uMjQzMTYtLjI0NDE0LS4yNDMxNi0uNjQwNjIsMC0uODg0NzcuMjQ0MTQtLjI0NDE0LjY0MDYyLS4yNDQxNC44ODQ3NywwbDQsNGMuMjQzMTYuMjQ0MTQuMjQzMTYuNjQwNjIsMCwuODg0NzctLjEyMjA3LjEyMjA3LS4yODIyMy4xODI2Mi0uNDQyMzguMTgyNjJaIi8+PHBhdGggZD0ibTEzLDI2LjYyNWMtLjE2MDE2LDAtLjMyMDMxLS4wNjA1NS0uNDQyMzgtLjE4MjYyLS4yNDMxNi0uMjQ0MTQtLjI0MzE2LS42NDA2MiwwLS44ODQ3N2w0LTRjLjI0NDE0LS4yNDQxNC42NDA2Mi0uMjQ0MTQuODg0NzcsMCwuMjQzMTYuMjQ0MTQuMjQzMTYuNjQwNjIsMCwuODg0NzdsLTQsNGMtLjEyMjA3LjEyMjA3LS4yODIyMy4xODI2Mi0uNDQyMzguMTgyNjJaIi8+PHBhdGggY2xhc3M9InV1aWQtMDVjOGY1M2QtMzk2YS00YTc3LWI2MTAtNGNhZTE2MDdiMzdmIiBkPSJtMTcuNDIzODMsMTMuNjI1Yy0uMjg4MDksMC0uNTQ3ODUtLjIwMTE3LS42MTAzNS0uNDk1MTJsLS40MjQ4LTJjLS4wNzEyOS0uMzM3ODkuMTQzNTUtLjY2OTkyLjQ4MTQ1LS43NDEyMS4zMzg4Ny0uMDc1Mi42Njk5Mi4xNDM1NS43NDEyMS40ODE0NWwuNDI0OCwyYy4wNzEyOS4zMzc4OS0uMTQzNTUuNjY5OTItLjQ4MTQ1Ljc0MTIxLS4wNDM5NS4wMDk3Ny0uMDg3ODkuMDEzNjctLjEzMDg2LjAxMzY3WiIvPjxwYXRoIGNsYXNzPSJ1dWlkLTA1YzhmNTNkLTM5NmEtNGE3Ny1iNjEwLTRjYWUxNjA3YjM3ZiIgZD0ibTE0LjAwMDk4LDE3LjA0OThjLS4wNDI5NywwLS4wODY5MS0uMDAzOTEtLjEzMDg2LS4wMTM2N2wtMi0uNDI0OGMtLjMzNzg5LS4wNzEyOS0uNTUyNzMtLjQwMzMyLS40ODE0NS0uNzQxMjEuMDcyMjctLjMzNzg5LjQwMjM0LS41NTg1OS43NDEyMS0uNDgxNDVsMiwuNDI0OGMuMzM3ODkuMDcxMjkuNTUyNzMuNDAzMzIuNDgxNDUuNzQxMjEtLjA2MjUuMjkzOTUtLjMyMjI3LjQ5NTEyLS42MTAzNS40OTUxMloiLz48cGF0aCBjbGFzcz0idXVpZC0wNWM4ZjUzZC0zOTZhLTRhNzctYjYxMC00Y2FlMTYwN2IzN2YiIGQ9Im0xNy4wMDA5OCwyNy42MjVjLS4wNDI5NywwLS4wODY5MS0uMDAzOTEtLjEzMDg2LS4wMTM2Ny0uMzM3ODktLjA3MTI5LS41NTI3My0uNDAzMzItLjQ4MTQ1LS43NDEyMWwuNDI0OC0yYy4wNzIyNy0uMzM3ODkuNDAxMzctLjU1NTY2Ljc0MTIxLS40ODE0NS4zMzc4OS4wNzEyOS41NTI3My40MDMzMi40ODE0NS43NDEyMWwtLjQyNDgsMmMtLjA2MjUuMjkzOTUtLjMyMjI3LjQ5NTEyLS42MTAzNS40OTUxMloiLz48cGF0aCBjbGFzcz0idXVpZC0wNWM4ZjUzZC0zOTZhLTRhNzctYjYxMC00Y2FlMTYwN2IzN2YiIGQ9Im0xMS45OTkwMiwyMi42MjVjLS4yODgwOSwwLS41NDc4NS0uMjAxMTctLjYxMDM1LS40OTUxMi0uMDcxMjktLjMzNzg5LjE0MzU1LS42Njk5Mi40ODE0NS0uNzQxMjFsMi0uNDI0OGMuMzQwODItLjA3NjE3LjY2OTkyLjE0MzU1Ljc0MTIxLjQ4MTQ1cy0uMTQzNTUuNjY5OTItLjQ4MTQ1Ljc0MTIxbC0yLC40MjQ4Yy0uMDQzOTUuMDA5NzctLjA4Nzg5LjAxMzY3LS4xMzA4Ni4wMTM2N1oiLz48cGF0aCBkPSJtOSwxNS42Mjk4OGMtLjE2MDE2LDAtLjMyMDMxLS4wNzAzMS0uNDQwNDMtLjE5MDQzLS4wNTk1Ny0uMDU5NTctLjA5OTYxLS4xMjAxMi0uMTM5NjUtLjE5OTIyLS4wMzAyNy0uMDgwMDgtLjA0OTgtLjE2MDE2LS4wNDk4LS4yNDAyMywwLS4xNjAxNi4wNjkzNC0uMzIwMzEuMTg5NDUtLjQ0MDQzLjIzMDQ3LS4yMjk0OS42NTAzOS0uMjQwMjMuODc5ODgsMCwuMTIwMTIuMTIwMTIuMTkwNDMuMjgwMjcuMTkwNDMuNDQwNDMsMCwuMDgwMDgtLjAyMDUxLjE2MDE2LS4wNDk4LjI0MDIzLS4wMzAyNy4wNzkxLS4wODAwOC4xMzk2NS0uMTQwNjIuMTk5MjItLjEyMDEyLjEyMDEyLS4yNzkzLjE5MDQzLS40Mzk0NS4xOTA0M1oiLz48cGF0aCBkPSJtOSwyMy42Mjk4OGMtLjE2MDE2LDAtLjMyMDMxLS4wNzAzMS0uNDQwNDMtLjE5MDQzLS4xMjAxMi0uMTA5MzgtLjE4OTQ1LS4yNzkzLS4xODk0NS0uNDM5NDVzLjA2OTM0LS4zMjAzMS4xODk0NS0uNDQwNDNjLjIzMDQ3LS4yMjk0OS42NDA2Mi0uMjQwMjMuODc5ODgsMCwuMTIwMTIuMTIwMTIuMTkwNDMuMjgwMjcuMTkwNDMuNDQwNDNzLS4wNzAzMS4zMzAwOC0uMTkwNDMuNDM5NDVjLS4xMjAxMi4xMjAxMi0uMjc5My4xOTA0My0uNDM5NDUuMTkwNDNaIi8+PC9zdmc+ + + packages: # link to the name used in the associated package documents in ../packages + - red-hat-developer-hub-backstage-plugin-lightspeed + - red-hat-developer-hub-backstage-plugin-lightspeed-backend + + installation: | + ## Installation + + ### Dynamic Plugin Installation for Red Hat Developer Hub + + Add the following configuration to your dynamic plugin yaml: + + ```yaml + includes: + - dynamic-plugins.default.yaml + plugins: + # Frontend plugin + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-lightspeed:bs_1.39.1__0.5.7!red-hat-developer-hub-backstage-plugin-lightspeed + disabled: false + pluginConfig: + lightspeed: + # OPTIONAL: Custom users prompts displayed to users + # If not provided, the plugin uses built-in default prompts + prompts: + - title: 'Getting Started with Red Hat Developer Hub' + message: Can you guide me through the first steps to start using Developer Hub as a developer, like exploring the Software Catalog and adding my service? + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-lightspeed: + appIcons: + - name: LightspeedIcon + module: LightspeedPlugin + importName: LightspeedIcon + dynamicRoutes: + - path: /lightspeed + importName: LightspeedPage + module: LightspeedPlugin + menuItem: + icon: LightspeedIcon + text: Lightspeed + + # Backend plugin + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-lightspeed-backend:bs_1.39.1__0.5.7!red-hat-developer-hub-backstage-plugin-lightspeed-backend + disabled: false + pluginConfig: + lightspeed: + # REQUIRED: Configure LLM servers with OpenAI API compatibility + servers: + - id: ${LIGHTSPEED_SERVER_ID} + url: ${LIGHTSPEED_SERVER_URL} + token: ${LIGHTSPEED_SERVER_TOKEN} + + # OPTIONAL: Enable/disable question validation (default: true) + # When enabled, restricts questions to RHDH-related topics for better security + questionValidation: true + + # OPTIONAL: Custom user prompts displayed to users + # If not provided, the plugin uses built-in default user prompts + # prompts: + # - title: "Quick Start" + # message: "How do I enable a dynamic plugin?" + + # OPTIONAL: Port for lightspeed service (default: 8080) + # servicePort: 8080 + + # OPTIONAL: Override default RHDH system prompt + # systemPrompt: "You are a helpful assistant focused on Red Hat Developer Hub development." + ``` + + ### Static Installation for Backstage application. + + This section documents the static method of installing plugin packages in a Backstage application. + Use this approach only when you want to manually add and configure plugins. + Ensure you follow each step carefully to integrate the plugin correctly within your Backstage environment. + + #### 1. Install Plugin Packages + + ```bash + # Install frontend plugin + yarn workspace app add @red-hat-developer-hub/backstage-plugin-lightspeed + + # Install backend plugin + yarn add --cwd packages/backend @red-hat-developer-hub/backstage-plugin-lightspeed-backend + ``` + + #### 2. Register Backend Plugin + + Add to your `packages/backend/src/index.ts`: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + + const backend = createBackend(); + + // Add the Lightspeed backend plugin + backend.add( + import('@red-hat-developer-hub/backstage-plugin-lightspeed-backend'), + ); + + backend.start(); + ``` + + #### 3. Add Frontend Components + + **Add Navigation Route** in `packages/app/src/App.tsx`: + + ```tsx + import { LightspeedPage } from '@red-hat-developer-hub/backstage-plugin-lightspeed'; + + // Add this route within your existing routes + } /> + ``` + + **Add Navigation Menu Item** in `packages/app/src/components/Root/Root.tsx`: + + ```tsx + import { LightspeedIcon } from '@red-hat-developer-hub/backstage-plugin-lightspeed'; + + // Add this within your existing sidebar items + + ``` + + #### 4. Configure the Plugin + **Configure your LLM server** in `app-config.yaml` or `app-config.local.yaml`: + + + ```yaml + lightspeed: + servers: + - id: openai-server + url: https://api.openai.com/v1 + token: ${OPENAI_API_KEY} + ``` + + ## Configuration + + ### Complete Configuration Reference + + Add the following configuration to your `app-config.yaml`: + + ```yaml + lightspeed: + # REQUIRED: Configure LLM servers with OpenAI API compatibility + servers: + - id: # REQUIRED: Unique identifier for the server + url: # REQUIRED: Base URL of the LLM server (e.g., https://api.openai.com/v1) + token: # REQUIRED: Authentication token/API key for the server + + # OPTIONAL: Enable/disable question validation (default: true) + # When enabled, restricts questions to RHDH-related topics for better security + questionValidation: true + + # OPTIONAL: Custom users prompts displayed to users + # If not provided, the plugin uses built-in default prompts + prompts: + - title: # REQUIRED: Display title for the prompt + message: # REQUIRED: The actual prompt text/question + + # OPTIONAL: Backend-only configurations + servicePort: 8080 # OPTIONAL: Port for lightspeed service (default: 8080) + systemPrompt: # OPTIONAL: Override default RHDH system prompt + ``` + + #### Configuration Fields + + | Field | Type | Required | Default | Description | + |-------|------|----------|---------|-------------| + | `servers` | Array | ✅ Yes | - | Array of LLM server configurations | + | `servers[].id` | String | ✅ Yes | - | Unique identifier for the server | + | `servers[].url` | String | ✅ Yes | - | Base URL of the LLM server with OpenAI API compatibility | + | `servers[].token` | String | ✅ Yes | - | Authentication token or API key for accessing the server | + | `questionValidation` | Boolean | ❌ No | `true` | Enable/disable question validation for security | + | `prompts` | Array | ❌ No | Built-in prompts | Custom welcome prompts for users | + | `prompts[].title` | String | ✅ Yes* | - | Display title for the prompt (*required if prompts array is provided) | + | `prompts[].message` | String | ✅ Yes* | - | The actual prompt text/question (*required if prompts array is provided) | + | `servicePort` | Number | ❌ No | `8080` | Port for lightspeed backend service | + | `systemPrompt` | String | ❌ No | RHDH default | Custom system prompt to override default behavior | + + ### Example Configurations + + #### Basic Configuration (Required fields only) + ```yaml + lightspeed: + servers: + - id: openai-server + url: https://api.openai.com/v1 + token: ${OPENAI_API_KEY} + ``` + + #### Local Development Configuration + ```yaml + lightspeed: + servers: + - id: 'my-llm-server' + url: 'http://localhost:11434/v1' + token: 'dummy' # dummy token + ``` + + #### Disable Question Validation + ```yaml + lightspeed: + questionValidation: false + servers: + - id: openai-server + url: https://api.openai.com/v1 + token: ${OPENAI_API_KEY} + ``` + + #### Custom User Prompts (Welcome Prompts in Lightspeed UI) + ```yaml + lightspeed: + servers: + - id: openai-server + url: https://api.openai.com/v1 + token: ${OPENAI_API_KEY} + prompts: + - title: "Get Started with RHDH" + message: "How can I set up a new component in Red Hat Developer Hub?" + - title: "Troubleshooting" + message: "What are common issues when deploying to OpenShift?" + - title: "Best Practices" + message: "What are the recommended practices for RHDH development?" + ``` + + #### Complete Configuration with All Options + ```yaml + lightspeed: + servers: + - id: openai-server + url: https://api.openai.com/v1 + token: ${OPENAI_API_KEY} + questionValidation: true + prompts: + - title: "Quick Start" + message: "How do I enable a dynamic plugin?" + servicePort: 8080 + systemPrompt: "You are a helpful assistant focused on Red Hat Developer Hub development." + ``` + + ## Permissions + + The Lightspeed plugin supports the Backstage permission framework for access control. + + ### RBAC Configuration + + When using the [RBAC permission framework](https://github.com/backstage/community-plugins/tree/main/workspaces/rbac/plugins/rbac-backend#installation), add the following permissions to your `rbac-policy.csv` file: + + ```csv + # Allow team_a role to read, create, and delete lightspeed chats + p, role:default/team_a, lightspeed.chat.read, read, allow + p, role:default/team_a, lightspeed.chat.create, create, allow + p, role:default/team_a, lightspeed.chat.delete, delete, allow + + # Assign user to team_a role + g, user:default/, role:default/team_a + ``` + + ### Permission Configuration + + Configure the permission system in your application configuration: + + ```yaml + permission: + enabled: true + rbac: + policies-csv-file: /some/path/rbac-policy.csv + policyFileReload: true + ``` + + ## Development + + ### Local Development + + 1. **Fork and clone this repository**: + + ```bash + git clone https://github.com/your-username/rhdh-plugins.git + cd rhdh-plugins/workspaces/lightspeed + ``` + + 2. **Install dependencies**: + + ```bash + yarn install + ``` + + 3. **Add configurations** in `app-config.yaml` or `app-config.local.yaml`: + + ```yaml + lightspeed: + servers: + - id: 'my-llm-server' + url: 'http://localhost:11434/v1' + token: 'dummy' # dummy token + questionValidation: true + ``` + + 4. **Start the development server**: + + ```bash + yarn dev + ``` + + 5. **Access the application** at [http://localhost:3000](http://localhost:3000) and navigate to the Developer Lightspeed page + + + + ### Environment Variables + + The following environment variables can be used in configuration: + + - `LIGHTSPEED_SERVER_ID`: Server identifier + - `LIGHTSPEED_SERVER_URL`: LLM server URL + - `LIGHTSPEED_SERVER_TOKEN`: Authentication token + - `LIGHTSPEED_SERVICE_PORT`: Service port (default: 8080) + - `LIGHTSPEED_QUESTION_VALIDATION`: Enable question validation (default: true) + + ### Example with Environment Variables + + ```yaml + lightspeed: + servers: + - id: ${LIGHTSPEED_SERVER_ID} + url: ${LIGHTSPEED_SERVER_URL} + token: ${LIGHTSPEED_SERVER_TOKEN} + servicePort: ${LIGHTSPEED_SERVICE_PORT:-8080} + questionValidation: ${LIGHTSPEED_QUESTION_VALIDATION:-true} + ``` + + diff --git a/catalog-entities/marketplace/plugins/mcp-chat.yaml b/catalog-entities/marketplace/plugins/mcp-chat.yaml new file mode 100644 index 0000000000..9da88b024e --- /dev/null +++ b/catalog-entities/marketplace/plugins/mcp-chat.yaml @@ -0,0 +1,68 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: mcp-chat + namespace: rhdh + title: MCP Chat + annotations: + extensions.backstage.io/pre-installed: 'true' + links: + - title: Plugin Overview (README) + url: https://github.com/backstage/community-plugins/blob/main/workspaces/mcp-chat/README.md + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat + tags: + - ai + - chat + - automation + - mcp + - developer-tools + description: | + AI-powered chat interface with Model Context Protocol integration for intelligent automation and tool orchestration +spec: + author: Backstage Community + support: + provider: Backstage Community + level: community + lifecycle: active + publisher: Backstage Community + + categories: + - AI + - Developer Tools + + description: | + The MCP Chat plugin brings conversational AI capabilities directly into your Backstage environment. It leverages the Model Context Protocol (MCP) + to connect with various AI providers and external tools, enabling developers to interact with their infrastructure, catalogs, and external services + through natural language. + + ## Features + + - **Multi-Provider AI Support**: Works with OpenAI, Claude, Gemini, and Ollama - choose the AI provider that best fits your needs + - **Multi-Server Support**: Connect multiple MCP servers simultaneously (STDIO, SSE, Streamable HTTP) for diverse tool integration + - **Tool Management**: Browse and dynamically enable/disable tools from connected MCP servers through an intuitive interface + - **Rich Chat Interface**: Beautiful, responsive chat UI with full markdown support for formatted responses + - **Quick Setup**: Configurable QuickStart prompts for common use cases - get started with pre-built automation tasks + + ## Supported AI Providers + + The following AI providers and models have been thoroughly tested: + + - **OpenAI** (`gpt-4o-mini`) - Fully tested, recommended for production use + - **Gemini** (`gemini-2.5-flash`) - Fully tested with excellent tool calling performance, free tier available + - **Ollama** (`llama3.1:8b`) - Tested, works well locally (larger models like `llama3.1:30b` recommended for better results) + - **Claude** - Supported with tool calling capabilities + + ## Highlights + + - **Multi-Provider AI Support**: Works with OpenAI, Claude, Gemini, and Ollama - choose the AI provider that best fits your needs + - **Model Context Protocol (MCP) Integration**: Connect with various AI providers and external tools, enabling developers to interact with their infrastructure, catalogs, and external services through natural language. + - **Dynamic Tool Discovery and Management**: Browse and dynamically enable/disable tools from connected MCP servers through an intuitive interface + - **Rich Markdown Chat Interface**: Beautiful, responsive chat UI with full markdown support for formatted responses + - **Configurable Quick Prompts**: Configurable QuickStart prompts for common use cases - get started with pre-built automation tasks + + packages: + - backstage-community-plugin-mcp-chat + - backstage-community-plugin-mcp-chat-backend + diff --git a/catalog-entities/marketplace/plugins/mcp-tools.yaml b/catalog-entities/marketplace/plugins/mcp-tools.yaml new file mode 100644 index 0000000000..7b87fc0927 --- /dev/null +++ b/catalog-entities/marketplace/plugins/mcp-tools.yaml @@ -0,0 +1,228 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: mcp-tools + namespace: rhdh + title: MCP Tools + annotations: + extensions.backstage.io/pre-installed: 'true' # Plugin is automatically listed in the catalog. + links: + - title: Homepage + url: https://red.ht/rhdh + - title: Bugs + url: https://issues.redhat.com/browse/RHDHPAI + - title: Documentation for Red Hat Developer Hub + url: https://docs.redhat.com/en/documentation/red_hat_developer_hub + - title: Source Code + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/mcp-integrations + tags: + - mcp + - developer-tools + - ai + - software-catalog + - techdocs + description: | + Backend plugins that provide MCP tools for MCP clients and AI assistants to interact with the software catalog and techdocs +spec: + author: Red Hat + support: dev-preview + lifecycle: active + publisher: Red Hat + + + highlights: + - Integrations with the software catalog and techdocs for AI assistants + - Provides insight into the RHDH catalog, by querying catalog entities, and retrieving metadata + - Learn about techdocs coverage, and retrieve techdocs for catalog entities + + + description: | + # MCP Tool Plugins + + + Red Hat Developer Hub provides a collection of MCP tools that can be used by AI assistants to interact with RHDH. + + + Model Context Protocol (MCP) provides a standard for connecting AI models and applications (MCP clients) to external systems, enabling them to access information and workflows on those systems. MCP servers define tools which can be called by AI applications to access this data. + RHDH supports running MCP tools through the mcp-actions-backend plugin available in Backstage. + + The MCP integrations in RHDH consist of two components: + + + - **Backend MCP server** (`@backstage/plugin-mcp-actions-backend`): Provides the MCP server to run the MCP tools + - **MCP Tool Plugins** (`@red-hat-developer/hub-backstage-plugin-software-catalog-mcp-tool` and `@red-hat-developer-hub/backstage-plugin-techdocs-mcp-tool`): Provides + + + ### Key Features + + + - **Client Integration**: Connect any compatible MCP client to RHDH to interact with the MCP tools + - **Integrations with the Software Catalog**: Query the software catalog to fetch catalog entities, and important metadata associated with them + - **Integrations with Techdocs**: Determine coverage of techdocs for catalog entities, and fetch the content of techdocs + + + ## Support + + + - **MCP Server Plugin**: [MCP Server README](https://github.com/backstage/backstage/blob/master/plugins/mcp-actions-backend/README.md) + - **Backend Plugin**: [Backend README](https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/mcp-integrations/README.md) + - **Issues**: [Jira Issues](https://issues.redhat.com/browse/RHDHBUGS) + + + packages: # link to the name used in the associated package documents in ../packages + - red-hat-developer-hub-plugin-software-catalog-mcp-tool + - red-hat-developer-hub-plugin-techdocs-mcp-tool + - backstage-plugin-mcp-actions-backend + + installation: | + ## Installation + + + ### Dynamic Plugin Installation for Red Hat Developer Hub + + + Add the following configuration to your dynamic plugin yaml: + + + ```yaml + includes: + - dynamic-plugins.default.yaml + plugins: + # MCP server backend plugin + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-plugin-mcp-actions-backend:bs_1.42.5__0.1.2!backstage-plugin-mcp-actions-backend + disabled: false + + # MCP tools plugins + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool:bs_1.42.5__0.2.2!red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool + disabled: false + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-techdocs-mcp-tool:bs_1.42.5__0.2.1!red-hat-developer-hub-backstage-plugin-techdocs-mcp-tool + disabled: false + ``` + + + ## RHDH Configuration + + + ### Complete Configuration Reference + + + Register the MCP tools as a plugin source in your App Config: + ```yaml + backend: + actions: + pluginSources: + - software-catalog-mcp-tool + - techdocs-mcp-tool + ``` + + Configure a static token for the MCP server in your App Config, where `` is some value specified by you: + + + ```yaml + backend: + auth: + externalAccess: + - type: static + options: + token: ${MCP_TOKEN} + subject: mcp-clients + ``` + + + ## MCP Client Configuration + + The MCP server in RHDH provides two endpoints that can be used by MCP clients: + + - Streamable HTTP: http:///api/mcp-actions/v1 + - SSE (Legacy): http:///api/mcp-actions/v1/sse + + + Some MCP clients will require the Streamable HTTP endpoint, while others may require the legacy SSE endpoint. + Consult your MCP client or AI application's documentation for how to configure MCP servers, and if a specific type of endpoint is required. + + + Below we've provided a couple sample configurations for common MCP clients + + + ### Cursor + + + 1) Navigate to Cursor Settings and select MCP Tools + 2) Select New MCP Server + 3) Paste the following configuration, where`` is the hostname for your RHDH instance, and is the static token configured previously. + + + ``` + { + "mcpServers": { + "backstage-actions": { + "url": "http:///api/mcp-actions/v1", + "headers": { + "Authorization": "Bearer " + } + } + } + } + ``` + + + ### Continue + + + Add the following to your agent's yaml configuration file, where`` is the hostname for your RHDH instance, and is the static token configured previously. + + + ```yaml + mcpServers: + - name: backstage-actions + type: sse + url: http:///api/mcp-actions/v1/sse + requestOptions: + headers: + Authorization: "Bearer " + ``` + + ## Local Development + + + 1. **Fork and clone this repository**: + + + ```bash + git clone https://github.com/your-username/rhdh-plugins.git + cd rhdh-plugins/workspaces/mcp-integrations + ``` + + + 2. **Install dependencies**: + + ```bash + yarn install + ``` + + + 3. Set `MCP_TOKEN` to some value (at least 8 characters): + + + ```bash + export MCP_TOKEN= + ``` + + + 4. **Start the development server**: + + + ```bash + yarn dev + ``` + + + 5. **Configure your MCP client** to point to either: + + + Streamable HTTP: http://localhost:7007/api/mcp-actions/v1 + SSE: http://localhost:7007/api/mcp-actions/v1/sse + + + with the bearer token set to `MCP_TOKEN`. diff --git a/catalog-entities/marketplace/plugins/microsoft-graph-catalog-integration.yaml b/catalog-entities/marketplace/plugins/microsoft-graph-catalog-integration.yaml index 154f05a22a..d5bd699ec1 100644 --- a/catalog-entities/marketplace/plugins/microsoft-graph-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/microsoft-graph-catalog-integration.yaml @@ -27,7 +27,9 @@ metadata: spec: author: Backstage Community - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/nexus-repository-manager.yaml b/catalog-entities/marketplace/plugins/nexus-repository-manager.yaml index 31b6de2387..16c229b6a8 100644 --- a/catalog-entities/marketplace/plugins/nexus-repository-manager.yaml +++ b/catalog-entities/marketplace/plugins/nexus-repository-manager.yaml @@ -27,7 +27,9 @@ metadata: spec: author: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/notifications-email.yaml b/catalog-entities/marketplace/plugins/notifications-email.yaml index d12b285984..514e14a5b1 100644 --- a/catalog-entities/marketplace/plugins/notifications-email.yaml +++ b/catalog-entities/marketplace/plugins/notifications-email.yaml @@ -22,7 +22,9 @@ metadata: url: https://backstage.io/docs/notifications/ spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/notifications.yaml b/catalog-entities/marketplace/plugins/notifications.yaml index d4ad5368be..c161ed25de 100644 --- a/catalog-entities/marketplace/plugins/notifications.yaml +++ b/catalog-entities/marketplace/plugins/notifications.yaml @@ -22,7 +22,9 @@ metadata: url: https://backstage.io/docs/notifications/ spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/openshift-cluster-manager.yaml b/catalog-entities/marketplace/plugins/openshift-cluster-manager.yaml index 058ab8e628..2388d7f511 100644 --- a/catalog-entities/marketplace/plugins/openshift-cluster-manager.yaml +++ b/catalog-entities/marketplace/plugins/openshift-cluster-manager.yaml @@ -5,7 +5,7 @@ metadata: name: openshift-cluster-manager namespace: rhdh title: OpenShift Cluster Manager - description: The Open Cluster Management (OCM) plugin integrates your Red Hat Developer instance with the MultiClusterHub and MultiCluster engines of OCM. + description: The DEPRECATED Open Cluster Management (OCM) plugin integrates your Red Hat Developer instance with the MultiClusterHub and MultiCluster engines of OCM. annotations: extensions.backstage.io/pre-installed: 'true' extensions.backstage.io/verified-by: Red Hat @@ -21,15 +21,20 @@ metadata: url: https://github.com/backstage/community-plugins/tree/main/workspaces/ocm/plugins/ocm spec: author: Red Hat - support: production + support: + provider: Red Hat + level: generally-available publisher: Red Hat - lifecycle: active + # https://issues.redhat.com/browse/RHDHPLAN-265 - OCM is deprecated in 1.8; will be removed in 1.10 + lifecycle: deprecated categories: - Monitoring description: | - The Open Cluster Management (OCM) plugin integrates your Backstage instance with the `MultiClusterHub` and `MultiCluster` engines of OCM. + The DEPRECATED Open Cluster Management (OCM) plugin integrates your Backstage instance with the `MultiClusterHub` and `MultiCluster` engines of OCM. + + This deprecated plugin will be removed in a future release. You should migrate to a replacement as soon as possible. The OCM plugin has the following capabilities: diff --git a/catalog-entities/marketplace/plugins/optimizations.yaml b/catalog-entities/marketplace/plugins/optimizations.yaml new file mode 100644 index 0000000000..9fd07c0d12 --- /dev/null +++ b/catalog-entities/marketplace/plugins/optimizations.yaml @@ -0,0 +1,348 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: optimizations + namespace: rhdh + title: RedHat Insights Optimizations For Red Hat Developer Hub + annotations: + extensions.backstage.io/pre-installed: 'true' # Plugin is automatically listed in the catalog. + links: + - title: Homepage + url: https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/redhat-resource-optimization + tags: + - optimization # Used for filtering + - insights + - cluster + description: | + Optimizations brings Red Hat Insights OpenShift recommendations into Backstage with extended actions. You can view recommendations and apply them to your configured clusters. +spec: + author: Red Hat + support: + provider: Red Hat + level: tech-preview + lifecycle: active + publisher: Red Hat + + categories: + - Automation + highlights: + - View Red Hat Insights recommendations for OpenShift clusters + - Apply OpenShift recommendations to your configured clusters + + description: | + Optimizations brings Red Hat Insights OpenShift recommendations into Backstage with extended actions. You can view recommendations and apply them to your configured clusters. + + The Optimizations features two primary functionalities: + + * View and manage Red Hat Insights recommendations for OpenShift clusters + * Apply OpenShift recommendations to your configured clusters + + ## Adding The Plugin To Red Hat Developer Hub + + See the [Red Hat Developer Hub documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) + for further instructions on how to add, enable, configure, and remove plugins in your instance. + + ## Configuring The Plugin ## + + Plugins often need additional configuration to work correctly - particularly those that integrate with other + systems. See the original source code repository, the software vendor, or the [Red Hat Developer Hub documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) + for further details regarding the configuration required. + + # Images are base 64 encoded SVGs + icon: data:image/svg+xml;base64, + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEi + IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjE4OSIgaGVpZ2h0PSIx + ODkiPgo8cGF0aCBkPSJNMCAwIEMwLjc1NDc0NjA5IC0wLjAxMDk1NzAzIDEuNTA5NDkyMTkgLTAu + MDIxOTE0MDYgMi4yODcxMDkzOCAtMC4wMzMyMDMxMiBDNS43ODg4MTY2MyAwLjAxMzA3NDk0IDgu + MDIyNjc1NzQgMC4yNzE3OTYzOSAxMC45MTc5Njg3NSAyLjMwMDc4MTI1IEMxMi42MDQ4MTMzOCA0 + LjgxMTUzNDU2IDEzLjAxMTI0NDAzIDYuMzE2MTQ4NDkgMTMuMTg3NSA5LjMxMjUgQzEzLjI0NDIx + ODc1IDEwLjExMTcxODc1IDEzLjMwMDkzNzUgMTAuOTEwOTM3NSAxMy4zNTkzNzUgMTEuNzM0Mzc1 + IEMxMy4zODUxNTYyNSAxMi4zMzc2NTYyNSAxMy40MTA5Mzc1IDEyLjk0MDkzNzUgMTMuNDM3NSAx + My41NjI1IEMxNS4wODc1IDE0LjIyMjUgMTYuNzM3NSAxNC44ODI1IDE4LjQzNzUgMTUuNTYyNSBD + MTkuMjgzMTI1IDE0LjcxNjg3NSAyMC4xMjg3NSAxMy44NzEyNSAyMSAxMyBDMjIuNDQxNDA2MjUg + MTEuNTU4NTkzNzUgMjIuNDQxNDA2MjUgMTEuNTU4NTkzNzUgMjQuNDM3NSAxMC41NjI1IEMzMC4x + NzkxNDM3NiAxMC42NTU0MjgzNCAzMi44NjA2NjQ3NSAxMi4xODI2NDk1NiAzNi44MTI1IDE2LjI1 + IEMzNy42NjU4NTkzNyAxNy4wOTk0OTIxOSAzOC41MTkyMTg3NSAxNy45NDg5ODQzNyAzOS4zOTg0 + Mzc1IDE4LjgyNDIxODc1IEM0MS42Nzg3Nzk5NyAyMS44ODY1MTc3NCA0Mi4yNjU1OTYyNCAyMy43 + NzU0MDgwOCA0Mi40Mzc1IDI3LjU2MjUgQzQxLjA2MzU2MjcgMzAuNDQxMjI1NzcgMzkuNjg3NjA1 + NjMgMzIuMzEyMzk0MzcgMzcuNDM3NSAzNC41NjI1IEMzNy4yNzA2ODg5MSAzNy42NDU5NzgyNiAz + Ny4yNzA2ODg5MSAzNy42NDU5NzgyNiAzNy40Mzc1IDQwLjU2MjUgQzM4LjQ2ODEwNTQ3IDQwLjYw + MTE3MTg4IDM4LjQ2ODEwNTQ3IDQwLjYwMTE3MTg4IDM5LjUxOTUzMTI1IDQwLjY0MDYyNSBDNDAu + NDIwNTg1OTQgNDAuNjk3MzQzNzUgNDEuMzIxNjQwNjMgNDAuNzU0MDYyNSA0Mi4yNSA0MC44MTI1 + IEM0My4xNDMzMjAzMSA0MC44NTg5MDYyNSA0NC4wMzY2NDA2MyA0MC45MDUzMTI1IDQ0Ljk1NzAz + MTI1IDQwLjk1MzEyNSBDNDcuNDM3NSA0MS41NjI1IDQ3LjQzNzUgNDEuNTYyNSA0OS4yMzgyODEy + NSA0My4wNzgxMjUgQzUwLjk3NzMxMTMxIDQ2LjY4MDgwNjE2IDUwLjg3MjI5OTc2IDUwLjE0ODkz + ODE5IDUwLjgxMjUgNTQuMDYyNSBDNTAuODI0MTAxNTYgNTQuODIxNzU3ODEgNTAuODM1NzAzMTIg + NTUuNTgxMDE1NjIgNTAuODQ3NjU2MjUgNTYuMzYzMjgxMjUgQzUwLjgzMDM3ODAxIDU5LjY1MTkw + NTggNTAuNjgwODc1MTEgNjIuMTEyNzU0MTggNDkuMTAxNTYyNSA2NS4wMzEyNSBDNDYuMzY3Nzc0 + MzEgNjcuNTQ2ODQ4NTIgNDMuNzk2MDU5OSA2Ny42ODMxMzIxMyA0MC4yNSA2Ny42MjUgQzM4Ljk5 + MTg3NSA2Ny42MDQzNzUgMzcuNzMzNzUgNjcuNTgzNzUgMzYuNDM3NSA2Ny41NjI1IEMzNS40Nzgx + ODQzIDY5Ljc1NzY0ODczIDM1LjQ3ODE4NDMgNjkuNzU3NjQ4NzMgMzUuNDM3NSA3Mi41NjI1IEMz + Ny4wOTk5NzAxNCA3NC41NjU5ODk2NiAzOC43NjY4Mjg2NyA3Ni41NjU4NDQwMiA0MC40Mzc1IDc4 + LjU2MjUgQzQxLjE4NzUgODEuNDM3NSA0MS4xODc1IDgxLjQzNzUgNDAuNDM3NSA4NC41NjI1IEMz + OC4zNzc4NDYzMSA4Ny41MjI4OTM2IDM2LjAwMjA4NzMzIDkwLjAzNTU0ODEzIDMzLjQzNzUgOTIu + NTYyNSBDMzIuNjEyNSA5My4zODc1IDMxLjc4NzUgOTQuMjEyNSAzMC45Mzc1IDk1LjA2MjUgQzI3 + LjQ4NDIxODYxIDk3LjEzNDQ2ODg0IDI1LjM5NTMxNzU1IDk3LjE5ODU3NzgyIDIxLjQzNzUgOTYu + NTYyNSBDMTkuNzUwODc1NDIgOTQuOTE2MDMzMTUgMTguMDgyMzgyOTQgOTMuMjUwNjY5MzMgMTYu + NDM3NSA5MS41NjI1IEMxMy42NzczMzUgOTEuNjEyMjk1ODQgMTMuNjc3MzM1IDkxLjYxMjI5NTg0 + IDExLjQzNzUgOTIuNTYyNSBDMTEuMzI3OTI5NjkgOTMuMTc3MzgyODEgMTEuMjE4MzU5MzggOTMu + NzkyMjY1NjIgMTEuMTA1NDY4NzUgOTQuNDI1NzgxMjUgQzEwLjg2NzYzNjcyIDk1LjYzODE0NDUz + IDEwLjg2NzYzNjcyIDk1LjYzODE0NDUzIDEwLjYyNSA5Ni44NzUgQzEwLjQ3NDE3OTY5IDk3LjY3 + NTUwNzgxIDEwLjMyMzM1OTM4IDk4LjQ3NjAxNTYzIDEwLjE2Nzk2ODc1IDk5LjMwMDc4MTI1IEM5 + LjM0MzcxMTY3IDEwMS44NTI4OTI3NCA4LjUzMDI0MzU5IDEwMi45MTU2Njc4OCA2LjQzNzUgMTA0 + LjU2MjUgQzMuMTM0MTQ5MzQgMTA1LjY2MzYxNjg5IDAuNTM5MTc4NjMgMTA1Ljc2NDc2NTI4IC0y + LjkzNzUgMTA1LjgxMjUgQy00LjYxOTcyNjU2IDEwNS44NTExNzE4OCAtNC42MTk3MjY1NiAxMDUu + ODUxMTcxODggLTYuMzM1OTM3NSAxMDUuODkwNjI1IEMtOS44OTY2NDcyNyAxMDUuNTI4NTE4OTIg + LTExLjcyMzA3NTM5IDEwNC42OTk3NTY0MyAtMTQuNTYyNSAxMDIuNTYyNSBDLTE2LjQ1OTczNzQ3 + IDk5LjA1MjYxMDY3IC0xNy4wMTQzNDA5OCA5NS40OTA5NzI5OSAtMTcuNTYyNSA5MS41NjI1IEMt + MTkuMjk4MjU2NDkgOTAuNjg4MTM1ODIgLTE5LjI5ODI1NjQ5IDkwLjY4ODEzNTgyIC0yMS41NjI1 + IDkwLjU2MjUgQy0yMi4zMjU2MjUgOTEuMjAxODc1IC0yMy4wODg3NSA5MS44NDEyNSAtMjMuODc1 + IDkyLjUgQy0yNi41NjI1IDk0LjU2MjUgLTI2LjU2MjUgOTQuNTYyNSAtMjkuODc1IDk1LjI1IEMt + MzUuMTg4Nzc1MzEgOTQuMjU5Mjk2MTMgLTM3Ljg4OTE1NTM5IDkxLjM3MTMwNDE3IC00MS41NjI1 + IDg3LjU2MjUgQy00Mi44IDg2LjI5NDA2MjUgLTQyLjggODYuMjk0MDYyNSAtNDQuMDYyNSA4NSBD + LTQ2LjAxODE3MTEyIDgxLjgyMjAzNDQzIC00Ni4yMzcxODkwMyA4MC4yMzU4MDY5NiAtNDUuNTYy + NSA3Ni41NjI1IEMtNDQuNzE2ODc1IDc1LjU1MTg3NSAtNDMuODcxMjUgNzQuNTQxMjUgLTQzIDcz + LjUgQy00MC4yMTQ0NjQ5OCA3MC44Mjc4MDQzMiAtNDAuMjE0NDY0OTggNzAuODI3ODA0MzIgLTQw + Ljc1IDY3LjY4NzUgQy00MS4wMTgxMjUgNjYuOTg2MjUgLTQxLjI4NjI1IDY2LjI4NSAtNDEuNTYy + NSA2NS41NjI1IEMtNDIuMTc3MzgyODEgNjUuNDUyOTI5NjkgLTQyLjc5MjI2NTYyIDY1LjM0MzM1 + OTM4IC00My40MjU3ODEyNSA2NS4yMzA0Njg3NSBDLTQ0LjYzODE0NDUzIDY0Ljk5MjYzNjcyIC00 + NC42MzgxNDQ1MyA2NC45OTI2MzY3MiAtNDUuODc1IDY0Ljc1IEMtNDYuNjc1NTA3ODEgNjQuNTk5 + MTc5NjkgLTQ3LjQ3NjAxNTYzIDY0LjQ0ODM1OTM3IC00OC4zMDA3ODEyNSA2NC4yOTI5Njg3NSBD + LTUwLjg5OTY4NTA4IDYzLjQ1MzU5OTEyIC01MS44NTUxNTQ1MiA2Mi42NjkzMDg5NyAtNTMuNTYy + NSA2MC41NjI1IEMtNTQuMTgwMTkzNTUgNTcuNjEyODczMzEgLTU0LjAyNjE0OTMyIDU0LjYzMjE3 + MTU5IC01NCA1MS42MjUgQy01NC4wMTk5ODA0NyA1MC44MTM1MzUxNiAtNTQuMDM5OTYwOTQgNTAu + MDAyMDcwMzEgLTU0LjA2MDU0Njg4IDQ5LjE2NjAxNTYyIEMtNTQuMDU3NDM2ODcgNDUuMzc0OTE4 + MDggLTU0LjAxNjQ3MDQ3IDQzLjIyMzQ3MjgxIC01MS44MzIwMzEyNSA0MC4wNDI5Njg3NSBDLTQ5 + LjMyMTI0NjAxIDM4LjQwNTEyNDM0IC00Ny43ODQzMzI4NyAzNy45ODczMTM3IC00NC44MTI1IDM3 + LjgxMjUgQy00NC4wMTMyODEyNSAzNy43NTU3ODEyNSAtNDMuMjE0MDYyNSAzNy42OTkwNjI1IC00 + Mi4zOTA2MjUgMzcuNjQwNjI1IEMtNDEuNzg3MzQzNzUgMzcuNjE0ODQzNzUgLTQxLjE4NDA2MjUg + MzcuNTg5MDYyNSAtNDAuNTYyNSAzNy41NjI1IEMtMzkuNjkzOTk4MjYgMzUuMzEzNzQyNTMgLTM5 + LjY5Mzk5ODI2IDM1LjMxMzc0MjUzIC0zOS41NjI1IDMyLjU2MjUgQy00MC4yMDE4NzUgMzEuNzc4 + NzUgLTQwLjg0MTI1IDMwLjk5NSAtNDEuNSAzMC4xODc1IEMtNDMuNTYyNSAyNy41NjI1IC00My41 + NjI1IDI3LjU2MjUgLTQ0LjM3NSAyNC4zNzUgQy00My4wNzc4MDE3OSAxOC4yODgxNDY4NiAtMzku + MTc4MTA3MjcgMTQuNTczNTA2OTUgLTM0LjU2MjUgMTAuNTYyNSBDLTMxLjg4OTQxNzM1IDguOTMw + NzM4NyAtMzAuODA3NDY5MzggOC43NDYxNzc1MSAtMjcuNTYyNSA4LjU2MjUgQy0yNC4xOTI0OTA4 + MyA5LjgzNDIwMTU3IC0yMi4xMDExMjE2MyAxMS4wMjM4NzgzNyAtMTkuNTYyNSAxMy41NjI1IEMt + MTYuNDc5MDIxNzQgMTMuNzI5MzExMDkgLTE2LjQ3OTAyMTc0IDEzLjcyOTMxMTA5IC0xMy41NjI1 + IDEzLjU2MjUgQy0xMy43MTcxODc1IDExLjczNzE4NzUgLTEzLjcxNzE4NzUgMTEuNzM3MTg3NSAt + MTMuODc1IDkuODc1IEMtMTQuMTU1OTU3NTcgNi41NTk3MDA2NiAtMTMuNTgzOTg0ODEgNS41OTIx + MDUwNSAtMTEuNTc4MTI1IDIuODI4MTI1IEMtNy41ODM3NTExMSAtMC4xNzI4Mjk0OCAtNC44NTgx + ODA2OSAtMC4xNTQyOTQxNSAwIDAgWiBNLTYuNTYyNSA3LjU2MjUgQy02Ljg5MjUgMTAuODYyNSAt + Ny4yMjI1IDE0LjE2MjUgLTcuNTYyNSAxNy41NjI1IEMtOS4xMTc3OTEyIDE4LjI2NjE1NjAyIC0x + MC42ODIxNDgyNyAxOC45NDk3OTM3OCAtMTIuMjUgMTkuNjI1IEMtMTMuMTIwMTE3MTkgMjAuMDA3 + ODUxNTYgLTEzLjk5MDIzNDM4IDIwLjM5MDcwMzEzIC0xNC44ODY3MTg3NSAyMC43ODUxNTYyNSBD + LTE3Ljk1Mzg5ODQxIDIxLjY3NjIwNTUyIC0xOS41NTA3NzYzNSAyMS41NjY0MDc4OCAtMjIuNTYy + NSAyMC41NjI1IEMtMjUuMzc1IDE4IC0yNS4zNzUgMTggLTI3LjU2MjUgMTUuNTYyNSBDLTMxLjM5 + MDQyODY4IDE3LjEyMjAyNjUgLTMzLjkyNjA5ODY0IDE5LjM5ODgxODM2IC0zNi41NjI1IDIyLjU2 + MjUgQy0zNi44MDE1MTcxMSAyNC42OTE1NzMxOSAtMzYuODAxNTE3MTEgMjQuNjkxNTczMTkgLTM1 + LjU2MjUgMjYuNTYyNSBDLTM0Ljg2MTI1IDI3LjE4MTI1IC0zNC4xNiAyNy44IC0zMy40Mzc1IDI4 + LjQzNzUgQy0zMS41NjI1IDMwLjU2MjUgLTMxLjU2MjUgMzAuNTYyNSAtMzEuNjI1IDMzLjM3NSBD + LTMyLjY4NzMzOTQ0IDM2Ljk4Njk1NDA5IC0zMy45MDM4OTM4MiA0MC4xNzg5NDMzOSAtMzUuNTYy + NSA0My41NjI1IEMtMzkuMjE2MDgyMTIgNDUuMzg5MjkxMDYgLTQzLjU0MjU4MzQ0IDQ1LjIwMTcz + ODI2IC00Ny41NjI1IDQ1LjU2MjUgQy00Ny41NjI1IDQ5LjUyMjUgLTQ3LjU2MjUgNTMuNDgyNSAt + NDcuNTYyNSA1Ny41NjI1IEMtNDUuMjY2MjAwMDYgNTguNzEwNjQ5OTcgLTQzLjQ4NTUxOTE0IDU4 + Ljg3MDE5ODA5IC00MC45Mzc1IDU5LjEyNSBDLTQwLjEyMDIzNDM3IDU5LjIwODc4OTA2IC0zOS4z + MDI5Njg3NSA1OS4yOTI1NzgxMyAtMzguNDYwOTM3NSA1OS4zNzg5MDYyNSBDLTM3LjUyMTIxMDk0 + IDU5LjQ2OTc4NTE2IC0zNy41MjEyMTA5NCA1OS40Njk3ODUxNiAtMzYuNTYyNSA1OS41NjI1IEMt + MzUuODYxMTY0MDEgNjEuMTM5NzUzNDcgLTM1LjE3NjkxNyA2Mi43MjQ2MTMzMyAtMzQuNSA2NC4z + MTI1IEMtMzQuMTE3MTQ4NDQgNjUuMTk0MjE4NzUgLTMzLjczNDI5Njg3IDY2LjA3NTkzNzUgLTMz + LjMzOTg0Mzc1IDY2Ljk4NDM3NSBDLTMyLjQ5ODE2ODM0IDY5Ljc3NTg2MTI4IC0zMi40Mzc4ODM5 + OCA3MC45MDg0MDYxOSAtMzMuNTYyNSA3My41NjI1IEMtMzYuMTI1IDc2LjMxMjUgLTM2LjEyNSA3 + Ni4zMTI1IC0zOC41NjI1IDc4LjU2MjUgQy0zNy4xODA2MTU0NyA4MS43NzI5Mzg4MiAtMzUuNjM4 + MjgwOTcgODMuNjExODYzNjUgLTMyLjkzNzUgODUuODEyNSBDLTMxLjk5MDAzOTA2IDg2LjU5MzY3 + MTg3IC0zMS45OTAwMzkwNiA4Ni41OTM2NzE4NyAtMzEuMDIzNDM3NSA4Ny4zOTA2MjUgQy0zMC41 + NDEzMjgxMiA4Ny43NzczNDM3NSAtMzAuMDU5MjE4NzUgODguMTY0MDYyNSAtMjkuNTYyNSA4OC41 + NjI1IEMtMjkuMTg3MzgyODEgODguMTE3NzczNDQgLTI4LjgxMjI2NTYyIDg3LjY3MzA0Njg4IC0y + OC40MjU3ODEyNSA4Ny4yMTQ4NDM3NSBDLTI2Ljg4MzQ5MDk1IDg1LjUwOTM4OTI0IC0yNS4zNzIx + MTk0OSA4My45ODI0ODg1IC0yMy41NjI1IDgyLjU2MjUgQy0yMS4yNSA4Mi41IC0yMS4yNSA4Mi41 + IC0xOC41NjI1IDgzLjU2MjUgQy0xNi45NTk3NjQ0NiA4NC4wODc3MjA3NyAtMTUuMzU1NDgyMDEg + ODQuNjA4MjM1NDggLTEzLjc1IDg1LjEyNSBDLTEyLjM1MzE2NzA3IDg1LjYwMTI0NDgzIC0xMC45 + NTY5OTEwOSA4Ni4wNzk0NDEgLTkuNTYyNSA4Ni41NjI1IEMtOS41NzQxMDE1NiA4Ny4zNDQ5NjA5 + NCAtOS41ODU3MDMxMyA4OC4xMjc0MjE4NyAtOS41OTc2NTYyNSA4OC45MzM1OTM3NSBDLTkuNjA2 + Njc5NjkgODkuOTQ1NTA3ODEgLTkuNjE1NzAzMTMgOTAuOTU3NDIxODcgLTkuNjI1IDkyIEMtOS42 + MzY2MDE1NiA5My4wMDkzMzU5NCAtOS42NDgyMDMxMyA5NC4wMTg2NzE4NyAtOS42NjAxNTYyNSA5 + NS4wNTg1OTM3NSBDLTkuODQ4NjI2NzYgOTcuNTAyNzEwNjcgLTkuODQ4NjI2NzYgOTcuNTAyNzEw + NjcgLTguNTYyNSA5OC41NjI1IEMtNi43MzEzNDExNyA5OC42NjEwMTE3MSAtNC44OTYzMDA2NyA5 + OC42OTIyMjYyOSAtMy4wNjI1IDk4LjY4NzUgQy0xLjU2MjAzMTI1IDk4LjY5MTM2NzE5IC0xLjU2 + MjAzMTI1IDk4LjY5MTM2NzE5IC0wLjAzMTI1IDk4LjY5NTMxMjUgQzIuMzgxNDk2MjIgOTguODQx + MjAzODIgMi4zODE0OTYyMiA5OC44NDEyMDM4MiAzLjQzNzUgOTcuNTYyNSBDMy42NzAzNzAwOCA5 + NS44ODA2NjA1MiAzLjg1MDE0MTY2IDk0LjE5MTI1ODQgNCA5Mi41IEM0LjA4Mzc4OTA2IDkxLjU4 + MDg5ODQ0IDQuMTY3NTc4MTIgOTAuNjYxNzk2ODcgNC4yNTM5MDYyNSA4OS43MTQ4NDM3NSBDNC4z + NDQ3ODUxNiA4OC42NDk0MzM1OSA0LjM0NDc4NTE2IDg4LjY0OTQzMzU5IDQuNDM3NSA4Ny41NjI1 + IEM1Ljk5Mjc5MTIgODYuODU4ODQzOTggNy41NTcxNDgyNyA4Ni4xNzUyMDYyMiA5LjEyNSA4NS41 + IEM5Ljk5NTExNzE5IDg1LjExNzE0ODQ0IDEwLjg2NTIzNDM4IDg0LjczNDI5Njg3IDExLjc2MTcx + ODc1IDg0LjMzOTg0Mzc1IEMxNC44MjAzODE0NiA4My40NTEyNjg3NCAxNi40MzcxMDEzNiA4My41 + NDg4NTE4MSAxOS40Mzc1IDg0LjU2MjUgQzIxLjc1IDg3LjEyNSAyMS43NSA4Ny4xMjUgMjMuNDM3 + NSA4OS41NjI1IEMyNi43OTAwMDcwMSA4OC45ODY3NDMzNiAyOC4zNzU2ODYyOSA4Ny45Njk0Mzcz + NyAzMC42ODc1IDg1LjUgQzMxLjIwODI4MTI1IDg0Ljk1MjE0ODQ0IDMxLjcyOTA2MjUgODQuNDA0 + Mjk2ODggMzIuMjY1NjI1IDgzLjgzOTg0Mzc1IEMzMi44NDU3MDMxMiA4My4yMDc1NTg1OSAzMi44 + NDU3MDMxMiA4My4yMDc1NTg1OSAzMy40Mzc1IDgyLjU2MjUgQzMyLjQyMTU5NDgyIDgwLjI5NjI0 + OTk3IDMxLjczNDA3MjczIDc4Ljc5MzE2NzY4IDI5Ljc1IDc3LjI1IEMyOC40Mzc1IDc1LjU2MjUg + MjguNDM3NSA3NS41NjI1IDI4LjU2MjUgNzIuMzEyNSBDMjkuNDc3NTc4MjcgNjguMzkwNzM1OTgg + MzAuNzMyMDgxMTggNjUuMTk1NzgzNTggMzIuNDM3NSA2MS41NjI1IEMzNi4wNjc1IDYxLjIzMjUg + MzkuNjk3NSA2MC45MDI1IDQzLjQzNzUgNjAuNTYyNSBDNDMuNDM3NSA1Ni4yNzI1IDQzLjQzNzUg + NTEuOTgyNSA0My40Mzc1IDQ3LjU2MjUgQzQwLjEzNzUgNDcuMjMyNSAzNi44Mzc1IDQ2LjkwMjUg + MzMuNDM3NSA0Ni41NjI1IEMyOC40NjY2MjYyMSAzNi4xNTQ3MzMwMSAyOC40NjY2MjYyMSAzNi4x + NTQ3MzMwMSAyOS40Mzc1IDMyLjU2MjUgQzMxLjI2NTU4NDc3IDMwLjM1NDAwNDUyIDMzLjI3MjU1 + NDYzIDI4LjQzNzQ5NzMzIDM1LjQzNzUgMjYuNTYyNSBDMzMuODU0NDQyMyAyMi4yODgyNDQyIDMw + LjkzMTgxNTk2IDIwLjI5NzE4MjA2IDI3LjQzNzUgMTcuNTYyNSBDMjYuOTA2NDA2MjUgMTguMDA3 + MjI2NTYgMjYuMzc1MzEyNSAxOC40NTE5NTMxMyAyNS44MjgxMjUgMTguOTEwMTU2MjUgQzI0Ljc2 + ODUxNTYyIDE5Ljc1OTAwMzkxIDI0Ljc2ODUxNTYyIDE5Ljc1OTAwMzkxIDIzLjY4NzUgMjAuNjI1 + IEMyMi42NDMzNTkzNyAyMS40Nzc3MTQ4NCAyMi42NDMzNTkzNyAyMS40Nzc3MTQ4NCAyMS41Nzgx + MjUgMjIuMzQ3NjU2MjUgQzE5LjQzNzUgMjMuNTYyNSAxOS40Mzc1IDIzLjU2MjUgMTcuNDMzNTkz + NzUgMjMuMzcxMDkzNzUgQzE1LjMxOTMzNjk2IDIyLjUxNDYzMzU2IDEzLjI4MjI3MDIgMjEuNTk5 + NjA1OTkgMTEuMjUgMjAuNTYyNSBDMTAuNTU1MTk1MzEgMjAuMjExODc1IDkuODYwMzkwNjMgMTku + ODYxMjUgOS4xNDQ1MzEyNSAxOS41IEM3LjQzNzUgMTguNTYyNSA3LjQzNzUgMTguNTYyNSA2LjQz + NzUgMTcuNTYyNSBDNS45NzczODc1IDE0LjIzOTQ2NTI1IDUuNzMzNjg3ODggMTAuOTA1MTkxODIg + NS40Mzc1IDcuNTYyNSBDMS40Nzc1IDcuNTYyNSAtMi40ODI1IDcuNTYyNSAtNi41NjI1IDcuNTYy + NSBaICIgZmlsbD0iIzAwMDAwMCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTMuNTYyNSw0Ni40Mzc1 + KSIvPgo8cGF0aCBkPSJNMCAwIEMwLjMzIDEuOTggMC42NiAzLjk2IDEgNiBDMy4zNzQyOTI5NiA2 + LjI1MDY5OTEzIDMuMzc0MjkyOTYgNi4yNTA2OTkxMyA2IDYgQzYuNDk1IDUuNDg0Mzc1IDYuOTkg + NC45Njg3NSA3LjUgNC40Mzc1IEM3Ljk5NSAzLjk2MzEyNSA4LjQ5IDMuNDg4NzUgOSAzIEMxMS43 + OTQ2NDYxNiAzLjE0MzMxNTE5IDEzLjgwNjYwNDIyIDMuOTE4NTcwMiAxNi4zNzUgNSBDMTggNyAx + OCA3IDE4LjAyMzQzNzUgOS4xOTkyMTg3NSBDMTcuNzcxNTI5NzkgMTEuNDkxNTc4OTQgMTcuNDM2 + NjUxNzYgMTMuNzM2MDU1NTMgMTcgMTYgQzE5LjY0IDE2Ljk5IDIyLjI4IDE3Ljk4IDI1IDE5IEMy + NS40OTUgMjMuNDU1IDI1LjQ5NSAyMy40NTUgMjYgMjggQzI0LjAyIDI4LjY2IDIyLjA0IDI5LjMy + IDIwIDMwIEMxOS44MzMxMjU1MiAzMi40MTY0NTc4MiAxOS44MzMxMjU1MiAzMi40MTY0NTc4MiAy + MCAzNSBDMjAuNjYgMzUuNjYgMjEuMzIgMzYuMzIgMjIgMzcgQzIyLjQzNzUgMzkuMzEyNSAyMi40 + Mzc1IDM5LjMxMjUgMjIgNDIgQzE5LjUgNDQuODEyNSAxOS41IDQ0LjgxMjUgMTcgNDcgQzE1Ljkw + Njg3NSA0Ni42NDkzNzUgMTQuODEzNzUgNDYuMjk4NzUgMTMuNjg3NSA0NS45Mzc1IEMxMC4wOTA3 + OTYyNyA0NC42Njk2MDU0NiAxMC4wOTA3OTYyNyA0NC42Njk2MDU0NiA3IDQ2IEM3LjIyNjg3NSA0 + Ni43NjMxMjUgNy40NTM3NSA0Ny41MjYyNSA3LjY4NzUgNDguMzEyNSBDOCA1MSA4IDUxIDcuMDYy + NSA1Mi44MTI1IEMzLjc2NzgxODg4IDU0LjcwOTQzNzYyIDAuNzU3NjE1MzYgNTQuMTg0ODAwNzYg + LTMgNTQgQy0zLjIyNjg3NSA1My4yMTYyNSAtMy40NTM3NSA1Mi40MzI1IC0zLjY4NzUgNTEuNjI1 + IEMtNC43ODEyNSA0OC43ODEyNSAtNC43ODEyNSA0OC43ODEyNSAtNy42MjUgNDcuNjg3NSBDLTgu + NDA4NzUgNDcuNDYwNjI1IC05LjE5MjUgNDcuMjMzNzUgLTEwIDQ3IEMtMTAuNjYgNDguMzIgLTEx + LjMyIDQ5LjY0IC0xMiA1MSBDLTE2LjgzMjU2MzA1IDUwLjU4NTc4MDMxIC0xOC44MjY3OTIxOCA0 + OC41MzU4NjAxNCAtMjIgNDUgQy0yMS42NDkzNzUgNDQuMDUxMjUgLTIxLjI5ODc1IDQzLjEwMjUg + LTIwLjkzNzUgNDIuMTI1IEMtMTkuNjQ5NzMyMjMgMzkuMTI5Mzk4MjggLTE5LjY0OTczMjIzIDM5 + LjEyOTM5ODI4IC0yMSAzNyBDLTIyLjE1NSAzNi42NyAtMjMuMzEgMzYuMzQgLTI0LjUgMzYgQy0y + NS42NTUgMzUuNjcgLTI2LjgxIDM1LjM0IC0yOCAzNSBDLTI5LjYwNzI1NjM1IDMxLjc4NTQ4NzMx + IC0yOS4wNTc0ODE4NSAyOC41NjM4NzQ2NCAtMjkgMjUgQy0yNy4wMiAyNC42NyAtMjUuMDQgMjQu + MzQgLTIzIDI0IEMtMjIuNzQ5MzAwODcgMjEuNjI1NzA3MDQgLTIyLjc0OTMwMDg3IDIxLjYyNTcw + NzA0IC0yMyAxOSBDLTIzLjUxNTYyNSAxOC41MDUgLTI0LjAzMTI1IDE4LjAxIC0yNC41NjI1IDE3 + LjUgQy0yNS4wMzY4NzUgMTcuMDA1IC0yNS41MTEyNSAxNi41MSAtMjYgMTYgQy0yNS45MTU5Njc0 + MiAxMi43MjI3Mjk0NiAtMjUuMTc5MDA3ODggMTEuMjM0NTYyMDUgLTIzLjE4NzUgOC42MjUgQy0y + MSA3IC0yMSA3IC0xOC45Mzc1IDcuMTg3NSBDLTE4LjI5ODEyNSA3LjQ1NTYyNSAtMTcuNjU4NzUg + Ny43MjM3NSAtMTcgOCBDLTE0IDkuMzMzMzMzMzMgLTE0IDkuMzMzMzMzMzMgLTExIDggQy0xMSA1 + LjY5IC0xMSAzLjM4IC0xMSAxIEMtMy41NzE0Mjg1NyAtMS40Mjg1NzE0MyAtMy41NzE0Mjg1NyAt + MS40Mjg1NzE0MyAwIDAgWiBNLTExIDIyIEMtMTIuNDUxNDc5MDMgMjQuOTAyOTU4MDUgLTEyLjM3 + MjM5MDI1IDI2Ljc3MjYxNzc5IC0xMiAzMCBDLTEwLjE4Njg5ODU4IDMyLjkyOTM3NjU0IC04LjEy + NzA0MTAxIDM1LjQzNjQ3OTQ5IC01IDM3IEMwLjI2ODgzODc2IDM3LjU5ODczMTY4IDIuODg0NjQ2 + OCAzNi4yNTQwMDAyMSA3IDMzIEM4LjYwMDg2NjI3IDI5Ljc5ODI2NzQ2IDguNDk5MTcwODkgMjYu + NDc0MjI5NDEgOCAyMyBDNi4yMDYzNjA4OSAyMC4xODk5NjU0IDQuOTgxMTkwNjUgMTguNDkwNTk1 + MzIgMiAxNyBDLTQuMzgyODkwNjUgMTYuMzcyMTc0NjkgLTYuODM1Njc5NzQgMTYuNjk5OTU2MDQg + LTExIDIyIFogIiBmaWxsPSIjMDAwMDAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjcsMTEyKSIv + Pgo8cGF0aCBkPSJNMCAwIEMwLjcwNTIzODA0IDAuMDA0MDQ4NDYgMS40MTA0NzYwNyAwLjAwODA5 + NjkyIDIuMTM3MDg0OTYgMC4wMTIyNjgwNyBDMi44NjE5ODEyIDAuMDEwMzU0NjEgMy41ODY4Nzc0 + NCAwLjAwODQ0MTE2IDQuMzMzNzQwMjMgMC4wMDY0Njk3MyBDNS44NjY5ODc1OCAwLjAwNTEwODIg + Ny40MDAyNDY0NiAwLjAwODgwMjQzIDguOTMzNDcxNjggMC4wMTcxNTA4OCBDMTEuMjg0MTU3NTUg + MC4wMjc4NTEyOSAxMy42MzQwNzkxOSAwLjAxNzI1NDk4IDE1Ljk4NDc0MTIxIDAuMDA0NDU1NTcg + QzE3LjQ3MzAyNDE1IDAuMDA1Nzc3MTcgMTguOTYxMzA2NjIgMC4wMDgzMzk1NyAyMC40NDk1ODQ5 + NiAwLjAxMjI2ODA3IEMyMS4xNTQ4MjMgMC4wMDgyMTk2IDIxLjg2MDA2MTA0IDAuMDA0MTcxMTQg + MjIuNTg2NjY5OTIgMCBDMjcuNTYzNDEwMTEgMC4wNDc5NjgyMSAyNy41NjM0MTAxMSAwLjA0Nzk2 + ODIxIDI5Ljc5MzMzNDk2IDIuMjc3ODkzMDcgQzI5Ljk5MjgyMDUzIDQuNzYzNTU4NSAzMC4wNzMy + MzIzOSA3LjEzNTQwMDU2IDMwLjA1ODk1OTk2IDkuNjIxNjQzMDcgQzMwLjA2MTgzMDE0IDEwLjcw + ODk4NzQzIDMwLjA2MTgzMDE0IDEwLjcwODk4NzQzIDMwLjA2NDc1ODMgMTEuODE4Mjk4MzQgQzMw + LjA2NjExOTgzIDEzLjM1MTU0NTY4IDMwLjA2MjQyNTYgMTQuODg0ODA0NTYgMzAuMDU0MDc3MTUg + MTYuNDE4MDI5NzkgQzMwLjA0MzM3Njc0IDE4Ljc2ODcxNTY2IDMwLjA1Mzk3MzA0IDIxLjExODYz + NzI5IDMwLjA2Njc3MjQ2IDIzLjQ2OTI5OTMyIEMzMC4wNjU0NTA4NiAyNC45NTc1ODIyNiAzMC4w + NjI4ODg0NSAyNi40NDU4NjQ3MiAzMC4wNTg5NTk5NiAyNy45MzQxNDMwNyBDMzAuMDYzMDA4NDIg + MjguNjM5MzgxMSAzMC4wNjcwNTY4OCAyOS4zNDQ2MTkxNCAzMC4wNzEyMjgwMyAzMC4wNzEyMjgw + MyBDMzAuMDIzMjU5ODIgMzUuMDQ3OTY4MjEgMzAuMDIzMjU5ODIgMzUuMDQ3OTY4MjEgMjcuNzkz + MzM0OTYgMzcuMjc3ODkzMDcgQzI1LjI5MzMzNDk2IDM3LjUyNzg5MzA3IDI1LjI5MzMzNDk2IDM3 + LjUyNzg5MzA3IDIyLjc5MzMzNDk2IDM3LjI3Nzg5MzA3IEMyMC40Mzk3NTI0NSAzNC45MjQzMTA1 + NSAyMC41MTQ2MTU5MiAzNC4zNDgyMDkxMyAyMC4zNzkyNzI0NiAzMS4xNDUwODA1NyBDMjAuMzIx + MjY0NjUgMjkuOTM2NTg0NDcgMjAuMzIxMjY0NjUgMjkuOTM2NTg0NDcgMjAuMjYyMDg0OTYgMjgu + NzAzNjc0MzIgQzIwLjIzMTE0NzQ2IDI3Ljg2MTkxNjUgMjAuMjAwMjA5OTYgMjcuMDIwMTU4Njkg + MjAuMTY4MzM0OTYgMjYuMTUyODkzMDcgQzIwLjExMDMyNzE1IDI0Ljg3ODY1NDc5IDIwLjExMDMy + NzE1IDI0Ljg3ODY1NDc5IDIwLjA1MTE0NzQ2IDIzLjU3ODY3NDMyIEMxOS45NTY3NzAwMiAyMS40 + Nzg3NzYyMyAxOS44NzM5NTkxIDE5LjM3ODM2NDE2IDE5Ljc5MzMzNDk2IDE3LjI3Nzg5MzA3IEMx + OS4wNjIxOTQ4MiAxOC4wMjk5ODA0NyAxOC4zMzEwNTQ2OSAxOC43ODIwNjc4NyAxNy41Nzc3NTg3 + OSAxOS41NTY5NDU4IEMxNC44NTc3MTA3NCAyMi4zNDk0OTQ1MyAxMi4xMjQzNjMyMiAyNS4xMjg3 + MDE3OCA5LjM4Njg0MDgyIDI3LjkwNDExMzc3IEM4LjIwNDc5MzY1IDI5LjEwNjI1MzMyIDcuMDI2 + MzY0MjkgMzAuMzExOTYxNTUgNS44NTE2ODQ1NyAzMS41MjEzMDEyNyBDNC4xNjA2ODI1NyAzMy4y + NjA5MjQwNSAyLjQ1NzAwMzc0IDM0Ljk4NzIxNzQgMC43NTAzNjYyMSAzNi43MTE0ODY4MiBDMC4y + MjkzMjgxNiAzNy4yNTMxNzAwMSAtMC4yOTE3MDk5IDM3Ljc5NDg1MzIxIC0wLjgyODUzNjk5IDM4 + LjM1Mjk1MTA1IEMtMy43OTIzODM2IDQxLjMxODU4ODA1IC01LjkyNzM5ODczIDQzLjEyMTk4NzIy + IC0xMC4yMDY2NjUwNCA0My4yNzc4OTMwNyBDLTEyLjA4MTY2NTA0IDQyLjE1Mjg5MzA3IC0xMi4w + ODE2NjUwNCA0Mi4xNTI4OTMwNyAtMTMuMjA2NjY1MDQgNDAuMjc3ODkzMDcgQy0xMy4wMjI1NTQ0 + NSAzNS4yMjQ0Njk2MyAtMTAuMDg2MzkzMDcgMzIuNjM1NjUzNzcgLTYuNjQwMjU4NzkgMjkuMzIw + ODYxODIgQy02LjA4Njc3MjYxIDI4Ljc3MzAzNTQzIC01LjUzMzI4NjQ0IDI4LjIyNTIwOTA1IC00 + Ljk2MzAyNzk1IDI3LjY2MDc4MTg2IEMtMy4xOTkyNjQ5MyAyNS45MTkzNDU1NCAtMS40MjIwODcx + NyAyNC4xOTIzNTk0NyAwLjM1NTgzNDk2IDIyLjQ2NTM5MzA3IEMxLjU1NjYxNzYyIDIxLjI4NDY4 + MDEgMi43NTY0OTg0NCAyMC4xMDMwNDkyMyAzLjk1NTQ0NDM0IDE4LjkyMDQ3MTE5IEM2Ljg5MTA2 + MzI2IDE2LjAyODg3MDM3IDkuODM4Nzg5NzggMTMuMTUwMTQ3NzUgMTIuNzkzMzM0OTYgMTAuMjc3 + ODkzMDcgQzExLjAwNDc2MDc0IDEwLjIwNDQxNjUgMTEuMDA0NzYwNzQgMTAuMjA0NDE2NSA5LjE4 + MDA1MzcxIDEwLjEyOTQ1NTU3IEM3LjYxMzYyNDI4IDEwLjA1NDQxNzAzIDYuMDQ3MjE5MTcgOS45 + Nzg4Njk2NyA0LjQ4MDgzNDk2IDkuOTAyODkzMDcgQzMuMzAyMzA5NTcgOS44NTY0ODY4MiAzLjMw + MjMwOTU3IDkuODU2NDg2ODIgMi4wOTk5NzU1OSA5LjgwOTE0MzA3IEMxLjM0MjY1MTM3IDkuNzcw + NDcxMTkgMC41ODUzMjcxNSA5LjczMTc5OTMyIC0wLjE5NDk0NjI5IDkuNjkxOTU1NTcgQy0xLjIz + OTY5MTE2IDkuNjQ0ODI0MjIgLTEuMjM5NjkxMTYgOS42NDQ4MjQyMiAtMi4zMDU1NDE5OSA5LjU5 + Njc0MDcyIEMtNC4yMDY2NjUwNCA5LjI3Nzg5MzA3IC00LjIwNjY2NTA0IDkuMjc3ODkzMDcgLTcu + MjA2NjY1MDQgNy4yNzc4OTMwNyBDLTcuNTE5MTY1MDQgNC43Nzc4OTMwNyAtNy41MTkxNjUwNCA0 + Ljc3Nzg5MzA3IC03LjIwNjY2NTA0IDIuMjc3ODkzMDcgQy00Ljc0NjYzNzE3IC0wLjE4MjEzNDgx + IC0zLjM1ODcyNjY1IDAuMDMyMzczMDIgMCAwIFogIiBmaWxsPSIjMDAwMDAwIiB0cmFuc2Zvcm09 + InRyYW5zbGF0ZSgxMzQuMjA2NjY1MDM5MDYyNSwzNC43MjIxMDY5MzM1OTM3NSkiLz4KPHBhdGgg + ZD0iTTAgMCBDNC45MTAwOTMwOCA0LjkxMDA5MzA4IDYuODEzOTk2MzggMTAuNTc4ODM3MDcgNy4x + MDE1NjI1IDE3LjQxNDA2MjUgQzYuNzc3MTk5NyAyNS40NzMyMzA1MSAzLjE3MjkxODA4IDMwLjkw + NjQwNDg3IC0yLjUgMzYuNDM3NSBDLTguMzkyNzAyNSA0MC4xMjA0MzkwNiAtMTQuMTg3NDc0NCA0 + MC44MDI2ODQyOSAtMjEgNDAgQy0yOC4yMjA2MzA5OSAzOC4xNDE5MjIzMiAtMzIuODI2MTM0NTkg + MzQuMDcxMDc2OTYgLTM3IDI4IEMtMzkuODk4MjY4NzYgMjIuMjAzNDYyNDcgLTQwLjEwNDM0MzM2 + IDE1LjQ5MjgwNjkgLTM4LjE2MDE1NjI1IDkuMzQzNzUgQy0zNS4xMDMyNTE0NCAyLjUwOTQ1Nzc4 + IC0zMC45NDU0MDU0MyAtMS44OTg2OTEzNyAtMjQuMDIzNDM3NSAtNC44Mzk4NDM3NSBDLTE1LjMw + Mzg3NjM5IC03LjQ5NzM5OTIzIC03LjE4NDY2MzYzIC01LjM5ODk2MDgyIDAgMCBaIE0tMjkuNDM3 + NSA3LjYyNSBDLTMyLjU2MjU5NTMxIDEyLjM3NTE0NDg3IC0zMi41ODc5NDk0MyAxNi4zOTc2ODE4 + OCAtMzIgMjIgQy0zMC42NzYwMDY4NCAyNi4yMzUxODI5NSAtMjguMzc4NTY4ODYgMjguNzA0NzE2 + MjkgLTI0Ljg3NSAzMS40Mzc1IEMtMjAuNDA0OTU2ODIgMzMuNjU4MTAyMSAtMTUuODcyNTA4Nzcg + MzMuNzk3MzE5NjIgLTExIDMzIEMtNi41NzUxNTEyMiAzMC43ODc1NzU2MSAtMy44MDUyMzM0MyAy + OC4wNTIwMDM4NCAtMSAyNCBDMC42OTE3OTQ2NiAxOC45MjQ2MTYwMyAwLjU2MzcxODY3IDE0LjY4 + MDM1NTY0IC0xLjYyNSA5LjgxMjUgQy0zLjc3NTI3MTAxIDUuOTQ2NTA3NTIgLTUuOTMwODQ4OTYg + My45MTk0MTA4NyAtMTAgMiBDLTE3LjkxMDY3OTExIC0wLjI0NTUxNzQ1IC0yMy44NzQ0NzAzOCAx + LjYzNDA0NTAyIC0yOS40Mzc1IDcuNjI1IFogIiBmaWxsPSIjMDAwMDAwIiB0cmFuc2Zvcm09InRy + YW5zbGF0ZSg2OCw4MikiLz4KPHBhdGggZD0iTTAgMCBDNy4yNiAwIDE0LjUyIDAgMjIgMCBDMjIg + Ny4yNiAyMiAxNC41MiAyMiAyMiBDMjAuMzUgMjIuMzMgMTguNyAyMi42NiAxNyAyMyBDMTUuODUx + ODUwMDMgMjAuNzAzNzAwMDYgMTUuNjkyMzAxOTEgMTguOTIzMDE5MTQgMTUuNDM3NSAxNi4zNzUg + QzE1LjM1MzcxMDk0IDE1LjU1NzczNDM4IDE1LjI2OTkyMTg3IDE0Ljc0MDQ2ODc1IDE1LjE4MzU5 + Mzc1IDEzLjg5ODQzNzUgQzE1LjEyMzAwNzgxIDEzLjI3MTk1MzEyIDE1LjA2MjQyMTg3IDEyLjY0 + NTQ2ODc1IDE1IDEyIEMxNC41NTI2OTUzMSAxMi40OTM3MTA5NCAxNC4xMDUzOTA2MiAxMi45ODc0 + MjE4OCAxMy42NDQ1MzEyNSAxMy40OTYwOTM3NSBDNy42Mzk3MTg4IDE5Ljg1OTQwMjQ2IDcuNjM5 + NzE4OCAxOS44NTk0MDI0NiAzIDIwIEMyLjI4NTE1NjI1IDE3Ljc2OTUzMTI1IDIuMjg1MTU2MjUg + MTcuNzY5NTMxMjUgMiAxNSBDMy40MzM1OTM3NSAxMi43NjE3MTg3NSAzLjQzMzU5Mzc1IDEyLjc2 + MTcxODc1IDUuNDM3NSAxMC42ODc1IEM2LjA5NjIxMDk0IDkuOTkwMTE3MTkgNi43NTQ5MjE4NyA5 + LjI5MjczNDM4IDcuNDMzNTkzNzUgOC41NzQyMTg3NSBDNy45NTA1MDc4MSA4LjA1NDcyNjU2IDgu + NDY3NDIxODcgNy41MzUyMzQzOCA5IDcgQzcuNzIxMjUgNi45MTc1IDYuNDQyNSA2LjgzNSA1LjEy + NSA2Ljc1IEMxLjIyMDI3MzkxIDYuMjczMTM5NjUgMS4yMjAyNzM5MSA2LjI3MzEzOTY1IC0wLjU2 + MjUgNC4wNjI1IEMtMSAyIC0xIDIgMCAwIFogIiBmaWxsPSIjMDAwMDAwIiB0cmFuc2Zvcm09InRy + YW5zbGF0ZSg3NiwxNikiLz4KPHBhdGggZD0iTTAgMCBDMC44OTQ2MDkzNyAtMC4wMDEyODkwNiAx + Ljc4OTIxODc1IC0wLjAwMjU3ODEyIDIuNzEwOTM3NSAtMC4wMDM5MDYyNSBDMy42NTE5NTMxMyAt + MC4wMDAwMzkwNiA0LjU5Mjk2ODc1IDAuMDAzODI4MTIgNS41NjI1IDAuMDA3ODEyNSBDNi45NzQw + MjM0NCAwLjAwMjAxMTcyIDYuOTc0MDIzNDQgMC4wMDIwMTE3MiA4LjQxNDA2MjUgLTAuMDAzOTA2 + MjUgQzkuNzU1OTc2NTYgLTAuMDAxOTcyNjYgOS43NTU5NzY1NiAtMC4wMDE5NzI2NiAxMS4xMjUg + MCBDMTEuOTUxMjg5MDYgMC4wMDExMjc5MyAxMi43Nzc1NzgxMiAwLjAwMjI1NTg2IDEzLjYyODkw + NjI1IDAuMDAzNDE3OTcgQzE1LjU2MjUgMC4xMzI4MTI1IDE1LjU2MjUgMC4xMzI4MTI1IDE2LjU2 + MjUgMS4xMzI4MTI1IEMxNi42NDkzNTYwMyAyLjY5NDUzOTk1IDE2LjY2OTUyMjE5IDQuMjYwMTA1 + OTQgMTYuNjYwMTU2MjUgNS44MjQyMTg3NSBDMTYuNjU2OTMzNTkgNi43Njg0NTcwMyAxNi42NTM3 + MTA5NCA3LjcxMjY5NTMxIDE2LjY1MDM5MDYyIDguNjg1NTQ2ODggQzE2LjY0MjAxMTcyIDkuNjc4 + NzY5NTMgMTYuNjMzNjMyODEgMTAuNjcxOTkyMTkgMTYuNjI1IDExLjY5NTMxMjUgQzE2LjYyMDQ4 + ODI4IDEyLjY5MjQwMjM0IDE2LjYxNTk3NjU2IDEzLjY4OTQ5MjE5IDE2LjYxMTMyODEyIDE0Ljcx + Njc5Njg4IEMxNi41OTk1MDAwNyAxNy4xODg4NjA5OSAxNi41ODMwMTg0OSAxOS42NjA4MDc2OCAx + Ni41NjI1IDIyLjEzMjgxMjUgQzE0LjkxMjUgMjIuNDYyODEyNSAxMy4yNjI1IDIyLjc5MjgxMjUg + MTEuNTYyNSAyMy4xMzI4MTI1IEMxMC40MTQzNTAwMyAyMC44MzY1MTI1NiAxMC4yNTQ4MDE5MSAx + OS4wNTU4MzE2NCAxMCAxNi41MDc4MTI1IEM5Ljg3NDMxNjQxIDE1LjI4MTkxNDA2IDkuODc0MzE2 + NDEgMTUuMjgxOTE0MDYgOS43NDYwOTM3NSAxNC4wMzEyNSBDOS42ODU1MDc4MSAxMy40MDQ3NjU2 + MiA5LjYyNDkyMTg4IDEyLjc3ODI4MTI1IDkuNTYyNSAxMi4xMzI4MTI1IEM5LjA0MzAwNzgxIDEy + LjcyMTkxNDA2IDguNTIzNTE1NjIgMTMuMzExMDE1NjIgNy45ODgyODEyNSAxMy45MTc5Njg3NSBD + Ny4yOTA4OTg0NCAxNC42Njk0OTIxOSA2LjU5MzUxNTYzIDE1LjQyMTAxNTYyIDUuODc1IDE2LjE5 + NTMxMjUgQzUuMTkwNTA3ODEgMTYuOTQ5NDE0MDYgNC41MDYwMTU2MyAxNy43MDM1MTU2MiAzLjgw + MDc4MTI1IDE4LjQ4MDQ2ODc1IEMxLjU2MjUgMjAuMTMyODEyNSAxLjU2MjUgMjAuMTMyODEyNSAt + MS4yMDcwMzEyNSAxOS44Nzg5MDYyNSBDLTEuOTQzMDg1OTQgMTkuNjMyNjk1MzEgLTIuNjc5MTQw + NjMgMTkuMzg2NDg0MzcgLTMuNDM3NSAxOS4xMzI4MTI1IEMtMy4yODM0NTg4NyAxNC4wNDk0NTUy + NSAtMC40MTY4MTU2OCAxMS43NzUyNjUzMiAzLjA2NjQwNjI1IDguNDg4MjgxMjUgQzMuNTYwMTE3 + MTkgOC4wNDA5NzY1NiA0LjA1MzgyODEyIDcuNTkzNjcxODcgNC41NjI1IDcuMTMyODEyNSBDMS41 + OTI1IDYuODAyODEyNSAtMS4zNzc1IDYuNDcyODEyNSAtNC40Mzc1IDYuMTMyODEyNSBDLTQuODE5 + Njg3NjcgNC40NzY2NjU5MyAtNS4xNTE0NTEwMiAyLjgwODI0MjI2IC01LjQzNzUgMS4xMzI4MTI1 + IEMtMy44NDgxMjQ0NCAtMC40NTY1NjMwNiAtMi4xOTg1MDE1NCAwLjAwMzAwMTA3IDAgMCBaICIg + ZmlsbD0iIzAwMDAwMCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTcyLjQzNzUsOTQuODY3MTg3NSki + Lz4KPC9zdmc+Cg== diff --git a/catalog-entities/marketplace/plugins/orchestrator-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/orchestrator-scaffolder-actions.yaml index 74b55cb9ed..aad910aabb 100644 --- a/catalog-entities/marketplace/plugins/orchestrator-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/orchestrator-scaffolder-actions.yaml @@ -6,7 +6,7 @@ metadata: namespace: rhdh title: Orchestrator Scaffolder Actions For Red Hat Developer Hub annotations: - extensions.backstage.io/pre-installed: 'false' # For plugins contained in the RHDH image + extensions.backstage.io/pre-installed: 'true' # this means the plugin yaml is preinstalled, not the plugin itself links: - title: Homepage url: https://www.rhdhorchestrator.io/ @@ -20,7 +20,9 @@ metadata: description: This plugin contains a collection of actions for working with Orchestrator spec: author: Red Hat - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/orchestrator.yaml b/catalog-entities/marketplace/plugins/orchestrator.yaml index 54975d6098..8c1a046a65 100644 --- a/catalog-entities/marketplace/plugins/orchestrator.yaml +++ b/catalog-entities/marketplace/plugins/orchestrator.yaml @@ -6,7 +6,7 @@ metadata: namespace: rhdh title: Orchestrator For Red Hat Developer Hub annotations: - extensions.backstage.io/pre-installed: 'false' # For plugins contained in the RHDH image + extensions.backstage.io/pre-installed: 'true' # this means the plugin yaml is preinstalled, not the plugin itself links: - title: Homepage url: https://www.rhdhorchestrator.io/ @@ -22,7 +22,9 @@ metadata: or external systems. spec: author: Red Hat - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/pagerduty.yaml b/catalog-entities/marketplace/plugins/pagerduty.yaml index ef3f777f0d..23644c976a 100644 --- a/catalog-entities/marketplace/plugins/pagerduty.yaml +++ b/catalog-entities/marketplace/plugins/pagerduty.yaml @@ -28,7 +28,9 @@ metadata: spec: author: PagerDuty - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/pingidentity.yaml b/catalog-entities/marketplace/plugins/pingidentity.yaml index 1ff5c9fdc8..6ea0af092a 100644 --- a/catalog-entities/marketplace/plugins/pingidentity.yaml +++ b/catalog-entities/marketplace/plugins/pingidentity.yaml @@ -19,7 +19,9 @@ metadata: url: https://github.com/redhat-developer/rhdh/tree/main/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic spec: author: Backstage Community - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/quay-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/quay-scaffolder-actions.yaml index 0cf0325b7f..5a3e55937a 100644 --- a/catalog-entities/marketplace/plugins/quay-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/quay-scaffolder-actions.yaml @@ -26,7 +26,9 @@ spec: - name: Red Hat url: https://redhat.com - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/quickstart.yaml b/catalog-entities/marketplace/plugins/quickstart.yaml new file mode 100644 index 0000000000..cabc41c537 --- /dev/null +++ b/catalog-entities/marketplace/plugins/quickstart.yaml @@ -0,0 +1,50 @@ +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: quickstart + namespace: rhdh + title: Quickstart + description: "Guided quickstarts to help users discover and set up key features in Red Hat Developer Hub." + annotations: + extensions.backstage.io/pre-installed: 'true' + tags: + - onboarding + - customization + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHIDP + title: Bugs + - title: Documentation for Red Hat Developer Hub + url: https://docs.redhat.com/en/documentation/red_hat_developer_hub + - title: Source Code + url: https://github.com/redhat-developer/rhdh/tree/main/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart +spec: + author: Red Hat + support: + provider: Red Hat + level: generally-available + lifecycle: active + publisher: Red Hat + + categories: + - Customization + + highlights: + - Provide in-product quickstarts and guidance + + description: | + Quickstart provides in-product, contextual onboarding flows that help users set up and discover + features in Red Hat Developer Hub. It includes a help button in the global header and a drawer + provider to surface guidance when needed. + + ## Adding The Plugin To Red Hat Developer Hub + + See the [Red Hat Developer Hub documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) + for further instructions on how to add, enable, configure, and remove plugins in your instance. + + + packages: + - rhdh-backstage-plugin-quickstart + + diff --git a/catalog-entities/marketplace/plugins/rbac.yaml b/catalog-entities/marketplace/plugins/rbac.yaml index 271e14969f..fbd6004e8a 100644 --- a/catalog-entities/marketplace/plugins/rbac.yaml +++ b/catalog-entities/marketplace/plugins/rbac.yaml @@ -23,7 +23,9 @@ metadata: - rbac spec: author: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/redhat-argocd.yaml b/catalog-entities/marketplace/plugins/redhat-argocd.yaml index 71c239161c..a76f81afc9 100644 --- a/catalog-entities/marketplace/plugins/redhat-argocd.yaml +++ b/catalog-entities/marketplace/plugins/redhat-argocd.yaml @@ -25,7 +25,9 @@ spec: - CI/CD author: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat description: | diff --git a/catalog-entities/marketplace/plugins/regex-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/regex-scaffolder-actions.yaml index 7bb55f7443..39e1231c39 100644 --- a/catalog-entities/marketplace/plugins/regex-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/regex-scaffolder-actions.yaml @@ -25,7 +25,9 @@ metadata: spec: author: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/roadie-argocd.yaml b/catalog-entities/marketplace/plugins/roadie-argocd.yaml index 0b73048c9e..5705a552ab 100644 --- a/catalog-entities/marketplace/plugins/roadie-argocd.yaml +++ b/catalog-entities/marketplace/plugins/roadie-argocd.yaml @@ -16,7 +16,9 @@ metadata: title: Roadie Documentation spec: lifecycle: active - support: production + support: + provider: Red Hat + level: generally-available publisher: Red Hat author: Roadie diff --git a/catalog-entities/marketplace/plugins/roadie-scaffolder-util-actions.yaml b/catalog-entities/marketplace/plugins/roadie-scaffolder-util-actions.yaml index a4b840f9ed..42e9611c4e 100644 --- a/catalog-entities/marketplace/plugins/roadie-scaffolder-util-actions.yaml +++ b/catalog-entities/marketplace/plugins/roadie-scaffolder-util-actions.yaml @@ -24,7 +24,9 @@ metadata: spec: author: Roadie - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/scaffolder-integrations.yaml b/catalog-entities/marketplace/plugins/scaffolder-integrations.yaml index 9b1154e3f9..0ee062e0fa 100644 --- a/catalog-entities/marketplace/plugins/scaffolder-integrations.yaml +++ b/catalog-entities/marketplace/plugins/scaffolder-integrations.yaml @@ -30,7 +30,7 @@ spec: - backstage-plugin-scaffolder-backend-module-gerrit - backstage-plugin-scaffolder-backend-module-github - backstage-plugin-scaffolder-backend-module-gitlab - - parfuemerie-douglas-scaffolder-backend-module-azure-repositorie + - parfuemerie-douglas-scaffolder-backend-module-azure-repositories - roadiehq-scaffolder-backend-argocd - roadiehq-scaffolder-backend-module-http-request - roadiehq-scaffolder-backend-module-utils diff --git a/catalog-entities/marketplace/plugins/scaffolder-relation-processor-catalog-integration.yaml b/catalog-entities/marketplace/plugins/scaffolder-relation-processor-catalog-integration.yaml index 9637793adf..ead8cf654b 100644 --- a/catalog-entities/marketplace/plugins/scaffolder-relation-processor-catalog-integration.yaml +++ b/catalog-entities/marketplace/plugins/scaffolder-relation-processor-catalog-integration.yaml @@ -27,7 +27,9 @@ spec: author: Backstage Community publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: - Software Catalog diff --git a/catalog-entities/marketplace/plugins/scorecard.yaml b/catalog-entities/marketplace/plugins/scorecard.yaml new file mode 100644 index 0000000000..c97e5f0075 --- /dev/null +++ b/catalog-entities/marketplace/plugins/scorecard.yaml @@ -0,0 +1,67 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: scorecard + namespace: rhdh + title: Scorecard + description: | + Track the health, security, and compliance of your components with customizable KPIs. + annotations: + extensions.backstage.io/pre-installed: 'true' + tags: + - analytics + + links: + - url: https://red.ht/rhdh + title: Homepage + - url: https://issues.redhat.com/browse/RHIDP + title: Bugs + - title: Documentation for Red Hat Developer Hub + url: https://docs.redhat.com/en/documentation/red_hat_developer_hub + - title: Source Code + url: https://github.com/redhat-developer/rhdh/tree/main/dynamic-plugins/wrappers/ + +spec: + + author: Red Hat + support: + provider: Red Hat + level: tech-preview + lifecycle: active + publisher: Red Hat + + categories: + - Analytics + + highlights: + - Centralized KPIs monitoring + - Visual health indication by scoring thresholds + - Customizable scoring thresholds + - Integration with GitHub and Jira data sources + - Extensible through custom backend modules for integrating your own metrics and data sources + + description: | + The Scorecard plugin offers comprehensive, customizable insights into the health, security posture, and compliance + of your components, services, and APIs. It centralizes Key Performance Indicators (KPIs) in your Backstage instance, + so you do not have to consult multiple external systems. + + ## Adding The Plugin To Red Hat Developer Hub + + See the [Red Hat Developer Hub documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) + for further instructions on how to add, enable, and configure plugins in your instance. + + ## Configuring The Plugin ## + + Plugins often need additional configuration to work correctly - particularly those that integrate with other + systems. See the original source code repository, the software vendor, or the [Red Hat Developer Hub documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) + for further details regarding the configuration required. + + icon: data:image/svg+xml;base64, + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjM4IiBoZWlnaHQ9IjM4IiB2aWV3Qm94PSIwIDAgMzggMzgiPjxnIGlkPSJ1dWlkLTc5MDFmODc4LWNlMDAtNDQxZi1hYzI2LWRkZDM2NTRkNGY3OSI+PHJlY3QgeD0iMSIgeT0iMSIgd2lkdGg9IjM2IiBoZWlnaHQ9IjM2IiByeD0iOSIgcnk9IjkiIHN0cm9rZS13aWR0aD0iMCIvPjxwYXRoIGQ9Im0yOCwyLjI1YzQuMjczMzYsMCw3Ljc1LDMuNDc2NjQsNy43NSw3Ljc1djE4YzAsNC4yNzMzNi0zLjQ3NjY0LDcuNzUtNy43NSw3Ljc1SDEwYy00LjI3MzM2LDAtNy43NS0zLjQ3NjY0LTcuNzUtNy43NVYxMGMwLTQuMjczMzYsMy40NzY2NC03Ljc1LDcuNzUtNy43NWgxOG0wLTEuMjVIMTBDNS4wMjk0NCwxLDEsNS4wMjk0MywxLDEwdjE4YzAsNC45NzA1Nyw0LjAyOTQ0LDksOSw5aDE4YzQuOTcwNTYsMCw5LTQuMDI5NDMsOS05VjEwYzAtNC45NzA1Ny00LjAyOTQ0LTktOS05aDBaIiBmaWxsPSIjNGQ0ZDRkIiBzdHJva2Utd2lkdGg9IjAiLz48L2c+PGcgaWQ9InV1aWQtYzNjYTY4OTEtNmUxOC00MmNiLTg1MmItM2RlZGQ2YzMxZTY4Ij48cGF0aCBkPSJtMjYuNDQyMzgsMjUuNTU4MTFsLTMuNzczNzQtMy43NzM3NGMuNTkxNDMtLjc3NzA0Ljk1NjM2LTEuNzM0OC45NTYzNi0yLjc4NDM2LDAtMi41NTAyOS0yLjA3NTItNC42MjUtNC42MjUtNC42MjUtMi41NTAyOSwwLTQuNjI1LDIuMDc0NzEtNC42MjUsNC42MjVzMi4wNzQ3MSw0LjYyNSw0LjYyNSw0LjYyNWMxLjA0OTQ0LDAsMi4wMDcyNi0uMzY0OTMsMi43ODQzNi0uOTU2MzZsMy43NzMyNSwzLjc3MzI1Yy4xMjIwNy4xMjIwNy4yODIyMy4xODMxMS40NDIzOC4xODMxMXMuMzIwMzEtLjA2MTA0LjQ0MjM4LS4xODMxMWMuMjQzMTYtLjI0NDE0LjI0MzE2LS42Mzk2NSwwLS44ODM3OVptLTEwLjgxNzM4LTYuNTU4MTFjMC0xLjg2MDg0LDEuNTE0MTYtMy4zNzUsMy4zNzUtMy4zNzUsMS44NjEzMywwLDMuMzc1LDEuNTE0MTYsMy4zNzUsMy4zNzVzLTEuNTEzNjcsMy4zNzUtMy4zNzUsMy4zNzVjLTEuODYwODQsMC0zLjM3NS0xLjUxNDE2LTMuMzc1LTMuMzc1WiIgZmlsbD0iI2UwMCIgc3Ryb2tlLXdpZHRoPSIwIi8+PHBhdGggZD0ibTI3LDEzLjYyNWMxLjQ0NzI3LDAsMi42MjUtMS4xNzc3MywyLjYyNS0yLjYyNXMtMS4xNzc3My0yLjYyNS0yLjYyNS0yLjYyNS0yLjYyNSwxLjE3NzczLTIuNjI1LDIuNjI1YzAsLjQ5NjcuMTQ2NjEuOTU2NTQuMzg3MjcsMS4zNTMwM2wtMS4yMDQ2NSwxLjIwNTA4Yy0uMjQ0MTQuMjQ0MTQtLjI0MzE2LjYzOTY1LjAwMDk4Ljg4Mzc5LjEyMTA5LjEyMjA3LjI4MTI1LjE4MzExLjQ0MTQxLjE4MzExcy4zMjAzMS0uMDYxMDQuNDQyMzgtLjE4MzExbDEuMjA0MS0xLjIwNDQ3Yy4zOTY2MS4yNDA5MS44NTY2My4zODc1NywxLjM1MzUyLjM4NzU3Wm0wLTRjLjc1NzgxLDAsMS4zNzUuNjE2NywxLjM3NSwxLjM3NXMtLjYxNzE5LDEuMzc1LTEuMzc1LDEuMzc1Yy0uMzc4MTEsMC0uNzIxMDctLjE1MzY5LS45Njk5Ny0uNDAxNzMtLjAwMDczLS4wMDA3My0uMDAwOTgtLjAwMTgzLS4wMDE3MS0uMDAyNTYtLjAwMDYxLS4wMDA2MS0uMDAxNTMtLjAwMDc5LS4wMDIxNC0uMDAxNC0uMjQ3NjItLjI0ODc4LS40MDExOC0uNTkxMzctLjQwMTE4LS45NjkzLDAtLjc1ODMuNjE3MTktMS4zNzUsMS4zNzUtMS4zNzVaIiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJtMTksOC4zNzVjLTEuMTcxODgsMC0yLjEyNS45NTMxMi0yLjEyNSwyLjEyNXMuOTUzMTIsMi4xMjUsMi4xMjUsMi4xMjUsMi4xMjUtLjk1MzEyLDIuMTI1LTIuMTI1LS45NTMxMi0yLjEyNS0yLjEyNS0yLjEyNVptMCwzYy0uNDgyNDIsMC0uODc1LS4zOTI1OC0uODc1LS44NzVzLjM5MjU4LS44NzUuODc1LS44NzUuODc1LjM5MjU4Ljg3NS44NzUtLjM5MjU4Ljg3NS0uODc1Ljg3NVoiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPjxwYXRoIGQ9Im0xOSwyNS4zNzVjLTEuMTcxODgsMC0yLjEyNS45NTMxMi0yLjEyNSwyLjEyNXMuOTUzMTIsMi4xMjUsMi4xMjUsMi4xMjUsMi4xMjUtLjk1MzEyLDIuMTI1LTIuMTI1LS45NTMxMi0yLjEyNS0yLjEyNS0yLjEyNVptMCwzYy0uNDgyNDIsMC0uODc1LS4zOTI1OC0uODc1LS44NzVzLjM5MjU4LS44NzUuODc1LS44NzUuODc1LjM5MjU4Ljg3NS44NzUtLjM5MjU4Ljg3NS0uODc1Ljg3NVoiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPjxwYXRoIGQ9Im0yNy41LDE2Ljg3NWMtMS4xNzE4OCwwLTIuMTI1Ljk1MzEyLTIuMTI1LDIuMTI1cy45NTMxMiwyLjEyNSwyLjEyNSwyLjEyNSwyLjEyNS0uOTUzMTIsMi4xMjUtMi4xMjUtLjk1MzEyLTIuMTI1LTIuMTI1LTIuMTI1Wm0wLDNjLS40ODI0MiwwLS44NzUtLjM5MjU4LS44NzUtLjg3NXMuMzkyNTgtLjg3NS44NzUtLjg3NS44NzUuMzkyNTguODc1Ljg3NS0uMzkyNTguODc1LS44NzUuODc1WiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+PHBhdGggZD0ibTEyLjYyNSwxOWMwLTEuMTcxODgtLjk1MzEyLTIuMTI1LTIuMTI1LTIuMTI1cy0yLjEyNS45NTMxMi0yLjEyNSwyLjEyNS45NTMxMiwyLjEyNSwyLjEyNSwyLjEyNSwyLjEyNS0uOTUzMTIsMi4xMjUtMi4xMjVabS0zLDBjMC0uNDgyNDIuMzkyNTgtLjg3NS44NzUtLjg3NXMuODc1LjM5MjU4Ljg3NS44NzUtLjM5MjU4Ljg3NS0uODc1Ljg3NS0uODc1LS4zOTI1OC0uODc1LS44NzVaIiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJtMTMuMjM3NDMsMTIuMzUzNjRjLjI0MDkxLS4zOTY2MS4zODc1Ny0uODU2NzUuMzg3NTctMS4zNTM2NCwwLTEuNDQ3MjctMS4xNzc3My0yLjYyNS0yLjYyNS0yLjYyNXMtMi42MjUsMS4xNzc3My0yLjYyNSwyLjYyNSwxLjE3NzczLDIuNjI1LDIuNjI1LDIuNjI1Yy40OTY4OSwwLC45NTcwMy0uMTQ2NjcsMS4zNTM2NC0uMzg3NTdsMS4yMDQ0NywxLjIwNDQ3Yy4xMjIwNy4xMjIwNy4yODE3NC4xODMxMS40NDE4OS4xODMxMXMuMzE5ODItLjA2MTA0LjQ0MTg5LS4xODMxMWMuMjQ0MTQtLjI0NDE0LjI0NDE0LS42Mzk2NSwwLS44ODM3OWwtMS4yMDQ0Ny0xLjIwNDQ3Wm0tMy42MTI0My0xLjM1MzY0YzAtLjc1ODMuNjE2Ny0xLjM3NSwxLjM3NS0xLjM3NXMxLjM3NS42MTY3LDEuMzc1LDEuMzc1YzAsLjM3Nzk5LS4xNTM1LjcyMDU4LS40MDExMi45NjkzNi0uMDAwNzkuMDAwNzktLjAwMTg5LjAwMTA0LS4wMDI2OS4wMDE4M3MtLjAwMTA0LjAwMTg5LS4wMDE4My4wMDI2OWMtLjI0ODc4LjI0NzYyLS41OTEzNy40MDExMi0uOTY5MzYuNDAxMTItLjc1ODMsMC0xLjM3NS0uNjE2Ny0xLjM3NS0xLjM3NVoiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMCIvPjxwYXRoIGQ9Im0xMy41NTgxMSwyMy41NTgxMWwtMS4yMDQ0NywxLjIwNDQ3Yy0uMzk2NjEtLjI0MDkxLS44NTY3NS0uMzg3NTctMS4zNTM2NC0uMzg3NTctMS40NDcyNywwLTIuNjI1LDEuMTc3NzMtMi42MjUsMi42MjVzMS4xNzc3MywyLjYyNSwyLjYyNSwyLjYyNSwyLjYyNS0xLjE3NzczLDIuNjI1LTIuNjI1YzAtLjQ5Njg5LS4xNDY2Ny0uOTU3MDMtLjM4NzU3LTEuMzUzNjRsMS4yMDQ0Ny0xLjIwNDQ3Yy4yNDQxNC0uMjQ0MTQuMjQ0MTQtLjYzOTY1LDAtLjg4Mzc5cy0uNjM5NjUtLjI0NDE0LS44ODM3OSwwWm0tMi41NTgxMSw0LjgxNjg5Yy0uNzU4MywwLTEuMzc1LS42MTY3LTEuMzc1LTEuMzc1cy42MTY3LTEuMzc1LDEuMzc1LTEuMzc1Yy4zNzg4NSwwLC43MjIyOS4xNTM5OS45NzExOS40MDI1OS4wMDAyNC4wMDAyNC4wMDAyNC4wMDA0OS4wMDA0OS4wMDA3M3MuMDAwNDkuMDAwMjQuMDAwNzMuMDAwNDljLjI0ODYuMjQ4OS40MDI1OS41OTIzNS40MDI1OS45NzExOSwwLC43NTgzLS42MTY3LDEuMzc1LTEuMzc1LDEuMzc1WiIgZmlsbD0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIwIi8+PC9nPjwvc3ZnPg== + + packages: + - rhdh-backstage-plugin-scorecard-backend-module-github + - rhdh-backstage-plugin-scorecard-backend-module-jira + - rhdh-backstage-plugin-scorecard-backend + - rhdh-backstage-plugin-scorecard diff --git a/catalog-entities/marketplace/plugins/security-insights.yaml b/catalog-entities/marketplace/plugins/security-insights.yaml index 00df954191..c148896fd6 100644 --- a/catalog-entities/marketplace/plugins/security-insights.yaml +++ b/catalog-entities/marketplace/plugins/security-insights.yaml @@ -26,7 +26,9 @@ metadata: spec: author: Roadie publisher: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: diff --git a/catalog-entities/marketplace/plugins/servicenow-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/servicenow-scaffolder-actions.yaml index 28467632db..9347cb1ed6 100644 --- a/catalog-entities/marketplace/plugins/servicenow-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/servicenow-scaffolder-actions.yaml @@ -27,7 +27,9 @@ metadata: spec: author: Red Hat - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/servicenow.yaml b/catalog-entities/marketplace/plugins/servicenow.yaml new file mode 100644 index 0000000000..b651f8644e --- /dev/null +++ b/catalog-entities/marketplace/plugins/servicenow.yaml @@ -0,0 +1,70 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: servicenow + namespace: rhdh + title: ServiceNow Integration for Red Hat Developer Hub + description: | + The ServiceNow plugin integrates ServiceNow incidents directly into Red Hat Developer Hub. + It displays incidents associated with the currently logged in user, such as those where + they are the caller, assignee, or reporter, as well as incidents linked to the current + catalog entity. This enables faster visibility into relevant issues and improves + operational awareness. + + annotations: + extensions.backstage.io/pre-installed: 'true' # Indicates that this plugin YAML is pre-installed, not the plugin itself + tags: + - itsm + - incident-management + links: + - title: Homepage + url: https://red.ht/rhdh + - title: Bugs + url: https://issues.redhat.com/browse/RHDHBUGS + - title: Documentation + url: https://github.com/backstage/community-plugins/tree/main/workspaces/servicenow + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/servicenow + +spec: + support: + provider: Backstage Community + level: community + lifecycle: active + author: Red Hat + publisher: Red Hat + + categories: + - Integration + + highlights: + - View ServiceNow incidents for the logged-in user or associated with the current catalog entity + - Filter by incident state and priority + - Search incidents by request ID or description + - Sort incidents by request ID, description, created date, priority, or state + - Customize queries with advanced parameters + + description: | + The ServiceNow plugin brings incident visibility from your ServiceNow instance into the + Red Hat Developer Hub. It allows users to view incidents associated with the logged in user, + whether they are the caller, assignee, or reporter, as well as incidents linked to the + current catalog entity. This enables seamless access to operational data and helps accelerate + issue resolution. + + + ## Adding The Plugin To Red Hat Developer Hub + + See the [Red Hat Developer Hub documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) + for further instructions on how to add, enable, configure, and remove plugins in your instance. + + ## Configuration + + The plugin requires your ServiceNow instance URL and authentication details (such as Basic Auth or OAuth). + You can optionally filter incidents by user fields like `caller_id`, `assigned_to`, or `opened_by`. + + For detailed setup of both frontend and backend components, refer to the [ServiceNow plugin documentation](https://github.com/backstage/community-plugins/tree/main/workspaces/servicenow). + + packages: + - backstage-community-plugin-servicenow-backend + - backstage-community-plugin-servicenow diff --git a/catalog-entities/marketplace/plugins/signals-backend.yaml b/catalog-entities/marketplace/plugins/signals-backend.yaml index f8beb00230..1a8e60bcbc 100644 --- a/catalog-entities/marketplace/plugins/signals-backend.yaml +++ b/catalog-entities/marketplace/plugins/signals-backend.yaml @@ -25,7 +25,9 @@ metadata: spec: author: Backstage Community - support: production # This plugin has GA status + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/signals.yaml b/catalog-entities/marketplace/plugins/signals.yaml index b66947818e..849bdf1e9e 100644 --- a/catalog-entities/marketplace/plugins/signals.yaml +++ b/catalog-entities/marketplace/plugins/signals.yaml @@ -24,7 +24,9 @@ metadata: spec: author: Backstage Community - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/sonarqube-catalog-cards.yaml b/catalog-entities/marketplace/plugins/sonarqube-catalog-cards.yaml index 3456c08f03..6df00a67f9 100644 --- a/catalog-entities/marketplace/plugins/sonarqube-catalog-cards.yaml +++ b/catalog-entities/marketplace/plugins/sonarqube-catalog-cards.yaml @@ -26,7 +26,9 @@ metadata: spec: author: SDA SE - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/sonarqube-scaffolder-actions.yaml b/catalog-entities/marketplace/plugins/sonarqube-scaffolder-actions.yaml index 71aeca8866..6614fd8c79 100644 --- a/catalog-entities/marketplace/plugins/sonarqube-scaffolder-actions.yaml +++ b/catalog-entities/marketplace/plugins/sonarqube-scaffolder-actions.yaml @@ -28,7 +28,9 @@ metadata: spec: author: Backstage Community - support: tech-preview # production, tech-preview, dev-preveiw + support: + provider: Red Hat + level: tech-preview lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/tech-radar.yaml b/catalog-entities/marketplace/plugins/tech-radar.yaml index 8febb58b93..1473cab626 100644 --- a/catalog-entities/marketplace/plugins/tech-radar.yaml +++ b/catalog-entities/marketplace/plugins/tech-radar.yaml @@ -33,7 +33,9 @@ spec: author: Backstage Community publisher: Red Hat license: Apache-2.0 - support: tech-preview + support: + provider: Red Hat + level: tech-preview lifecycle: active categories: diff --git a/catalog-entities/marketplace/plugins/techdocs.yaml b/catalog-entities/marketplace/plugins/techdocs.yaml index 10efe42fcf..72d23210f9 100644 --- a/catalog-entities/marketplace/plugins/techdocs.yaml +++ b/catalog-entities/marketplace/plugins/techdocs.yaml @@ -30,7 +30,9 @@ spec: publisher: Red Hat license: Apache-2.0 lifecycle: active - support: production + support: + provider: Red Hat + level: generally-available categories: - Backstage Core diff --git a/catalog-entities/marketplace/plugins/tekton.yaml b/catalog-entities/marketplace/plugins/tekton.yaml index 744cb65bd3..c843461261 100644 --- a/catalog-entities/marketplace/plugins/tekton.yaml +++ b/catalog-entities/marketplace/plugins/tekton.yaml @@ -27,7 +27,9 @@ metadata: spec: author: Red Hat - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active publisher: Red Hat diff --git a/catalog-entities/marketplace/plugins/todo.yaml b/catalog-entities/marketplace/plugins/todo.yaml new file mode 100644 index 0000000000..b7e0febdfe --- /dev/null +++ b/catalog-entities/marketplace/plugins/todo.yaml @@ -0,0 +1,86 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/refs/heads/main/workspaces/marketplace/json-schema/plugins.json +apiVersion: extensions.backstage.io/v1alpha1 +kind: Plugin +metadata: + name: todo + namespace: rhdh + title: TODO Plugin + annotations: + extensions.backstage.io/pre-installed: 'true' # Plugin is automatically listed in the catalog. + links: + - title: Plugin Overview (README) + url: https://github.com/backstage/community-plugins/blob/main/workspaces/todo/README.md + - title: Frontend Plugin Documentation + url: https://github.com/backstage/community-plugins/blob/main/workspaces/todo/plugins/todo/README.md + - title: Backend Plugin Documentation + url: https://github.com/backstage/community-plugins/blob/main/workspaces/todo/plugins/todo-backend/README.md + - title: Source Code + url: https://github.com/backstage/community-plugins/tree/main/workspaces/todo + tags: + - code-quality + - development + - productivity + - source-code + description: | + Browse and track TODO comments in your source code repositories +spec: + author: Backstage Community + support: + provider: Backstage Community + level: community + lifecycle: active + publisher: Backstage Community + + categories: + - Code Quality + + description: | + The TODO Plugin helps development teams track and manage TODO comments across their source code repositories. + It automatically scans source code and displays TODO and FIXME comments in a centralized view within Backstage. + + ## Features + + - **Multi-language Support**: Scans TODO comments in multiple programming languages via the Leasot parser + - **Entity Integration**: Displays TODO items directly on entity pages for easy access + - **Customizable Tags**: Supports TODO and FIXME tags by default, with the ability to add custom tags (NOTE, XXX, HACK) + - **Automatic Discovery**: Integrates with Backstage's software catalog to automatically scan repositories with `backstage.io/source-location` annotations + - **Author References**: Recognizes and displays author information from TODO comments + + ## Use Cases + + - Track technical debt across your codebase + - Monitor outstanding development tasks during code reviews + - Identify areas requiring follow-up work + - Maintain visibility of temporary workarounds and fixes + + ## How It Works + + The backend plugin determines which source code to scan by reading entity annotations from the catalog: + - First checks the `backstage.io/source-location` annotation on the entity + - Falls back to the `backstage.io/managed-by-location` annotation if source-location is not set + - Only `url` locations are supported (locally configured `file` locations won't work) + - Dot-files and dot-folders are automatically ignored during scanning + + ## Components + + This plugin consists of two packages: + - **Frontend Plugin** (`@backstage-community/plugin-todo`): Provides UI components to display TODO items + - **Backend Plugin** (`@backstage-community/plugin-todo-backend`): Scans repositories and extracts TODO comments + + Both plugins must be installed together for full functionality. + + mountPoints: + - entityTab + - entityCard + + dependencies: + - backstage-community-plugin-todo-backend + + assets: + - type: icon + filename: todo-logo.png + originUri: https://backstage.io/img/todo-logo.png + + packages: + - backstage-community-plugin-todo + - backstage-community-plugin-todo-backend diff --git a/catalog-entities/marketplace/plugins/topology.yaml b/catalog-entities/marketplace/plugins/topology.yaml index be927dd4ca..1f2d2b9c75 100644 --- a/catalog-entities/marketplace/plugins/topology.yaml +++ b/catalog-entities/marketplace/plugins/topology.yaml @@ -25,7 +25,9 @@ metadata: url: https://github.com/backstage/community-plugins/tree/main/workspaces/topology/plugins/topology spec: - support: production + support: + provider: Red Hat + level: generally-available lifecycle: active author: Red Hat publisher: Red Hat @@ -58,4 +60,5 @@ spec: packages: - backstage-community-plugin-topology + - backstage-plugin-kubernetes - backstage-plugin-kubernetes-backend diff --git a/docker/Dockerfile b/docker/Dockerfile index 9a22d6f1be..2768800f21 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -15,7 +15,7 @@ # Stage 1 - Build nodejs skeleton # https://registry.access.redhat.com/ubi9/nodejs-22 -FROM registry.access.redhat.com/ubi9/nodejs-22:9.6-1751968740 AS skeleton +FROM registry.access.redhat.com/ubi9/nodejs-22:9.6-1760386551 AS skeleton # hadolint ignore=DL3002 USER 0 @@ -45,7 +45,7 @@ RUN dnf install -q -y --allowerasing --nobest \ python3-subscription-manager-rhsm python3-systemd python3-urllib3 readline redhat-release rootfiles rpm rpm-build-libs rpm-libs rpm-plugin-selinux rpm-sign-libs rsync scl-utils \ sed selinux-policy selinux-policy-targeted setup shadow-utils skopeo slirp4netns sqlite-libs subscription-manager subscription-manager-rhsm-certificates systemd systemd-libs \ systemd-pam systemd-rpm-macros tar tcl tpm2-tss tzdata unzip usermode util-linux util-linux-core vim-filesystem vim-minimal virt-what which xz xz-libs yajl yum zlib zlib-devel && \ - + \ # '(micro)dnf update -y' not allowed in Konflux+Cachi2: instead use renovate or https://github.com/konflux-ci/rpm-lockfile-prototype to update the rpms.lock.yaml file dnf clean all @@ -68,11 +68,12 @@ COPY $EXTERNAL_SOURCE_NESTED/yarn.lock ./ # BEGIN COPY package.json files COPY $EXTERNAL_SOURCE_NESTED/plugins/scalprum-backend/package.json ./plugins/scalprum-backend/package.json COPY $EXTERNAL_SOURCE_NESTED/plugins/licensed-users-info-backend/package.json ./plugins/licensed-users-info-backend/package.json -COPY $EXTERNAL_SOURCE_NESTED/plugins/dynamic-plugins-info/package.json ./plugins/dynamic-plugins-info/package.json COPY $EXTERNAL_SOURCE_NESTED/plugins/dynamic-plugins-info-backend/package.json ./plugins/dynamic-plugins-info-backend/package.json +COPY $EXTERNAL_SOURCE_NESTED/packages/theme-wrapper/package.json ./packages/theme-wrapper/package.json COPY $EXTERNAL_SOURCE_NESTED/packages/plugin-utils/package.json ./packages/plugin-utils/package.json COPY $EXTERNAL_SOURCE_NESTED/packages/backend/package.json ./packages/backend/package.json COPY $EXTERNAL_SOURCE_NESTED/packages/app/package.json ./packages/app/package.json +COPY $EXTERNAL_SOURCE_NESTED/packages/app-next/package.json ./packages/app-next/package.json COPY $EXTERNAL_SOURCE_NESTED/package.json ./package.json # END COPY package.json files @@ -92,7 +93,7 @@ RUN NODE_HEADERS_VERSION=$(node --version); echo "=== Install node headers $NODE # Increase timeout for yarn install RUN "$YARN" config set httpTimeout 600000 -RUN echo "=== YARN INSTALL ==="; FAILED=0; "$YARN" install --immutable; \ +RUN echo "=== YARN INSTALL ==="; FAILED=0; "$YARN" install --immutable || FAILED=1; \ for d in /tmp/xfs-*; do if [[ -f ${d}/build.log ]]; then \ (( FAILED = FAILED + 1 )); \ echo; echo $d; \ @@ -123,7 +124,7 @@ RUN \ # suppress git warnings about dubious ownership in repository at '/opt/app-root/src' when building RUN echo "=== YARN BUILD ==="; FAILED=0; \ git config --global --add safe.directory /opt/app-root/src; \ - "$YARN" build || true; \ + "$YARN" build || FAILED=1; \ for d in $(find . -name yarn-install.log); do \ (( FAILED = FAILED + 1 )); echo; echo $d; echo "======"; cat ${d}; \ done; \ @@ -131,7 +132,7 @@ RUN echo "=== YARN BUILD ==="; FAILED=0; \ WORKDIR $CONTAINER_SOURCE/dynamic-plugins -RUN echo "=== DYNAMIC PLUGIN YARN INSTALL ==="; FAILED=0; "$YARN" install --immutable; \ +RUN echo "=== DYNAMIC PLUGIN YARN INSTALL ==="; FAILED=0; "$YARN" install --immutable || FAILED=1; \ for d in /tmp/xfs-*; do if [[ -f ${d}/build.log ]]; then \ (( FAILED = FAILED + 1 )); \ echo; echo $d; \ @@ -141,7 +142,7 @@ RUN echo "=== DYNAMIC PLUGIN YARN INSTALL ==="; FAILED=0; "$YARN" install --immu if [[ $FAILED -gt 0 ]]; then exit $FAILED; fi RUN echo "=== EXPORT DYNAMIC PLUGINS ==="; FAILED=0; \ - "$YARN" export-dynamic || true; \ + "$YARN" export-dynamic || FAILED=1; \ for d in $(find . -name yarn-install.log); do \ (( FAILED = FAILED + 1 )); echo; echo $d; echo "======"; cat ${d}; \ done; \ @@ -201,7 +202,7 @@ RUN \ # Stage 5 - Build the runner image # https://registry.access.redhat.com/ubi9/nodejs-22-minimal -FROM registry.access.redhat.com/ubi9/nodejs-22-minimal:9.6-1751380832 AS runner +FROM registry.access.redhat.com/ubi9/nodejs-22-minimal:9.6-1760544659 AS runner USER 0 ENV EXTERNAL_SOURCE_NESTED=. @@ -242,13 +243,8 @@ COPY $EXTERNAL_SOURCE_NESTED/catalog-entities/marketplace /marketplace/catalog-e # Copy script to gather dynamic plugins; copy embedded dynamic plugins to root folder; fix permissions COPY docker/install-dynamic-plugins.py docker/install-dynamic-plugins.sh ./ -RUN chmod -R a+r ./install-dynamic-plugins.py; \ - chmod -R a+rx ./install-dynamic-plugins.sh +RUN chmod -R a+rx ./install-dynamic-plugins.* -# The existence of the index.html.tmpl tells Backstage to take that file and load it into memory, inject the needed appConfig (instead of writing -# it into a random *.chunk.js file, and then serve that file from memory so that we can set the readOnlyRootFilesystem: true option for -# the container. -RUN ln -s /opt/app-root/src/packages/app/dist/index.html /opt/app-root/src/packages/app/dist/index.html.tmpl # Fix for https://issues.redhat.com/browse/RHIDP-728 RUN mkdir -p /opt/app-root/src/.npm; chown -R 1001:1001 /opt/app-root/src/.npm diff --git a/docker/install-dynamic-plugins.py b/docker/install-dynamic-plugins.py index b97e7764a1..4efcf5778c 100755 --- a/docker/install-dynamic-plugins.py +++ b/docker/install-dynamic-plugins.py @@ -30,38 +30,59 @@ import time import signal -# This script is used to install dynamic plugins in the Backstage application, -# and is available in the container image to be called at container initialization, -# for example in an init container when using Kubernetes. -# -# It expects, as the only argument, the path to the root directory where -# the dynamic plugins will be installed. -# -# Additionally, the MAX_ENTRY_SIZE environment variable can be defined to set -# the maximum size of a file in the archive (default: 20MB). -# -# The SKIP_INTEGRITY_CHECK environment variable can be defined with ("true") to skip the integrity check of remote packages -# -# It expects the `dynamic-plugins.yaml` file to be present in the current directory and -# to contain the list of plugins to install along with their optional configuration. -# -# The `dynamic-plugins.yaml` file must contain: -# - a `plugins` list of objects with the following properties: -# - `package`: the NPM package to install (either a package name or a path to a local package) -# - `integrity`: a string containing the integrity hash of the package (optional if package is local, as integrity check is not checked for local packages) -# - `pluginConfig`: an optional plugin-specific configuration fragment -# - `disabled`: an optional boolean to disable the plugin (`false` by default) -# - an optional `includes` list of yaml files to include, each file containing a list of plugins. -# -# The plugins listed in the included files will be included in the main list of considered plugins -# and possibly overwritten by the plugins already listed in the main `plugins` list. -# -# For each enabled plugin mentioned in the main `plugins` list and the various included files, -# the script will: -# - call `npm pack` to get the package archive and extract it in the dynamic plugins root directory -# - if the package comes from a remote registry, verify the integrity of the package with the given integrity hash -# - merge the plugin-specific configuration fragment in a global configuration file named `app-config.dynamic-plugins.yaml` -# +""" +Dynamic Plugin Installer for Backstage Application + +This script is used to install dynamic plugins in the Backstage application, and is available in the container image to be called at container initialization, for example in an init container when using Kubernetes. + +It expects, as the only argument, the path to the root directory where the dynamic plugins will be installed. + +Environment Variables: + MAX_ENTRY_SIZE: Maximum size of a file in the archive (default: 20MB) + SKIP_INTEGRITY_CHECK: Set to "true" to skip integrity check of remote packages + +Configuration: + The script expects the `dynamic-plugins.yaml` file to be present in the current directory and to contain the list of plugins to install along with their optional configuration. + + The `dynamic-plugins.yaml` file must contain: + - a `plugins` list of objects with the following properties: + - `package`: the package to install (NPM package name, local path starting with './', or OCI image starting with 'oci://') + - `integrity`: a string containing the integrity hash of the package (required for remote NPM packages unless SKIP_INTEGRITY_CHECK is set, optional for local packages, not used for OCI packages) + - `pluginConfig`: an optional plugin-specific configuration fragment + - `disabled`: an optional boolean to disable the plugin (`false` by default) + - `pullPolicy`: download behavior control - 'IfNotPresent' (default) or 'Always' (OCI packages with ':latest!' default to 'Always') + - `forceDownload`: an optional boolean to force download for NPM packages even if already installed (`false` by default) + - an optional `includes` list of yaml files to include, each file containing a list of plugins + + The plugins listed in the included files will be included in the main list of considered plugins and possibly overwritten by the plugins already listed in the main `plugins` list. + + A simple empty example `dynamic-plugins.yaml` file: + + ```yaml + includes: + - dynamic-plugins.default.yaml + plugins: [] + ``` + +Package Types: + 1. NPM packages: Standard package names (e.g., '@backstage/plugin-catalog') + 2. Local packages: Paths starting with './' (e.g., './my-local-plugin') - automatically detects changes via package.json version, modification times, and lock files + 3. OCI packages: Images starting with 'oci://' (e.g., 'oci://quay.io/user/plugin:v1.0!plugin-name') + +Pull Policies: + - IfNotPresent: Only download if not already installed (default for most packages) + - Always: Always check for updates and download if different (default for OCI packages with ':latest!' tag) + +Process: + For each enabled plugin mentioned in the main `plugins` list and the various included files, the script will: + - For NPM packages: call `npm pack` to get the package archive and extract it + - For OCI packages: use `skopeo` to download and extract the specified plugin from the container image + - For local packages: pack and extract from the local filesystem + - Verify package integrity (for remote NPM packages only, unless skipped) + - Track installation state using hash files to detect changes and avoid unnecessary re-downloads + - Merge the plugin-specific configuration fragment in a global configuration file named `app-config.dynamic-plugins.yaml` + +""" class PullPolicy(StrEnum): IF_NOT_PRESENT = 'IfNotPresent' @@ -72,35 +93,34 @@ class InstallException(Exception): """Exception class from which every exception in this library will derive.""" pass -RECOGNIZED_ALGORITHMS = ( - 'sha512', - 'sha384', - 'sha256', -) - -def merge(source, destination, prefix = ''): - for key, value in source.items(): - if isinstance(value, dict): - # get node or create one - node = destination.setdefault(key, {}) - merge(value, node, key + '.') - else: - # if key exists in destination trigger an error - if key in destination and destination[key] != value: - raise InstallException(f"Config key '{ prefix + key }' defined differently for 2 dynamic plugins") - - destination[key] = value - - return destination - -def maybeMergeConfig(config, globalConfig): - if config is not None and isinstance(config, dict): - print('\t==> Merging plugin-specific configuration', flush=True) - return merge(config, globalConfig) - else: - return globalConfig +class PluginInstaller: + """Base class for plugin installers with common functionality.""" + + def __init__(self, destination: str, skip_integrity_check: bool = False): + self.destination = destination + self.skip_integrity_check = skip_integrity_check + + def should_skip_installation(self, plugin: dict, plugin_path_by_hash: dict) -> tuple[bool, str]: + """Check if plugin installation should be skipped based on pull policy and current state.""" + plugin_hash = plugin['hash'] + pull_policy = plugin.get('pullPolicy', PullPolicy.IF_NOT_PRESENT) + force_download = plugin.get('forceDownload', False) + + if plugin_hash not in plugin_path_by_hash: + return False, "not_installed" + + if pull_policy == PullPolicy.ALWAYS or force_download: + return False, "force_download" + + return True, "already_installed" + + def install(self, plugin: dict, plugin_path_by_hash: dict) -> str: + """Install a plugin and return the plugin path. Must be implemented by subclasses.""" + raise NotImplementedError() class OciDownloader: + """Helper class for downloading and extracting plugins from OCI container images.""" + def __init__(self, destination: str): self._skopeo = shutil.which('skopeo') if self._skopeo is None: @@ -110,6 +130,7 @@ def __init__(self, destination: str): self.tmp_dir = self.tmp_dir_obj.name self.image_to_tarball = {} self.destination = destination + self.max_entry_size = int(os.environ.get('MAX_ENTRY_SIZE', 20000000)) def skopeo(self, command): rv = subprocess.run([self._skopeo] + command, check=True, capture_output=True) @@ -144,7 +165,7 @@ def extract_plugin(self, tar_file: str, plugin_path: str) -> None: if not member.name.startswith(plugin_path): continue # zip bomb protection - if member.size > int(os.environ.get('MAX_ENTRY_SIZE', 20000000)): + if member.size > self.max_entry_size: raise InstallException('Zip bomb detected in ' + member.name) if member.islnk() or member.issym(): @@ -156,7 +177,6 @@ def extract_plugin(self, tar_file: str, plugin_path: str) -> None: filesToExtract.append(member) tar.extractall(os.path.abspath(self.destination), members=filesToExtract, filter='tar') - def download(self, package: str) -> str: # split by ! to get the path in the image (image, plugin_path) = package.split('!') @@ -169,7 +189,7 @@ def download(self, package: str) -> str: return plugin_path def digest(self, package: str) -> str: - (image, plugin_path) = package.split('!') + (image, _) = package.split('!') image_url = image.replace('oci://', 'docker://') output = self.skopeo(['inspect', image_url]) data = json.loads(output) @@ -177,6 +197,280 @@ def digest(self, package: str) -> str: digest = data['Digest'].split(':')[1] return f"{digest}" +class OciPluginInstaller(PluginInstaller): + """Handles OCI container-based plugin installation using skopeo.""" + + def __init__(self, destination: str, skip_integrity_check: bool = False): + super().__init__(destination, skip_integrity_check) + self.downloader = OciDownloader(destination) + + def should_skip_installation(self, plugin: dict, plugin_path_by_hash: dict) -> tuple[bool, str]: + """OCI packages have special digest-based checking for ALWAYS pull policy.""" + package = plugin['package'] + plugin_hash = plugin['hash'] + pull_policy = plugin.get('pullPolicy', PullPolicy.ALWAYS if ':latest!' in package else PullPolicy.IF_NOT_PRESENT) + + if plugin_hash not in plugin_path_by_hash: + return False, "not_installed" + + if pull_policy == PullPolicy.IF_NOT_PRESENT: + return True, "already_installed" + + if pull_policy == PullPolicy.ALWAYS: + # Check if digest has changed + installed_path = plugin_path_by_hash[plugin_hash] + digest_file_path = os.path.join(self.destination, installed_path, 'dynamic-plugin-image.hash') + + local_digest = None + if os.path.isfile(digest_file_path): + with open(digest_file_path, 'r') as f: + local_digest = f.read().strip() + + remote_digest = self.downloader.digest(package) + if remote_digest == local_digest: + return True, "digest_unchanged" + + return False, "force_download" + + def install(self, plugin: dict, plugin_path_by_hash: dict) -> str: + """Install an OCI plugin package.""" + package = plugin['package'] + + try: + plugin_path = self.downloader.download(package) + + # Save digest for future comparison + digest_file_path = os.path.join(self.destination, plugin_path, 'dynamic-plugin-image.hash') + with open(digest_file_path, 'w') as f: + f.write(self.downloader.digest(package)) + + # Clean up duplicate hashes + for key in [k for k, v in plugin_path_by_hash.items() if v == plugin_path]: + plugin_path_by_hash.pop(key) + + return plugin_path + + except Exception as e: + raise InstallException(f"Error while installing OCI plugin {package}: {e}") + +class NpmPluginInstaller(PluginInstaller): + """Handles NPM and local package installation using npm pack.""" + + def __init__(self, destination: str, skip_integrity_check: bool = False): + super().__init__(destination, skip_integrity_check) + self.max_entry_size = int(os.environ.get('MAX_ENTRY_SIZE', 20000000)) + + def install(self, plugin: dict, plugin_path_by_hash: dict) -> str: + """Install an NPM or local plugin package.""" + package = plugin['package'] + package_is_local = package.startswith('./') + + if package_is_local: + package = os.path.join(os.getcwd(), package[2:]) + + # Verify integrity requirements + if not package_is_local and not self.skip_integrity_check and 'integrity' not in plugin: + raise InstallException(f"No integrity hash provided for Package {package}") + + # Download package + print('\t==> Grabbing package archive through `npm pack`', flush=True) + result = subprocess.run(['npm', 'pack', package], capture_output=True, cwd=self.destination) + if result.returncode != 0: + raise InstallException(f'Error while installing plugin {package} with \'npm pack\' : {result.stderr.decode("utf-8")}') + + archive = os.path.join(self.destination, result.stdout.decode('utf-8').strip()) + + # Verify integrity for remote packages + if not (package_is_local or self.skip_integrity_check): + print('\t==> Verifying package integrity', flush=True) + verify_package_integrity(plugin, archive, self.destination) + + # Extract package + plugin_path = self._extract_npm_package(archive) + + return plugin_path + + def _extract_npm_package(self, archive: str) -> str: + """Extract NPM package archive with security protections.""" + directory = archive.replace('.tgz', '') + directory_realpath = os.path.realpath(directory) + plugin_path = os.path.basename(directory_realpath) + + if os.path.exists(directory): + print('\t==> Removing previous plugin directory', directory, flush=True) + shutil.rmtree(directory, ignore_errors=True) + os.mkdir(directory) + + print('\t==> Extracting package archive', archive, flush=True) + with tarfile.open(archive, 'r:gz') as tar: + for member in tar.getmembers(): + if member.isreg(): + if not member.name.startswith('package/'): + raise InstallException(f"NPM package archive does not start with 'package/' as it should: {member.name}") + + if member.size > self.max_entry_size: + raise InstallException(f'Zip bomb detected in {member.name}') + + member.name = member.name.removeprefix('package/') + tar.extract(member, path=directory, filter='tar') + + elif member.isdir(): + print('\t\tSkipping directory entry', member.name, flush=True) + + elif member.islnk() or member.issym(): + if not member.linkpath.startswith('package/'): + raise InstallException(f'NPM package archive contains a link outside of the archive: {member.name} -> {member.linkpath}') + + member.name = member.name.removeprefix('package/') + member.linkpath = member.linkpath.removeprefix('package/') + + realpath = os.path.realpath(os.path.join(directory, *os.path.split(member.linkname))) + if not realpath.startswith(directory_realpath): + raise InstallException(f'NPM package archive contains a link outside of the archive: {member.name} -> {member.linkpath}') + + tar.extract(member, path=directory, filter='tar') + + else: + type_mapping = { + tarfile.CHRTYPE: "character device", + tarfile.BLKTYPE: "block device", + tarfile.FIFOTYPE: "FIFO" + } + type_str = type_mapping.get(member.type, "unknown") + raise InstallException(f'NPM package archive contains a non regular file: {member.name} - {type_str}') + + print('\t==> Removing package archive', archive, flush=True) + os.remove(archive) + + return plugin_path + +def create_plugin_installer(package: str, destination: str, skip_integrity_check: bool = False) -> PluginInstaller: + """Factory function to create appropriate plugin installer based on package type.""" + if package.startswith('oci://'): + return OciPluginInstaller(destination, skip_integrity_check) + else: + return NpmPluginInstaller(destination, skip_integrity_check) + +def install_plugin(plugin: dict, plugin_path_by_hash: dict, destination: str, skip_integrity_check: bool = False) -> tuple[str, dict]: + """Install a single plugin and handle configuration merging.""" + package = plugin['package'] + + # Check if plugin is disabled + if plugin.get('disabled', False): + print(f'\n======= Skipping disabled dynamic plugin {package}', flush=True) + return None, {} + + # Create appropriate installer + installer = create_plugin_installer(package, destination, skip_integrity_check) + + # Check if installation should be skipped + should_skip, reason = installer.should_skip_installation(plugin, plugin_path_by_hash) + if should_skip: + print(f'\n======= Skipping download of already installed dynamic plugin {package} ({reason})', flush=True) + # Remove from tracking dict so we don't delete it later + if plugin['hash'] in plugin_path_by_hash: + plugin_path_by_hash.pop(plugin['hash']) + return None, plugin.get('pluginConfig', {}) + + # Install the plugin + print(f'\n======= Installing dynamic plugin {package}', flush=True) + plugin_path = installer.install(plugin, plugin_path_by_hash) + + # Create hash file for tracking + hash_file_path = os.path.join(destination, plugin_path, 'dynamic-plugin-config.hash') + with open(hash_file_path, 'w') as f: + f.write(plugin['hash']) + + print(f'\t==> Successfully installed dynamic plugin {package}', flush=True) + + return plugin_path, plugin.get('pluginConfig', {}) + +RECOGNIZED_ALGORITHMS = ( + 'sha512', + 'sha384', + 'sha256', +) + +def merge(source, destination, prefix = ''): + for key, value in source.items(): + if isinstance(value, dict): + # get node or create one + node = destination.setdefault(key, {}) + merge(value, node, key + '.') + else: + # if key exists in destination trigger an error + if key in destination and destination[key] != value: + raise InstallException(f"Config key '{ prefix + key }' defined differently for 2 dynamic plugins") + + destination[key] = value + + return destination + +def get_local_package_info(package_path: str) -> dict: + """Get package information from a local package to include in hash calculation.""" + try: + if package_path.startswith('./'): + abs_package_path = os.path.join(os.getcwd(), package_path[2:]) + else: + abs_package_path = package_path + + package_json_path = os.path.join(abs_package_path, 'package.json') + + if not os.path.isfile(package_json_path): + # If no package.json, fall back to directory modification time + if os.path.isdir(abs_package_path): + mtime = os.path.getmtime(abs_package_path) + return {'_directory_mtime': mtime} + else: + return {'_not_found': True} + + with open(package_json_path, 'r') as f: + package_json = json.load(f) + + # Extract relevant fields that indicate package changes + info = {} + info['_package_json'] = package_json + + # Also include package.json modification time as additional change detection + info['_package_json_mtime'] = os.path.getmtime(package_json_path) + + # Include package-lock.json or yarn.lock modification time if present + for lock_file in ['package-lock.json', 'yarn.lock']: + lock_path = os.path.join(abs_package_path, lock_file) + if os.path.isfile(lock_path): + info[f'_{lock_file}_mtime'] = os.path.getmtime(lock_path) + + return info + + except (json.JSONDecodeError, OSError, IOError) as e: + # If we can't read the package info, include the error in hash + # This ensures we'll try to reinstall if there are permission issues, etc. + return {'_error': str(e)} + +def maybeMergeConfig(config, globalConfig): + if config is not None and isinstance(config, dict): + print('\t==> Merging plugin-specific configuration', flush=True) + return merge(config, globalConfig) + else: + return globalConfig + +def mergePlugin(plugin: dict, allPlugins: dict, dynamicPluginsFile: str): + package = plugin['package'] + if not isinstance(package, str): + raise InstallException(f"content of the \'plugins.package\' field must be a string in {dynamicPluginsFile}") + + # if `package` already exists in `allPlugins`, then override its fields + if package not in allPlugins: + allPlugins[package] = plugin + return + + # override the included plugins with fields in the main plugins list + print('\n======= Overriding dynamic plugin configuration', package, flush=True) + for key in plugin: + if key == 'package': + continue + allPlugins[package][key] = plugin[key] + def verify_package_integrity(plugin: dict, archive: str, working_directory: str) -> None: package = plugin['package'] if 'integrity' not in plugin: @@ -241,7 +535,6 @@ def main(): signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit(0)) create_lock(lock_file_path) - maxEntrySize = int(os.environ.get('MAX_ENTRY_SIZE', 20000000)) skipIntegrityCheck = os.environ.get("SKIP_INTEGRITY_CHECK", "").lower() == "true" dynamicPluginsFile = 'dynamic-plugins.yaml' @@ -294,7 +587,8 @@ def main(): print('\n======= Including dynamic plugins from', include, flush=True) if not os.path.isfile(include): - raise InstallException(f"File {include} does not exist") + print(f"WARNING: File {include} does not exist, skipping including dynamic packages from {include}", flush=True) + continue with open(include, 'r') as file: includeContent = yaml.safe_load(file) @@ -307,7 +601,7 @@ def main(): raise InstallException(f"content of the \'plugins\' field must be a list in {include}") for plugin in includePlugins: - allPlugins[plugin['package']] = plugin + mergePlugin(plugin, allPlugins, dynamicPluginsFile) if 'plugins' in content: plugins = content['plugins'] @@ -318,27 +612,19 @@ def main(): raise InstallException(f"content of the \'plugins\' field must be a list in {dynamicPluginsFile}") for plugin in plugins: - package = plugin['package'] - if not isinstance(package, str): - raise InstallException(f"content of the \'plugins.package\' field must be a string in {dynamicPluginsFile}") - - # if `package` already exists in `allPlugins`, then override its fields - if package not in allPlugins: - allPlugins[package] = plugin - continue - - # override the included plugins with fields in the main plugins list - print('\n======= Overriding dynamic plugin configuration', package, flush=True) - for key in plugin: - if key == 'package': - continue - allPlugins[package][key] = plugin[key] + mergePlugin(plugin, allPlugins, dynamicPluginsFile) # add a hash for each plugin configuration to detect changes for plugin in allPlugins.values(): hash_dict = copy.deepcopy(plugin) # remove elements that shouldn't be tracked for installation detection hash_dict.pop('pluginConfig', None) + + package = plugin['package'] + if package.startswith('./'): + local_info = get_local_package_info(package) + hash_dict['_local_package_info'] = local_info + hash = hashlib.sha256(json.dumps(hash_dict, sort_keys=True).encode('utf-8')).hexdigest() plugin['hash'] = hash @@ -353,164 +639,13 @@ def main(): hash_value = hash_file.read().strip() plugin_path_by_hash[hash_value] = dir_name - oci_downloader = OciDownloader(dynamicPluginsRoot) - # iterate through the list of plugins for plugin in allPlugins.values(): - package = plugin['package'] - - if 'disabled' in plugin and plugin['disabled'] is True: - print('\n======= Skipping disabled dynamic plugin', package, flush=True) - continue - - # Stores the relative path of the plugin directory once downloaded - plugin_path = '' - if package.startswith('oci://'): - # The OCI downloader - try: - pull_policy = plugin.get('pullPolicy', PullPolicy.ALWAYS if ':latest!' in package else PullPolicy.IF_NOT_PRESENT) - - if plugin['hash'] in plugin_path_by_hash and pull_policy == PullPolicy.IF_NOT_PRESENT: - print('\n======= Skipping download of already installed dynamic plugin', package, flush=True) - plugin_path_by_hash.pop(plugin['hash']) - globalConfig = maybeMergeConfig(plugin.get('pluginConfig'), globalConfig) - continue - - if plugin['hash'] in plugin_path_by_hash and pull_policy == PullPolicy.ALWAYS: - digest_file_path = os.path.join(dynamicPluginsRoot, plugin_path_by_hash.pop(plugin['hash']), 'dynamic-plugin-image.hash') - local_image_digest = None - if os.path.isfile(digest_file_path): - with open(digest_file_path, 'r') as digest_file: - digest_value = digest_file.read().strip() - local_image_digest = digest_value - remote_image_digest = oci_downloader.digest(package) - if remote_image_digest == local_image_digest: - print('\n======= Skipping download of already installed dynamic plugin', package, flush=True) - globalConfig = maybeMergeConfig(plugin.get('pluginConfig'), globalConfig) - continue - else: - print('\n======= Installing dynamic plugin', package, flush=True) - - else: - print('\n======= Installing dynamic plugin', package, flush=True) - - plugin_path = oci_downloader.download(package) - digest_file_path = os.path.join(dynamicPluginsRoot, plugin_path, 'dynamic-plugin-image.hash') - with open(digest_file_path, 'w') as digest_file: - digest_file.write(oci_downloader.digest(package)) - # remove any duplicate hashes which can occur when only the version is updated - for key in [k for k, v in plugin_path_by_hash.items() if v == plugin_path]: - plugin_path_by_hash.pop(key) - except Exception as e: - raise InstallException(f"Error while adding OCI plugin {package} to downloader: {e}") - else: - # The NPM downloader - plugin_already_installed = False - pull_policy = plugin.get('pullPolicy', PullPolicy.IF_NOT_PRESENT) - - if plugin['hash'] in plugin_path_by_hash: - force_download = plugin.get('forceDownload', False) - if pull_policy == PullPolicy.ALWAYS or force_download: - print('\n======= Forcing download of already installed dynamic plugin', package, flush=True) - else: - print('\n======= Skipping download of already installed dynamic plugin', package, flush=True) - plugin_already_installed = True - # remove the hash from plugin_path_by_hash so that we can detect plugins that have been removed - plugin_path_by_hash.pop(plugin['hash']) - else: - print('\n======= Installing dynamic plugin', package, flush=True) - - if plugin_already_installed: - globalConfig = maybeMergeConfig(plugin.get('pluginConfig'), globalConfig) - continue - - package_is_local = package.startswith('./') - - # If package is not local, then integrity check is mandatory - if not package_is_local and not skipIntegrityCheck and not 'integrity' in plugin: - raise InstallException(f"No integrity hash provided for Package {package}") - - if package_is_local: - package = os.path.join(os.getcwd(), package[2:]) - - print('\t==> Grabbing package archive through `npm pack`', flush=True) - completed = subprocess.run(['npm', 'pack', package], capture_output=True, cwd=dynamicPluginsRoot) - if completed.returncode != 0: - raise InstallException(f'Error while installing plugin { package } with \'npm pack\' : ' + completed.stderr.decode('utf-8')) - - archive = os.path.join(dynamicPluginsRoot, completed.stdout.decode('utf-8').strip()) - - if not (package_is_local or skipIntegrityCheck): - print('\t==> Verifying package integrity', flush=True) - verify_package_integrity(plugin, archive, dynamicPluginsRoot) - - directory = archive.replace('.tgz', '') - directoryRealpath = os.path.realpath(directory) - plugin_path = os.path.basename(directoryRealpath) - - if os.path.exists(directory): - print('\t==> Removing previous plugin directory', directory, flush=True) - shutil.rmtree(directory, ignore_errors=True, onerror=None) - os.mkdir(directory) - - print('\t==> Extracting package archive', archive, flush=True) - file = tarfile.open(archive, 'r:gz') # NOSONAR - # extract the archive content but take care of zip bombs - for member in file.getmembers(): - if member.isreg(): - if not member.name.startswith('package/'): - raise InstallException("NPM package archive archive does not start with 'package/' as it should: " + member.name) - - if member.size > maxEntrySize: - raise InstallException('Zip bomb detected in ' + member.name) - - member.name = member.name.removeprefix('package/') - file.extract(member, path=directory, filter='tar') - elif member.isdir(): - print('\t\tSkipping directory entry', member.name, flush=True) - elif member.islnk() or member.issym(): - if not member.linkpath.startswith('package/'): - raise InstallException('NPM package archive contains a link outside of the archive: ' + member.name + ' -> ' + member.linkpath) - - member.name = member.name.removeprefix('package/') - member.linkpath = member.linkpath.removeprefix('package/') - - realpath = os.path.realpath(os.path.join(directory, *os.path.split(member.linkname))) - if not realpath.startswith(directoryRealpath): - raise InstallException('NPM package archive contains a link outside of the archive: ' + member.name + ' -> ' + member.linkpath) - - file.extract(member, path=directory, filter='tar') - else: - if member.type == tarfile.CHRTYPE: - type_str = "character device" - elif member.type == tarfile.BLKTYPE: - type_str = "block device" - elif member.type == tarfile.FIFOTYPE: - type_str = "FIFO" - else: - type_str = "unknown" - - raise InstallException('NPM package archive contains a non regular file: ' + member.name + ' - ' + type_str) - - file.close() - - print('\t==> Removing package archive', archive, flush=True) - os.remove(archive) - - # create a hash file in the plugin directory - hash = plugin['hash'] - hash_file_path = os.path.join(dynamicPluginsRoot, plugin_path, 'dynamic-plugin-config.hash') - with open(hash_file_path, 'w') as digest_file: - digest_file.write(hash) - - if 'pluginConfig' not in plugin: - print('\t==> Successfully installed dynamic plugin', package, flush=True) - continue - - # if some plugin configuration is defined, merge it with the global configuration - globalConfig = maybeMergeConfig(plugin.get('pluginConfig'), globalConfig) - - print('\t==> Successfully installed dynamic plugin', package, flush=True) + _, plugin_config = install_plugin(plugin, plugin_path_by_hash, dynamicPluginsRoot, skipIntegrityCheck) + + # Merge plugin configuration if provided + if plugin_config: + globalConfig = maybeMergeConfig(plugin_config, globalConfig) yaml.safe_dump(globalConfig, open(dynamicPluginsGlobalConfigFile, 'w')) diff --git a/docs/auth.md b/docs/auth.md index 453fc326d4..d3b4d38ba0 100644 --- a/docs/auth.md +++ b/docs/auth.md @@ -65,7 +65,7 @@ For more information on setting up the GitLab auth provider, consult the [Backst ### OAuth2 Proxy -The OAuth2 Proxy Authentication provider will require an OAuth2 Proxy server. You can consult the [official documentation](https://oauth2-proxy.github.io/oauth2-proxy/) for OAuth2 Proxy, as well as our available [blog post](https://janus-idp.io/blog/2023/01/17/enabling-keycloak-authentication-in-backstage) on the topic. +The OAuth2 Proxy Authentication provider will require an OAuth2 Proxy server. You can consult the [official documentation](https://oauth2-proxy.github.io/oauth2-proxy/) for OAuth2 Proxy, as well as our available [blog post](https://janus-idp.io/blog/2023/01/17/enabling-keycloak-authentication-in-backstage) on the topic. - Add the OAuth2 Proxy Authentication provider details as outlined below. diff --git a/docs/customization.md b/docs/customization.md index 33da2ce096..3fd2c74be3 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -194,5 +194,277 @@ buildInfo: TechDocs builder: 'local' Authentication provider: 'Github' RBAC: disabled - full: true # If set to true, only the information specified in this configuration will be displayed. If set to false, the provided details will be shown along with the build versions. By default it will only display the configured information. + overrideBuildInfo: true # If set to true, only the information specified in this configuration will be displayed. If set to false, the provided details will be shown along with the build versions. By default it will only display the configured information. +``` + +## Customizing the Language dropdown + +To customize the language dropdown in the User settings page, configure the list of locales your app should support in the `app-config.yaml` file. + +Example configuration: + +``` +i18n: + locales: # List of supported locales. Must include `en`, otherwise the translation framework will fail to load. + - en + - de + - it + defaultLocale: en # Optional. Used as fallback when browser language preferences don't match supported locales, or defaults to 'en' if not specified. + overrides: # List of JSON translation files applied in order (last file wins). Each file may override/add translations for one or more plugins/locales + - /.json + - /.json + +``` + +Example of JSON translation file, where the top-level key is the plugin translation reference ID (defined as translationRef in the [plugin source](https://github.com/backstage/community-plugins/blob/main/workspaces/npm/plugins/npm/src/translations/ref.ts#L23) +) + +``` +{ + "plugin.npm.translation-ref": { + "en": { + "infoCard.title": "NPM Packet JSON {{packageName}}" + }, + "de": { + "infoCard.title": "NPM Paket JSON {{packageName}}" + }, + "zh": { + "infoCard.title": "NPM 包 JSON {{packageName}}" + } + }, + "extensions": { + "en": { + "catalogPage.installationAlert": "Backend restart required JSON" + } + } +} +``` + +### Customizing Translations + +In a translation override JSON file, you can: + +1. **Modify Existing Translations**: Edit any English value in the JSON file to override the default translation +2. **Add Other Languages**: Add new language sections (e.g., `"de"`, `"fr"`, `"es"`) to support additional locales by translating the English keys +3. **Add Custom Keys**: Add new translation keys for custom components or plugins + +### Example Translation Override File + +You can add other languages as needed: + +```json +{ + "rhdh": { + "en": { + "app.userSettings.infoCard.title": "Custom RHDH Metadata", + "menuItem.home": "Dashboard" + }, + "de": { + "app.userSettings.infoCard.title": "Benutzerdefinierte RHDH-Metadaten", + "menuItem.home": "Dashboard" + }, + "fr": { + "app.userSettings.infoCard.title": "Métadonnées RHDH personnalisées", + "menuItem.home": "Tableau de bord" + } + } +} +``` + +### Applying Translation Overrides + +To apply your custom translations: + +#### For Local Development + +1. **Save the JSON file** in your project directory (e.g., `translations/custom-overrides.json`) +2. **Update app-config.yaml** to include your override file: + +```yaml +i18n: + locales: + - en + - de + - fr + defaultLocale: en + overrides: + - translations/custom-overrides.json +``` + +3. **Restart the application** for changes to take effect + +#### For OpenShift Environment + +1. **Create a ConfigMap** with your translation overrides: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: translation-overrides + namespace: your-namespace +data: + custom-overrides.json: | + { + "rhdh": { + "en": { + "app.userSettings.infoCard.title": "Custom RHDH Metadata" + }, + "de": { + "app.userSettings.infoCard.title": "Benutzerdefinierte RHDH-Metadaten" + } + } + } +``` + +2. **Mount the ConfigMap** in your Backstage CR to `/src/translations/`: + +```yaml +apiVersion: apps/v1 +kind: Backstage +metadata: + name: rhdh +spec: + application: + appConfig: + mountPath: /opt/app-root/src + extraFiles: + configMaps: + - mountPath: /opt/app-root/src/translations/ + name: translation-overrides + mountPath: /opt/app-root/src +``` + +3. **Update your app-config.yaml** to reference the mounted file: + +```yaml +i18n: + locales: + - en + - de + - fr + defaultLocale: en + overrides: + - /opt/app-root/src/translations/custom-overrides.json +``` + +4. **Apply the ConfigMap and deployment** for changes to take effect + +### Default Language Selection Priority + +Default language selection follows this priority order: + +1. **Browser Language Priority**: The system first checks the user's browser language preferences to provide a personalized experience. + +2. **Configuration Priority**: If no browser language matches the supported locales, the `defaultLocale` from the `i18n` configuration is used as a fallback. + +3. **Fallback Priority**: If neither browser preferences nor configuration provide a match, defaults to `en`. + +## Language Preferences + +Red Hat Developer Hub automatically saves and restores user language settings across browser sessions. This feature is enabled by default and uses database storage. + +### Configuration (Optional) + +Language preferences use database storage by default. To opt-out and use browser storage instead, add the following to your `app-config.yaml`: + +```yaml title="app-config.yaml" +userSettings: + persistence: browser # opt-out of database storage +``` + +### Persistence Options + +- **`database`** (default): Stores language preferences in the backend database. Persists across devices and browsers. No configuration required. +- **`browser`** (opt-out): Stores language preferences in browser local storage. Limited to single browser/device. + +## How It Works + +When users change the language in the UI: + +- The preference is automatically saved to storage +- On next login/refresh, the language setting is restored +- Guest users cannot persist language preferences + +## Usage + +1. Change language using any language selector in the UI +2. Language setting will automatically be saved and restored + +## Customizing QuickAccess card icons on the Homepage + +1. Add the JSON Data source + +The QuickAccess Cards on the Homepage supports loading data from a JSON file. This JSON file in your GitHub repository or any accessible endpoint can be hosted. + +2. Configure the Proxy in `app-config.yaml` + +To allow Homepage to fetch data from the hosted JSON file, add the following proxy configuration to your `app-config.yaml`: + +``` +proxy: + endpoints: + # customize your backstage instance + '/developer-hub': + target: https://raw.githubusercontent.com/ # i.e https://raw.githubusercontent.com/ + pathRewrite: + '^/api/proxy/developer-hub$': .json # i.e /redhat-developer/rhdh/main/packages/app/public/homepage/data.json + changeOrigin: true + secure: true +``` + +3. Supported Icon types + +| Icon Type | Example | Rendered As | +| ------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Backstage System Icon** | `"catalog"` | Uses Backstage system [icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx) | +| **SVG String** | `"..."` | Renders inline SVG | +| **Image URL** | `"https://example.com/icon.png"` | Renders external image. External images might be be restricted to Content Security Policy (CSP) which can be configured in the `app-config.yaml`. | +| **Relative Path** | `"/homepage/icons/icon.png"` | Loads the icon from the app’s public folder (if present) | + +**Note:** + +SVGs must be valid strings when stored inside JSON (use single quotes inside ). + +Example JSON file: + +``` + [ + { + "title": "Community", + "isExpanded": true, + "links": [ + { + "iconUrl": "https://img.icons8.com/ios/50/globe--v1.png", + "label": "Website", + "url": "https://developers.redhat.com/" + }, + { + "iconUrl": "https://img.icons8.com/ios/50/link--v1.png", + "label": "Blog", + "url": "https://developers.redhat.com/blog" + }, + { + "iconUrl": "github", + "label": "GitHub", + "url": "https://github.com/redhat-developer" + }, + { + "iconUrl": "https://img.icons8.com/color/48/slack.png", + "label": "Slack", + "url": "https://join.slack.com/xyz" + }, + { + "iconUrl": "https://img.icons8.com/color/48/youtube-squared.png", + "label": "Videos for developers", + "url": "https://developers.redhat.com/videos" + }, + { + "iconUrl": "", + "label": "Mailing List", + "url": "https://groups.google.com/g/xyz" + }, + ] + } + ] ``` diff --git a/docs/dynamic-plugins/debugging.md b/docs/dynamic-plugins/debugging.md index f1dbdfa60a..6c351ab51f 100644 --- a/docs/dynamic-plugins/debugging.md +++ b/docs/dynamic-plugins/debugging.md @@ -25,6 +25,7 @@ Debugger listening on ws://127.0.0.1:9229/9299bb26-3c32-4781-9488-7759b8781db5 ``` * The application will be accessible from `http://localhost:7007`. You may start the front end by running the following command from the root directory: `yarn start --filter=app`. It will be available in `http://localhost:3000` + * Attach your IDE debugger to the backend process. This step may depend on the IDE that you are using. For example, if you are using VS Code you may want to check [Node.js debugging in VS Code](https://code.visualstudio.com/docs/nodejs/nodejs-debugging) * Add Breakpoints to the files in folder `dynamic-plugins-root/${plugin-id}`. Optionally you can configure your IDE to add the source maps for the plugin so you can debug the TypeScript code directly and not the compiled JavaScript files diff --git a/docs/dynamic-plugins/export-derived-package.md b/docs/dynamic-plugins/export-derived-package.md index f821f7b345..d7364e83eb 100644 --- a/docs/dynamic-plugins/export-derived-package.md +++ b/docs/dynamic-plugins/export-derived-package.md @@ -5,11 +5,11 @@ Exporting a dynamic plugin package is a process of creating a new package that c This document describes how to export a dynamic plugin package from an existing Backstage plugin. -The exporting is done using the `package export-dynamic-plugin` command from the `@janus-idp/cli` package. +The exporting is done using the `plugin export` command from the `@red-hat-developer-hub/cli` package. The most convenient way to run the command is to use `npx`: ```bash -npx @janus-idp/cli@latest package export-dynamic-plugin +npx @red-hat-developer-hub/cli@latest plugin export ``` This command needs to be executed in the root folder of the JavaScript package (with `package.json`) of the plugin that you want to export as a dynamic plugin. @@ -21,23 +21,10 @@ This allows packing it with `npm pack`, or publishing it to npm registry. See [P > [!NOTE] > The derived dynamic plugin JavaScript packages should **not** be pushed to the public npm registry. They should only be published to a private npm registry. -This documentation uses `@latest` tag to ensure that the latest version of the `@janus-idp/cli` package is used. -But you need to make sure that you are using the version of the `@janus-idp/cli` package that is compatible with your RHDH version. +This documentation uses `@latest` tag to ensure that the latest version of the `@red-hat-developer-hub/cli` package is used. +But you need to make sure that you are using the version of the `@red-hat-developer-hub/cli` package that is compatible with your RHDH version. You can find the compatible versions in the [Version Matrix](./versions.md). -If you are developing your own plugin that is going to be used as a dynamic plugin, it might be useful to add the `export-dynamic-plugin` command to the `package.json` file as a script: - -```json -{ - "scripts": { - "export-dynamic": "janus-cli package package export-dynamic-plugin" - }, - "devDependencies": { - "@janus-idp/cli": "^1.18.0" - } -} -``` - ## Backend plugins To be compatible with the showcase dynamic plugin support, and used as dynamic plugins, existing plugins must be based on, or compatible with, the new backend system, as well as rebuilt with a dedicated CLI command. @@ -74,7 +61,7 @@ If a plugin depends on another package in the same monorepo workspace, and it do Example of exporting a dynamic plugin with shared and embedded packages: ```bash -npx @janus-idp/cli@latest export-dynamic-plugin --shared-package '!/@backstage/plugin-notifications/' --embed-package @backstage/plugin-notifications-backend +npx @red-hat-developer-hub/cli@latest plugin export --shared-package '!/@backstage/plugin-notifications/' --embed-package @backstage/plugin-notifications-backend ``` In this example, the `@backstage/plugin-notifications` package is marked as a private dependency (not shared) and it will be bundled in the dynamic plugin package, even though it is in the `@backstage` scope. @@ -82,7 +69,7 @@ The `@backstage/plugin-notifications-backend` package is marked as an embedded d ## Frontend plugins -Our CLI can generate the default configuration for Scalprum on the fly. For generated defaults see logs when running `npx @janus-idp/cli@latest export-dynamic`. We default to the following configuration: +Our CLI can generate the default configuration for Scalprum on the fly. For generated defaults see logs when running `npx @red-hat-developer-hub/cli@latest plugin export`. We default to the following configuration: ```json ... diff --git a/docs/dynamic-plugins/frontend-plugin-wiring.md b/docs/dynamic-plugins/frontend-plugin-wiring.md index 217e55d244..d35b080a39 100644 --- a/docs/dynamic-plugins/frontend-plugin-wiring.md +++ b/docs/dynamic-plugins/frontend-plugin-wiring.md @@ -27,6 +27,7 @@ plugins: routeBindings: ... appIcons: ... apiFactories: ... + translationResources: ... ``` ## Extend internal library of available icons @@ -503,6 +504,41 @@ Here are the default catalog entity routes in the default order: The visibility of a tab is derived from the kind of entity that is being displayed along with the visibility guidance mentioned in "[Using mount points](#using-mount-points)". +## Translation resources + +Users can add translation resources exported by plugin packages in the plugin's dynamic configuration + +```yaml +# dynamic-plugins-config.yaml +plugins: + - plugin: + disabled: false + pluginConfig: + dynamicPlugins: + frontend: + : # same as `scalprum.name` key in plugin's `package.json` + translationResources: + # Adding the exported translations + - importName: +``` + +Users can override default translations of a plugin with their own JSON-based translations + +```yaml +# dynamic-plugins-config.yaml +plugins: + - plugin: + disabled: false + pluginConfig: + dynamicPlugins: + frontend: + : # must match the `scalprum.name` key in plugin's `package.json` + translationResources: + # Adding the exported translations for this plugin + - importName: + ref: # Ref is required for `jsonTranslations` +``` + ## Provide additional Utility APIs Backstage offers a Utility API mechanism that provide ways for plugins to communicate during their entire life cycle. Utility APIs are registered as: diff --git a/docs/dynamic-plugins/index.md b/docs/dynamic-plugins/index.md index 33d1f0859e..9f8819ae3f 100644 --- a/docs/dynamic-plugins/index.md +++ b/docs/dynamic-plugins/index.md @@ -7,6 +7,7 @@ The dynamic plugin support is based on the [backend plugin manager package](http Dynamic plugin support is based on Dynamic plugin derived packages. This is a special JavaScript package that is derived from an original plugin package source code. You can find more information about process of creating derived packages in the [Export Derived Dynamic Plugin Package](export-derived-package.md) document. + The dynamic plugin derived packages shouldn't be pushed into the [public npm registry](https://www.npmjs.com), but it can be published to a private or internal npm registry. More details about publishing dynamic plugins is in the [Packaging Dynamic Plugins](packaging-dynamic-plugins.md) document. @@ -54,7 +55,7 @@ Example of this process on the [todo](https://github.com/backstage/community-plu ```console $ cd plugins/todo-backend - $ npx @janus-idp/cli@latest package export-dynamic-plugin + $ npx @red-hat-developer-hub/cli@latest plugin export Building main package executing yarn build ✔ Packing main package to dist-dynamic/package.json @@ -80,7 +81,7 @@ Example of this process on the [todo](https://github.com/backstage/community-plu ```console $ cd ../todo - $ npx @janus-idp/cli@latest package export-dynamic-plugin + $ npx @red-hat-developer-hub/cli@latest plugin export No scalprum config. Using default dynamic UI configuration: { "name": "backstage-community.plugin-todo", @@ -107,7 +108,7 @@ Example of this process on the [todo](https://github.com/backstage/community-plu ```console $ cd ../.. $ #we should be in workspaces/todo - $ npx @janus-idp/cli@latest package package-dynamic-plugins --tag quay.io/user/backstage-community-plugin-todo:v0.1.1 + $ npx @red-hat-developer-hub/cli@latest plugin package --tag quay.io/user/backstage-community-plugin-todo:v0.1.1 executing podman --version ✔ Using existing 'dist-dynamic' directory at plugins/todo Using existing 'dist-dynamic' directory at plugins/todo-backend diff --git a/docs/dynamic-plugins/packaging-dynamic-plugins.md b/docs/dynamic-plugins/packaging-dynamic-plugins.md index 944175eea2..a4a7e3d436 100644 --- a/docs/dynamic-plugins/packaging-dynamic-plugins.md +++ b/docs/dynamic-plugins/packaging-dynamic-plugins.md @@ -3,7 +3,7 @@ To package a Backstage plugin as a dynamic plugin, you need access to its source code. -First you need to create a derived package using the `@janus-idp/cli` and then package it into one of the supported formats. +First you need to create a derived package using the `@red-hat-developer-hub/cli` and then package it into one of the supported formats. For detailed instructions on creating a derived package, see [Export Derived Dynamic Plugin Package](export-derived-package.md). There are three possible packaging formats for dynamic plugins: @@ -23,16 +23,29 @@ The derived dynamic plugin JavaScript packages should **not** be pushed to the p - `podman` or `docker` installed on your system. - An exported derived dynamic plugin package (see: [Export Derived Dynamic Plugin Package](export-derived-package.md)). -To package the plugin into an OCI image, use the `package package-dynamic-plugins` command from `@janus-idp/cli` in the plugin’s source code root directory (not in the `dist-dynamic` directory). +To package the plugin into an OCI image, use the `plugin package` command from `@red-hat-developer-hub/cli` in the plugin’s source code root directory (not in the `dist-dynamic` directory). The command will output the correct path definition for the plugin, which can be used in the `dynamic-plugin-config.yaml` file. ```bash -npx @janus-idp/cli@latest package package-dynamic-plugins --tag quay.io/example/image:v0.0.1 +npx @red-hat-developer-hub/cli@latest plugin package --tag quay.io/example/image:v0.0.1 ``` The `--tag` argument is required when using this packaging method. It specifies the image name and tag. The image won't be pushed to the registry automatically; use the `podman push` or `docker push` command to push the image to the registry. +> **Note:** If `podman` is **not** installed on your system, you must explicitly specify the container tool using the `--container-tool` option. +> +> **Available values:** +> - `"docker"` +> - `"podman"` (default) +> - `"buildah"` +> +> Example using Docker: +> +> ```bash +> npx @red-hat-developer-hub/cli@latest plugin package --container-tool docker --tag quay.io/example/image:v0.0.1 +> ``` + ## Creating a `tgz` Archive **Prerequisites:** @@ -97,7 +110,7 @@ cd dist-dynamic npm publish --registry ``` -Alternatively, add the following to your `package.json` before running `npx @janus-idp/cli@latest package export-dynamic-plugin`: +Alternatively, add the following to your `package.json` before running `npx @red-hat-developer-hub/cli@latest plugin export`: ```json { diff --git a/docs/dynamic-plugins/versions.md b/docs/dynamic-plugins/versions.md index 99901326fe..6b0cae401d 100644 --- a/docs/dynamic-plugins/versions.md +++ b/docs/dynamic-plugins/versions.md @@ -5,12 +5,12 @@ https://github.com/redhat-developer/rhdh/blob/main/backstage.json --> -Based on [Backstage 1.36.1](https://backstage.io/docs/releases/v1.36.0) +Based on [Backstage 1.42.5](https://backstage.io/docs/releases/v1.42.0) To bootstrap Backstage app that is compatible with RHDH 1.4, you can use: ```bash -npx @backstage/create-app@0.5.25 +npx @backstage/create-app@0.7.3 ``` ### Frontend packages @@ -18,12 +18,12 @@ npx @backstage/create-app@0.5.25 | **Package** | **Version** | | ------------------------------ | ----------- | -| `@backstage/catalog-model` | `1.7.3` | -| `@backstage/config` | `1.3.2` | -| `@backstage/core-app-api` | `1.15.5` | -| `@backstage/core-components` | `0.16.4` | -| `@backstage/core-plugin-api` | `1.10.4` | -| `@backstage/integration-react` | `1.2.4` | +| `@backstage/catalog-model` | `1.7.5` | +| `@backstage/config` | `1.3.3` | +| `@backstage/core-app-api` | `1.18.0` | +| `@backstage/core-components` | `0.17.5` | +| `@backstage/core-plugin-api` | `1.10.9` | +| `@backstage/integration-react` | `1.2.9` | @@ -37,14 +37,14 @@ in the `main` branch of the [RHDH repository](https://github.com/redhat-develope | **Package** | **Version** | | ------------------------------ | ----------- | -| `@backstage/backend-app-api` | `1.2.0` | -| `@backstage/backend-defaults` | `0.8.1` | -| `@backstage/backend-dynamic-feature-service` | `0.6.0` | -| `@backstage/backend-plugin-api` | `1.2.0` | -| `@backstage/catalog-model` | `1.7.3` | -| `@backstage/cli-node` | `0.2.13` | -| `@backstage/config` | `1.3.2` | -| `@backstage/config-loader` | `1.9.6` | +| `@backstage/backend-app-api` | `1.2.6` | +| `@backstage/backend-defaults` | `0.12.0` | +| `@backstage/backend-dynamic-feature-service` | `0.7.3` | +| `@backstage/backend-plugin-api` | `1.4.2` | +| `@backstage/catalog-model` | `1.7.5` | +| `@backstage/cli-node` | `0.2.14` | +| `@backstage/config` | `1.3.3` | +| `@backstage/config-loader` | `1.10.2` | @@ -53,6 +53,60 @@ If you want to check versions of other packages, you can check the [`backend`](https://github.com/redhat-developer/rhdh/tree/main/packages/backend) package in the `main` branch of the [RHDH repository](https://github.com/redhat-developer/rhdh/tree/main). +## RHDH 1.7 + + + +Based on [Backstage 1.39.1](https://backstage.io/docs/releases/v1.39.0) + +To bootstrap Backstage app that is compatible with RHDH 1.4, you can use: + +```bash +npx @backstage/create-app@0.6.2 +``` + +### Frontend packages + + +| **Package** | **Version** | +| ------------------------------ | ----------- | +| `@backstage/catalog-model` | `1.7.4` | +| `@backstage/config` | `1.3.2` | +| `@backstage/core-app-api` | `1.17.0` | +| `@backstage/core-components` | `0.17.2` | +| `@backstage/core-plugin-api` | `1.10.7` | +| `@backstage/integration-react` | `1.2.7` | + + + +If you want to check versions of other packages, you can check the +[`package.json`](https://github.com/redhat-developer/rhdh/blob/release-1.7/packages/app/package.json) in the +[`app`](https://github.com/redhat-developer/rhdh/tree/release-1.7/packages/app) package +in the `release-1.7` branch of the [RHDH repository](https://github.com/redhat-developer/rhdh/tree/release-1.7). + +### Backend packages + + +| **Package** | **Version** | +| ------------------------------ | ----------- | +| `@backstage/backend-app-api` | `1.2.3` | +| `@backstage/backend-defaults` | `0.10.0` | +| `@backstage/backend-dynamic-feature-service` | `0.7.0` | +| `@backstage/backend-plugin-api` | `1.3.1` | +| `@backstage/catalog-model` | `1.7.4` | +| `@backstage/cli-node` | `0.2.13` | +| `@backstage/config` | `1.3.2` | +| `@backstage/config-loader` | `1.10.1` | + + + +If you want to check versions of other packages, you can check the +[`package.json`](https://github.com/redhat-developer/rhdh/blob/release-1.7/packages/backend/package.json) in the +[`backend`](https://github.com/redhat-developer/rhdh/tree/release-1.7/packages/backend) package +in the `release-1.7` branch of the [RHDH repository](https://github.com/redhat-developer/rhdh/tree/release-1.7). + ## RHDH 1.6 - -Based on [Backstage 1.29.2](https://backstage.io/docs/releases/v1.29.0) - -To bootstrap Backstage app that is compatible with RHDH 1.4, you can use: - -```bash -npx @backstage/create-app@0.5.17 -``` - -### Frontend packages - - -| **Package** | **Version** | -| ------------------------------ | ----------- | -| `@backstage/catalog-model` | `1.5.0` | -| `@backstage/config` | `1.2.0` | -| `@backstage/core-app-api` | `1.14.1` | -| `@backstage/core-components` | `0.14.9` | -| `@backstage/core-plugin-api` | `1.9.3` | -| `@backstage/integration-react` | `1.1.29` | - - - -If you want to check versions of other packages, you can check the -[`package.json`](https://github.com/redhat-developer/rhdh/blob/release-1.3/packages/app/package.json) in the -[`app`](https://github.com/redhat-developer/rhdh/tree/release-1.3/packages/app) package -in the `release-1.3` branch of the [RHDH repository](https://github.com/redhat-developer/rhdh/tree/release-1.3). - -### Backend packages - - -| **Package** | **Version** | -| ------------------------------ | ----------- | -| `@backstage/backend-app-api` | `0.8.0` | -| `@backstage/backend-defaults` | `0.4.1` | -| `@backstage/backend-dynamic-feature-service` | `0.2.15` | -| `@backstage/backend-plugin-api` | `0.7.0` | -| `@backstage/catalog-model` | `1.5.0` | -| `@backstage/cli-node` | `0.2.7` | -| `@backstage/config` | `1.2.0` | -| `@backstage/config-loader` | `1.8.1` | - - - -If you want to check versions of other packages, you can check the -[`package.json`](https://github.com/redhat-developer/rhdh/blob/release-1.3/packages/backend/package.json) in the -[`backend`](https://github.com/redhat-developer/rhdh/tree/release-1.3/packages/backend) package -in the `release-1.3` branch of the [RHDH repository](https://github.com/redhat-developer/rhdh/tree/release-1.3). diff --git a/docs/e2e-tests/CI.md b/docs/e2e-tests/CI.md index a5a5eb5450..7228bdc940 100644 --- a/docs/e2e-tests/CI.md +++ b/docs/e2e-tests/CI.md @@ -25,24 +25,21 @@ For scenarios where tests are not automatically triggered, or when you need to m 2. **Triggering Tests Post-Validation:** - After a janus-idp member has validated the PR with `/ok-to-test`, anyone can trigger tests using the following commands: - - `/test`, `/test images`, `/test all` or `/test e2e-tests` + - `/test ?` to get a list of all available jobs + - `/test e2e-ocp-helm` for mandatory PR checks + - **Note:** Avoid using `/test all` as it may trigger unnecessary jobs and consume CI resources. Instead, use `/test ?` to see available options and trigger only the specific tests you need. 3. **Triggering Optional Nightly Job Execution on Pull Requests:** - The following optional nightly jobs can be manually triggered on PRs targeting the `main` branch. These jobs help validate changes across various deployment environments by commenting the trigger command on PR. - ### Available Nightly Jobs on PR - - **Operator-Specific Test:** - Runs PR tests using an operator-based deployment on an OpenShift (OCP) cluster. - Trigger command: `/test e2e-tests-operator-nightly` - - **Azure Kubernetes Service (AKS) Test:** - Runs PR tests on AKS. - Trigger command: `/test e2e-tests-aks-helm-nightly` - - **Google Kubernetes Engine (GKE) Test:** - Runs PR tests on GKE. - Trigger command: `/test e2e-tests-gke-helm-nightly` - - **Standard Nightly Test on OpenShift v4.17:** - Runs PR tests on OCP version 4.17. - Trigger command: `/test e2e-tests-nightly` - -These interactions are picked up by the OpenShift-CI service, which sets up a test environment on the **IBM Cloud**, specifically on an OpenShift Container Platform (OCP) cluster. The configurations and steps for setting up this environment are defined in the `openshift-ci-tests.sh` script. For more details, see the [High-Level Overview of `openshift-ci-tests.sh`](#high-level-overview-of-openshift-ci-testssh). + The following optional nightly jobs can be manually triggered on PRs targeting the `main` branch and `release-*` branches. These jobs help validate changes across various deployment environments by commenting the trigger command on PR. + + **Job Name Format:** Jobs follow the naming scheme `redhat-developer-rhdh-PLATFORM-[VERSION]-INSTALL_METHOD-[SPECIAL_TEST]-nightly` where: + - `PLATFORM`: The target platform (e.g., `ocp`, `aks`, `gke`) + - `VERSION`: The platform version (e.g., `v4-17`, `v4-18`, `v4-19`) + - `INSTALL_METHOD`: The deployment method (e.g., `helm`, `operator`) + - `SPECIAL_TEST`: Optional special test type (e.g., `auth-providers`, `upgrade`, `sealights`) + + Use `/test ?` to see the complete list of available jobs for your specific branch and PR context. + +These interactions are picked up by the OpenShift-CI service, which sets up a test environmentr. The configurations and steps for setting up this environment are defined in the `openshift-ci-tests.sh` script. For more details, see the [High-Level Overview of `openshift-ci-tests.sh`](#high-level-overview-of-openshift-ci-testssh). ### Retrying Tests @@ -55,8 +52,8 @@ If the initial automatically triggered tests fail, OpenShift-CI will add a comme - **Purpose:** Validate new PRs for code quality, functionality, and integration. - **Trigger:** - **Automatic:** When a PR includes code changes affecting tests (excluding doc-only changes), tests are automatically triggered. - - **Manual:** When `/ok-to-test` is commented by a janus-idp member for external contributors or when `/test`, `/test images`, `/test all` and `/test e2e-tests` is commented after validation. -- **Environment:** Runs on an ephemeral OpenShift cluster on IBM Cloud. + - **Manual:** When `/ok-to-test` is commented by a janus-idp member for external contributors or when `/test`, `/test images`, or `/test e2e-ocp-helm` is commented after validation. +- **Environment:** Runs on ephemeral OpenShift clusters managed by Hive. Kubernetes jobs use ephemeral EKS and AKS clusters on spot instances managed by [Mapt](https://github.com/redhat-developer/mapt). GKE uses a long-running cluster. - **Configurations:** - Tests are executed on both **RBAC** (Role-Based Access Control) and **non-RBAC** namespaces. Different sets of tests are executed for both the **non-RBAC RHDH instance** and the **RBAC RHDH instance**, each deployed in separate namespaces. - **Access:** In order to access the environment, you can run the bash at `.ibm/pipelines/ocp-cluster-claim-login.sh`. You will be prompted the prow url (the url from the openshift agent, which looks like https://prow.ci.openshift.org/...). Once you test calimed a cluster, this script will forward the cluster web console url along with the credentials. diff --git a/docs/e2e-tests/README.md b/docs/e2e-tests/README.md index 9fd4ef08f9..5c0485717d 100644 --- a/docs/e2e-tests/README.md +++ b/docs/e2e-tests/README.md @@ -48,6 +48,16 @@ To run the tests, ensure you have: - An instance of the application to run the tests against - [Playwright browsers installed](#install-playwright-browsers) +#### macOS Users +**Important**: If you're using macOS, you need to install GNU `grep` and GNU `sed` to avoid compatibility issues with scripts and CI/CD pipelines: + +```bash +brew install grep +brew install gnu-sed +``` + +**Note**: Make sure to set the GNU versions as default to ensure they are used instead of the built-in macOS versions, which may cause issues when running scripts or tests that expect GNU-compatible behavior. + ### Environment Variables Certain environment variables need to be set up, depending on what you intend to run. The most convenient way is to export them from the CLI or add them in your `.bash_profile` or `.zshrc`. Alternatively, they can be passed to Playwright via the `--env` flag: diff --git a/docs/e2e-tests/e2e-i18n-guide.md b/docs/e2e-tests/e2e-i18n-guide.md new file mode 100644 index 0000000000..57ffcb248c --- /dev/null +++ b/docs/e2e-tests/e2e-i18n-guide.md @@ -0,0 +1,227 @@ +# Internationalization (i18n) in E2E Tests + +Our Playwright-based E2E testing framework supports internationalization (i18n) to ensure tests are language-agnostic and easily adaptable across locales. Instead of hardcoding UI text in tests, we use language-specific translation variables, improving maintainability and scalability. + +--- + +## Project Structure (Relevant to i18n) + +``` +e2e-tests/ +├── playwright/ +│ ├── e2e/ +│ │ └── techdocs.spec.ts # Example test file using i18n +│ ├── support/ +│ │ └── translations/ +│ │ └── techdocs/ +│ │ ├── en.ts # English translations +│ │ ├── fr.ts # French translations +│ │ ├── de.ts # German translations +│ │ └── index.ts # Translation loader +``` + +--- + +## Translation Files + +Each language file exports a structured dictionary of strings grouped by UI sections for clarity. + +### Example: `en.ts` + +```ts +export const en = { + sidebar: { + favorites: "Favorites", + docs: "Docs", + }, + techdocs: { + linkName: "Red Hat Developer Hub", + pageTitle: "Getting Started running RHDH", + }, +}; +``` + +### Example: `fr.ts` + +```ts +export const fr = { + sidebar: { + favorites: "Favoris", + docs: "Docs", + }, + techdocs: { + linkName: "Red Hat Developer Hub", + pageTitle: "Commencer avec RHDH", + }, +}; +``` + +### Example: `de.ts` + +```ts +export const de = { + sidebar: { + favorites: "Favoriten", + docs: "Dokumentation", + }, + techdocs: { + linkName: "Red Hat Developer Hub", + pageTitle: "Erste Schritte mit RHDH", + }, +}; +``` + +--- + +## Translation Loader (`index.ts`) + +```ts +import { en } from './en'; +import { fr } from './fr'; +import { de } from './de'; + +export const locales = { en, fr, de }; + +export type Locale = keyof typeof locales; + +export const getCurrentLanguage = (): Locale => { + const lang = process.env.LOCALE || 'en'; + return lang as Locale; +}; + +export const getLocale = (lang: Locale = getCurrentLanguage()) => { + return locales[lang] || locales.en; +}; + +export const getTranslations = () => { + const lang = getCurrentLanguage(); + return getLocale(lang); +}; +``` + +* Reads current language from `LOCALE` env var (defaults to `en`) +* `getTranslations()` returns translations for the current locale in one call + +--- + +## Test File Using i18n with Simplified API + +### Before (Hardcoded UI Strings) + +```ts +test("Verify that TechDocs is visible in sidebar", async () => { + await uiHelper.openSidebarButton("Favorites"); + await uiHelper.openSidebar("Docs"); +}); + +test("Verify that TechDocs Docs page for Red Hat Developer Hub works", async ({ page }) => { + await uiHelper.openSidebarButton("Favorites"); + await uiHelper.openSidebar("Docs"); + await page.getByRole("link", { name: "Red Hat Developer Hub" }).click(); + await uiHelper.waitForTitle("Getting Started running RHDH", 1); +}); +``` + +--- + +### After (Using Simplified `getTranslations()`) + +```ts +import { getTranslations } from "../../support/translations/techdocs"; + +const t = getTranslations(); + +test("Verify that TechDocs is visible in sidebar", async () => { + await uiHelper.openSidebarButton(t.sidebar.favorites); + await uiHelper.openSidebar(t.sidebar.docs); +}); + +test("Verify that TechDocs Docs page for Red Hat Developer Hub works", async ({ page }) => { + await uiHelper.openSidebarButton(t.sidebar.favorites); + await uiHelper.openSidebar(t.sidebar.docs); + await page.getByRole("link", { name: t.techdocs.linkName }).click(); + await uiHelper.waitForTitle(t.techdocs.pageTitle, 1); +}); +``` + +--- + +## Running Tests in Different Languages + +Set the `LOCALE` environment variable to run tests in your desired language: + +```bash +LOCALE=fr npx playwright test +LOCALE=de npx playwright test +``` + +If not set, tests default to English (`en`). + +--- + +## Adding a New Locale to Localization Tests + +To support a new language (locale) in your E2E tests, follow these steps: + +### 1. **Create a Translation File** + +Create a new translation file inside the `translations/` folder following the naming convention `.ts`. For example, to add Spanish: + +**`support/techdocs/translations/es.ts`** + +```ts +export const es = { + sidebar: { + favorites: "Favoritos", + docs: "Documentación", + }, + techdocs: { + linkName: "Red Hat Developer Hub", + pageTitle: "Empezando con RHDH", + }, +}; +``` + +Ensure the structure matches the other locale files (`en.ts`, `fr.ts`, etc.). + +--- + +### 2. **Update the Translation Loader (`index.ts`)** + +Import your new locale and add it to the `locales` object: + +```ts +import { en } from './en'; +import { fr } from './fr'; +import { de } from './de'; +import { es } from './es'; // Add this line + +export const locales = { en, fr, de, es }; // And this line +``` + +No changes are required in test files, as they dynamically load the locale using the `LOCALE` environment variable. + +--- + +### 3. **Run Tests in the New Locale** + +Use the `LOCALE` environment variable to execute tests in the new language: + +```bash +LOCALE=es npx playwright test +``` + +--- + +## Summary + +| Concept | Description | +| ------------------- | ------------------------------------------------------------- | +| Translation files | Language-specific key-value mappings (`en.ts`, `fr.ts`, etc.) | +| `getTranslations()` | Fetches translations for the active locale in one call | +| `t.variable` | Translation keys used in tests instead of hardcoded text | +| `LOCALE` env var | Controls which language tests run in | + +--- + +With this setup, your tests are multilingual-ready, allowing you to catch UI issues across locales efficiently and with a simplified API. \ No newline at end of file diff --git a/docs/e2e-tests/enhanced-ci-reporting.md b/docs/e2e-tests/enhanced-ci-reporting.md new file mode 100644 index 0000000000..49d208ffec --- /dev/null +++ b/docs/e2e-tests/enhanced-ci-reporting.md @@ -0,0 +1,143 @@ +# Enhanced CI Reporting + +This document describes the enhanced CI reporting system that provides detailed status tracking and notifications for e2e test runs in OpenShift CI. + +## Overview + +The enhanced CI reporting system uses the [`.ibm/pipelines/reporting.sh`](../../.ibm/pipelines/reporting.sh) script to track various aspects of test execution and deployment status. Results are stored in the `SHARED_DIR` for use by OpenShift CI steps and are formatted into Slack notifications sent to the `#rhdh-e2e-test-alerts` channel. + +**Note:** The `SHARED_DIR` can only contain files. No directories or nested structures are supported. + +## Using reporting.sh Functions + +The [`.ibm/pipelines/reporting.sh`](../../.ibm/pipelines/reporting.sh) script provides several functions to signal different types of results. It uses a Bash array to store statuses for multiple deployments, indexed by `CURRENT_DEPLOYMENT` (a deployment number). + +### Core Reporting Functions + +#### `save_status_deployment_namespace(deployment, namespace)` +Records the namespace where a deployment was created. + +```bash +save_status_deployment_namespace $CURRENT_DEPLOYMENT $namespace +``` + +#### `save_status_failed_to_deploy(deployment, status)` +Records whether a deployment failed (true/false). + +```bash +save_status_failed_to_deploy $CURRENT_DEPLOYMENT false # Success +save_status_failed_to_deploy $CURRENT_DEPLOYMENT true # Failure +``` + +#### `save_status_test_failed(deployment, status)` +Records whether tests failed for a deployment (true/false). + +```bash +save_status_test_failed $CURRENT_DEPLOYMENT false # Tests passed +save_status_test_failed $CURRENT_DEPLOYMENT true # Tests failed +``` + +#### `save_status_number_of_test_failed(deployment, number)` +Records the number of failed tests. + +```bash +save_status_number_of_test_failed $CURRENT_DEPLOYMENT "3" +``` + +#### `save_overall_result(result)` +Records the overall test result (0 for success, 1 for failure). + +```bash +save_overall_result 0 # Overall success +save_overall_result 1 # Overall failure +``` + +## SHARED_DIR Integration + +All status information is written to files in the `SHARED_DIR` directory, which is shared between OpenShift CI steps: + +- `SHARED_DIR/STATUS_DEPLOYMENT_NAMESPACE.txt` - Bash array format +- `SHARED_DIR/STATUS_FAILED_TO_DEPLOY.txt` - Bash array format +- `SHARED_DIR/STATUS_TEST_FAILED.txt` - Bash array format +- `SHARED_DIR/STATUS_NUMBER_OF_TEST_FAILED.txt` - Bash array format +- `SHARED_DIR/STATUS_URL_REPORTPORTAL.txt` - Bash array format +- `SHARED_DIR/OVERALL_RESULT.txt` - Single value + +The status files use bash arrays indexed by `CURRENT_DEPLOYMENT` (deployment number), except for `OVERALL_RESULT.txt` which contains a single value. These files are also copied to `ARTIFACT_DIR/reporting/` for artifact collection. + +## Usage Examples + +### In Test Scripts + +```bash +# Source the reporting functions +source "${DIR}/reporting.sh" + +# Initialize overall result +save_overall_result 0 + +# Record deployment success +save_status_deployment_namespace $CURRENT_DEPLOYMENT "showcase" +save_status_failed_to_deploy $CURRENT_DEPLOYMENT false + +# Record test results +if [ "${RESULT}" -ne 0 ]; then + save_overall_result 1 + save_status_test_failed $CURRENT_DEPLOYMENT true +else + save_status_test_failed $CURRENT_DEPLOYMENT false +fi + +# Record number of failed tests +failed_tests=$(grep -oP 'failures="\K[0-9]+' "${JUNIT_RESULTS}" | head -n 1) +save_status_number_of_test_failed $CURRENT_DEPLOYMENT "${failed_tests}" +``` + +### Error Handling + +The system automatically handles script failures through the cleanup trap. See [`.ibm/pipelines/openshift-ci-tests.sh`](../../.ibm/pipelines/openshift-ci-tests.sh). + +## OpenShift CI Integration + +The reporting system integrates with OpenShift CI through: + +1. **Step Registry**: OpenShift CI steps can read the status files from `SHARED_DIR` +2. **Artifact Collection**: Status files are preserved in artifacts for debugging +3. **Slack Notifications**: Results are formatted and sent to `#rhdh-e2e-test-alerts` + +### The `redhat-developer-rhdh-send-alert` step + +The `redhat-developer-rhdh-send-alert` step is defined in the [OpenShift release repository](https://github.com/openshift/release) under [`ci-operator/step-registry/redhat-developer/rhdh/send/alert/`](https://github.com/openshift/release/tree/master/ci-operator/step-registry/redhat-developer/rhdh/send/alert). This step: + +- Runs as a post-step in OpenShift CI jobs +- Reads the status files from `SHARED_DIR` that were written by the reporting functions +- Formats the collected status information into structured Slack messages +- Sends notifications to the `#rhdh-e2e-test-alerts` channel +- Handles multiple deployments and their individual test results +- Provides links to job logs, artifacts, and ReportPortal results + +The step is configured in job definitions to run after test execution completes, ensuring all status information is captured and reported. + +## Slack Notifications + +For nightly runs, the system automatically sends notifications to the `#rhdh-e2e-test-alerts` Slack channel. The message format includes: + +- **Job Header**: Job name with overall status +- **Logs Link**: Direct link to job logs +- **Triage Mention**: `@rhdh-ci-test-triage` for team notification +- **Per-Deployment Status**: Each deployment shows: + - **Deployment Name**: e.g., `showcase-ci-nightly`, `showcase-rbac-nightly` + - **Deployment Status**: "deployed" status + - **Test Results**: "tests passed" or failure count (e.g., "2 tests failed") + - **Tools**: Playwright, ReportPortal, and artifacts links + +## File Locations + +- **Script**: [`.ibm/pipelines/reporting.sh`](../../.ibm/pipelines/reporting.sh) +- **Integration**: [`.ibm/pipelines/utils.sh`](../../.ibm/pipelines/utils.sh) and [`.ibm/pipelines/openshift-ci-tests.sh`](../../.ibm/pipelines/openshift-ci-tests.sh) + +## Related Documentation + +- [CI Testing Overview](CI.md) +- [E2E Tests Examples](examples.md) +- [Contributing to E2E Tests](CONTRIBUTING.MD) \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 63b7530d5c..0908d3ea2b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -225,6 +225,56 @@ The easiest and fastest method for getting started: RHDH app, running it locally ## Optional Configuration and Plugins +- Adding a Home Page + - Run `yarn export-dynamic` from the `dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page`: + ```bash + pushd dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page && yarn export-dynamic && popd + ``` + - Copy-paste the `dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page` folder into `dynamic-plugins-root`: + ```bash + cp -r dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page dynamic-plugins-root/ + ``` + - Add the following to your `app-config.local.yaml`: + ```yaml + dynamicPlugins: + frontend: + red-hat-developer-hub.backstage-plugin-dynamic-home-page: + dynamicRoutes: + - path: / + importName: DynamicHomePage + mountPoints: + - mountPoint: home.page/cards + importName: SearchBar + config: + layouts: + xl: { w: 10, h: 1, x: 1 } + lg: { w: 10, h: 1, x: 1 } + md: { w: 10, h: 1, x: 1 } + sm: { w: 10, h: 1, x: 1 } + xs: { w: 12, h: 1 } + xxs: { w: 12, h: 1 } + - mountPoint: home.page/cards + importName: QuickAccessCard + config: + layouts: + xl: { w: 7, h: 8 } + lg: { w: 7, h: 8 } + md: { w: 7, h: 8 } + sm: { w: 12, h: 8 } + xs: { w: 12, h: 8 } + xxs: { w: 12, h: 8 } + - mountPoint: home.page/cards + importName: CatalogStarredEntitiesCard + config: + layouts: + xl: { w: 5, h: 4, x: 7 } + lg: { w: 5, h: 4, x: 7 } + md: { w: 5, h: 4, x: 7 } + sm: { w: 12, h: 4 } + xs: { w: 12, h: 4 } + xxs: { w: 12, h: 4 } + ``` + - Enabling Authentication in Showcase - Refer to the [authentication documentation](./auth.md) for the available auth providers and the steps to configure them. diff --git a/docs/keycloak-quickstart.md b/docs/keycloak-quickstart.md index c833c3ddb5..49bde1e0f3 100644 --- a/docs/keycloak-quickstart.md +++ b/docs/keycloak-quickstart.md @@ -6,7 +6,7 @@ This guide will show you how to quickly start up a quick keycloak instance on Op This script allows a quick setup of a basic keycloak instance on OpenShift Container Platform (OCP) clusters for testing purposes. -User should be logged into a cluster to use this script and have the [Red Hat Keycloak Operator installed on the cluster](https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/22.0/html-single/operator_guide/index#installation-). +User should be logged into a cluster to use this script and have the [Red Hat Keycloak Operator installed on the cluster](https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.2/html-single/operator_guide/index#installation-). This script comes with a few example keycloak resources to be deployed onto the cluster. Please create a `scripts/keycloak-setup/auth/database-secrets.local.yaml` file with your custom database secret, and edit the other resources to fit your needs. diff --git a/docs/logging.md b/docs/logging.md new file mode 100644 index 0000000000..1a154d2f20 --- /dev/null +++ b/docs/logging.md @@ -0,0 +1,50 @@ +# Logging for RHDH + +This document covers logging configuration for Red Hat Developer Hub (RHDH). Logging in RHDH is conducted using the [winston](https://github.com/winstonjs/winston) library. By default, logs of level `debug` are not logged. To enable debug logs, you will need to set the environment variable `LOG_LEVEL` to `debug` in your deployment. + +## Prerequisites + +- Kubernetes 1.19+ +- PV provisioner support in the underlying infrastructure + + +### Helm deployment + +You can set the logging level by adding the environment variable in your Helm chart's `values.yaml`, as follows: + +```yaml title="values.yaml" +upstream: + backstage: + # Other configurations above + extraEnvVars: + - name: LOG_LEVEL + value: debug +``` + +### Operator-backed deployment + +You can set the logging level by adding the environment variable in your Custom Resource, like so: + +```yaml title="env var in Custom Resource" +spec: + # Other fields omitted + application: + extraEnvs: + envs: + - name: LOG_LEVEL + value: debug +``` + +### Openshift Logging Integration + +[Openshift Logging](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/logging/index) can be used to monitor Backstage logs. The only requirement is to correctly filter logs in Kibana. A possible filter is using the field `kubernetes.container_name` with operator `is` and value `backstage-backend`. + +### Logging with Azure Monitor Container Insights + +[Azure Monitor Container Insights](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/container-insights-log-query#container-logs) can be used to query logs from your Backstage instance. The AKS cluster must have Container Insights configured with container logs turned on. You can then query logs from your Backstage instance by querying from the `ContainerLogV2` table: + +```kql +ContainerLogV2 +| where ContainerName == "backstage-backend" +| project TimeGenerated, LogMessage +``` diff --git a/docs/monitoring-and-logging.md b/docs/monitoring-and-logging.md deleted file mode 100644 index fcdfe05b7d..0000000000 --- a/docs/monitoring-and-logging.md +++ /dev/null @@ -1,240 +0,0 @@ -# Setting up Metrics Monitoring and Logging for RHDH - -The RHDH provides a `/metrics` endpoint on port `9464` that provides OpenTelemetry metrics about your backstage application. This endpoint can be used to monitor your backstage instance using OpenTelemetry and Grafana. - -When deploying RHDH onto a kubernetes cluster with the [RHDH Helm chart](https://github.com/redhat-developer/rhdh-chart) or the [RHDH Operator](https://github.com/janus-idp/operator), monitoring and logging for your RHDH instance can be configured using the following steps. - -## Prerequisites - -- Kubernetes 1.19+ -- PV provisioner support in the underlying infrastructure -- If using the Helm Chart - - Helm 3.2.0+ - - The [RHDH Helm chart repositories](https://github.com/redhat-developer/rhdh-chart#installing-from-the-chart-repository) - -## Metrics Monitoring - -### Enabling Metrics Monitoring on Openshift - -To enable metrics monitoring on OpenShift, we need to create a `ServiceMonitor` resource in the OpenShift cluster that will be used by Prometheus to scrape metrics from your Backstage instance. For the metrics to be ingested by the built-in Prometheus instances in Openshift, please ensure you enabled [monitoring for user-defined projects](https://docs.openshift.com/container-platform/latest/observability/monitoring/configuring-user-workload-monitoring/preparing-to-configure-the-monitoring-stack-uwm.html). - -#### Helm deployment - -To enable metrics on Openshift when deploying with the [RHDH Helm chart](https://github.com/redhat-developer/rhdh-chart), you will need to modify the [`values.yaml`](https://github.com/redhat-developer/rhdh-chart/blob/main/charts/backstage/values.yaml) of the Chart. - -To obtain the `values.yaml`, you can run the following command: - -```bash -helm show values redhat-developer/backstage > values.yaml -``` - -Then, you will need to modify the `values.yaml` to enable metrics monitoring by setting `upstream.metrics.serviceMonitor.enabled` to true: - -```yaml title="values.yaml" -upstream: - # Other Configurations Above - metrics: - serviceMonitor: - enabled: true - path: /metrics - port: http-metrics -``` - -Then you can deploy the Janus Helm chart with the modified `values.yaml`: - -```bash -helm upgrade -i redhat-developer/backstage -f values.yaml -``` - -You can then verify metrics are being captured by navigating to the Openshift Console. Go to `Developer` Mode, change to the namespace the showcase is deployed on, selecting `Observe` and navigating to the `Metrics` tab. Here you can create PromQL queries to query the metrics being captured by OpenTelemetry. -![Openshift Metrics](./images/openshift-metrics.png) - -#### Operator-backed deployment - -At the moment, the operator does not support creating OpenShift `ServiceMonitor` instances out of the box. - -However, you can manually create a `ServiceMonitor` resource for your operator-backed Backstage instance; and it will be used by Prometheus to scrape metrics from your Backstage instance. To do so, please adjust and run the following commands using either `oc` or `kubectl`: - -```bash -# make sure to update CR_NAME value accordingly -$ CR_NAME=my-rhdh -$ MY_PROJECT=my-project -$ cat < /tmp/${CR_NAME}.ServiceMonitor.yaml -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: ${CR_NAME} - namespace: ${MY_PROJECT} - labels: - app.kubernetes.io/instance: ${CR_NAME} - app.kubernetes.io/name: backstage -spec: - namespaceSelector: - matchNames: - - ${MY_PROJECT} - selector: - matchLabels: - rhdh.redhat.com/app: backstage-${CR_NAME} - endpoints: - - port: http-metrics - path: '/metrics' -EOF -$ oc apply -f /tmp/${CR_NAME}.ServiceMonitor.yaml -``` - -Similar to the instructions above for a Helm-based deployment, you can then verify metrics are being captured by navigating to the Openshift Console. Go to `Developer` Mode, change to the namespace the showcase is deployed on, selecting `Observe` and navigating to the `Metrics` tab. - -### Enabling Metrics Monitoring on Azure Kubernetes Service (AKS) - -To enable metrics monitoring for RHDH on Azure Kubernetes Service (AKS), you can use the [Azure Monitor managed service for Prometheus](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/prometheus-metrics-overview). The AKS cluster will need to have an associated [Azure Monitor workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/prometheus-metrics-enable?tabs=azure-portal). - -One method is to configure the metrics scraping of your AKS cluster using the [Azure Monitor _metrics_ add-on](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/prometheus-metrics-scrape-configuration). - -The other method is to configure the Azure Monitor _monitoring_ add-on which also allows you to [send Prometheus metrics to the Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/container-insights-prometheus-logs). These metrics can then be queried using [Log Analytics queries](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/container-insights-log-query#prometheus-metrics) as well as be visible in a Grafana instance. - -In both methods, we can configure the metrics scraping to scrap from pods based on pod Annotations. Follow the steps below depending on how the RHDH application is deployed. - -#### Helm deployment - -To add annotations to the backstage pod, add the following to the Janus Helm chart `values.yaml`: - -```yaml title="values.yaml" -upstream: - backstage: - # Other configurations above - podAnnotations: - # Other annotations above - prometheus.io/scrape: 'true' - prometheus.io/path: '/metrics' - prometheus.io/port: '9464' - prometheus.io/scheme: 'http' -``` - -#### Operator-backed deployment - -For an operator-backed deployment, you will need to first create your Custom Resource, then manually add the annotations to the Backstage Pod created by the Operator. - -Using `oc` or `kubectl`, you can run the following command: - -```bash -# make sure to update CR_NAME value accordingly -$ CR_NAME=my-rhdh -$ oc annotate pods \ - --selector janus-idp.io/app="backstage-${CR_NAME}" \ - prometheus.io/scrape='true' \ - prometheus.io/path='/metrics' \ - prometheus.io/port='9464' \ - prometheus.io/scheme='http' -``` - -**NOTE**: Please note that these annotations might be lost if the pod has to be recreated by the operator. In this case, you can either add the annotations again or, as an administrator of the operator, change its default configuration. -To have something persistent, if you have access to the namespace where the operator is running (usually `rhdh-operator`, `openshift-operators`, or `backstage-system`), you can do the following, using either `oc` or `kubectl`: - -1. Edit the default configuration of the operator: - -```bash -# make sure to update OPERATOR_NS accordingly -$ OPERATOR_NS=rhdh-operator -$ oc edit configmap backstage-default-config -n "${OPERATOR_NS}" -``` - -2. Find the `deployment.yaml` key in the ConfigMap, and add the annotations to the `spec.template.metadata.annotations` field, like so: - -```yaml -deployment.yaml: |- - apiVersion: apps/v1 - kind: Deployment - # --- truncated --- - spec: - template: - # --- truncated --- - metadata: - labels: - janus-idp.io/app: # placeholder for 'backstage-' - # --- truncated --- - annotations: - prometheus.io/scrape: 'true' - prometheus.io/path: '/metrics' - prometheus.io/port: '9464' - prometheus.io/scheme: 'http' - # --- truncated --- -``` - -3. Save -4. If you already have existing resources created by the operator from existing Custom Resources, you might need to force the operator to recreate the pods, by deleting the corresponding Deployment. For example: - -```bash -# make sure to update CR_NAME value accordingly -$ CR_NAME=my-rhdh -$ oc delete deployment --selector app.kubernetes.io/instance="${CR_NAME}" -``` - -#### Metrics Add-on - -For the _metrics_ add-on, we can modify the [`ama-metrics-settings-configmap`](https://github.com/Azure/prometheus-collector/blob/main/otelcollector/configmaps/ama-metrics-settings-configmap.yaml) Config Map and enable pod annotations based scraping for the namespace your showcase instance is in. In the [example Config Map](./configuration_files/ama-metrics-settings-configmap.yaml), change the regex for the `podannotationnamespaceregex` option to match the namespaces you want to scrape from. For more information on how to configure this refer to the [official Azure docs](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/prometheus-metrics-scrape-configuration#customize-metrics-collected-by-default-targets). - -Alternatively, we will can instead add/modify the `ama-metrics-prometheus-config` Config Map in the `kube-system` namespace of the AKS cluster to configure custom scrape jobs. In the [example Config Map](./configuration_files/ama-metrics-prometheus-config.yaml), please replace the values of namespace with the namespace you the backstage instance into. For more information on how to configure this refer to the [official Azure docs](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/prometheus-metrics-scrape-configuration#configure-custom-prometheus-scrape-jobs). - -To view the metrics, you can create a Grafana instance, [configure an Azure Monitor data source plug-in](https://learn.microsoft.com/en-us/azure/azure-monitor/visualize/grafana-plugin#configure-an-azure-monitor-data-source-plug-in) and view the metrics using PromQL queries. - -#### Monitoring Add-on - -For the _monitoring_ add-on, we will need to add the a modified instance of this [Config Map](https://raw.githubusercontent.com/microsoft/Docker-Provider/ci_prod/kubernetes/container-azm-ms-agentconfig.yaml) to the `kube-system` namespace of the AKS cluster. In the [example Config Map](./configuration_files/container-azm-ms-agentconfig.yaml), please replace the values of namespace with the namespace you deployed the backstage instance into. For more information refer to the [official Azure docs](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/container-insights-prometheus-logs?tabs=cluster-wide). - -To view the metrics, you can create a Grafana instance, [configure an Azure Monitor data source plug-in](https://learn.microsoft.com/en-us/azure/azure-monitor/visualize/grafana-plugin#configure-an-azure-monitor-data-source-plug-in) and view the metrics using PromQL queries. - -Alternatively, you can use [Log Analytics](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/container-insights-log-query#prometheus-metrics) to query the metrics using KQL. The following is an example query to get a custom metric for the Backstage instance: - -```kql -let custom_metrics = "custom-metric-name"; -InsightsMetrics -| where Namespace contains "prometheus" -| where Name == custom_metrics -| extend tags = parse_json(Tags) -| where tostring(tags['app.kubernetes.io/component']) == "backstage" -``` - -## Logging - -Logging in RHDH is conducted using the [winston](https://github.com/winstonjs/winston) library. By default, logs of level `debug` are not logged. To enable debug logs, you will need to set the environment variable `LOG_LEVEL` to `debug` in your deployment. - -### Helm deployment - -You can set the logging level by adding the environment variable in your Helm chart's `values.yaml`, as follows: - -```yaml title="values.yaml" -upstream: - backstage: - # Other configurations above - extraEnvVars: - - name: LOG_LEVEL - value: debug -``` - -### Operator-backed deployment - -You can set the logging level by adding the environment variable in your Custom Resource, like so: - -```yaml title="env var in Custom Resource" -spec: - # Other fields omitted - application: - extraEnvs: - envs: - - name: LOG_LEVEL - value: debug -``` - -### Openshift Logging Integration - -[Openshift Logging](https://access.redhat.com/documentation/en-us/openshift_container_platform/4.13/html/logging/index) can be used to monitor Backstage logs. The only requirement is to correctly filter logs in Kibana. A possible filter is using the field `kubernetes.container_name` with operator `is` and value `backstage-backend`. - -### Logging with Azure Monitor Container Insights - -[Azure Monitor Container Insights](https://learn.microsoft.com/en-us/azure/azure-monitor/containers/container-insights-log-query#container-logs) can be used to query logs from your Backstage instance. The AKS cluster must have Container Insights configured with container logs turned on. You can then query logs from your Backstage instance by querying from the `ContainerLogV2` table: - -```kql -ContainerLogV2 -| where ContainerName == "backstage-backend" -| project TimeGenerated, LogMessage -``` diff --git a/docs/proxy.md b/docs/proxy.md index 4026b58ffe..f6a1999b5a 100644 --- a/docs/proxy.md +++ b/docs/proxy.md @@ -14,6 +14,7 @@ $ GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE='' \ yarn start ``` + You can use the command below to quickly start a local corporate proxy server (based on [Squid](https://www.squid-cache.org/)): ```shell @@ -134,6 +135,7 @@ This approach simulates a corporate proxy environment in a Kubernetes/OpenShift 1. Make sure the network plugin in your Kubernetes cluster supports network policies. [k3d](https://k3d.io) for example supports Network Policies out of the box. + 2. Create a separate proxy namespace, and deploy a [Squid](https://www.squid-cache.org/)-based proxy application there. The full URL to access the proxy server from within the cluster would be `http://squid-service.proxy.svc.cluster.local:3128`. ```shell @@ -271,6 +273,7 @@ spec: ### OpenShift + 2. Create a separate proxy project, and deploy a [Squid](https://www.squid-cache.org/)-based proxy application there. The full URL to access the proxy server from within the cluster would be `http://squid-service.proxy.svc.cluster.local:3128`. ```shell diff --git a/dynamic-plugins.default.yaml b/dynamic-plugins.default.yaml index 388eb75a2f..27bb5c6ef3 100644 --- a/dynamic-plugins.default.yaml +++ b/dynamic-plugins.default.yaml @@ -27,7 +27,6 @@ plugins: seconds: 15 timeout: minutes: 15 - - package: ./dynamic-plugins/dist/backstage-community-plugin-github-actions disabled: true pluginConfig: @@ -179,7 +178,6 @@ plugins: catalog: providers: gitlab: {} - - package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-gitlab-org-dynamic disabled: true pluginConfig: @@ -224,6 +222,10 @@ plugins: dynamicPlugins: frontend: backstage-community.plugin-topology: + translationResources: + - importName: topologyTranslations + ref: topologyTranslationRef + module: Alpha mountPoints: - mountPoint: entity.page.topology/cards importName: TopologyPage @@ -273,6 +275,10 @@ plugins: dynamicPlugins: frontend: backstage-community.plugin-redhat-argocd: + translationResources: + - importName: argocdTranslations + module: Alpha + ref: argocdTranslationRef mountPoints: - mountPoint: entity.page.overview/cards importName: ArgocdDeploymentSummary @@ -451,6 +457,7 @@ plugins: menuItem: icon: ocmIcon text: Clusters + textKey: menuItem.clusters mountPoints: - mountPoint: entity.page.overview/context importName: ClusterContextProvider @@ -488,6 +495,10 @@ plugins: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-bulk-import: + translationResources: + - importName: bulkImportTranslations + module: Alpha + ref: bulkImportTranslationRef appIcons: - name: bulkImportIcon importName: BulkImportIcon @@ -497,7 +508,9 @@ plugins: menuItem: icon: bulkImportIcon text: Bulk import - # Global Header + textKey: menuItem.bulkImport + + # Group: Global Header - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header disabled: false pluginConfig: @@ -512,7 +525,14 @@ plugins: menuItems: default.create: title: '' + default.admin: + title: Administration + textKey: menuItem.administration + icon: admin red-hat-developer-hub.backstage-plugin-global-header: + translationResources: + - importName: globalHeaderTranslations + ref: globalHeaderTranslationRef mountPoints: - mountPoint: application/header importName: GlobalHeader @@ -540,6 +560,7 @@ plugins: priority: 90 props: title: Self-service + titleKey: create.title icon: add to: create - mountPoint: global.header/component @@ -559,6 +580,7 @@ plugins: priority: 150 props: title: Developer Hub + titleKey: applicationLauncher.developerHub icon: developerHub link: https://docs.redhat.com/en/documentation/red_hat_developer_hub @@ -569,6 +591,7 @@ plugins: priority: 100 props: title: RHDH Local + titleKey: applicationLauncher.rhdhLocal icon: developerHub link: https://github.com/redhat-developer/rhdh-local @@ -581,7 +604,7 @@ plugins: importName: SupportButton config: priority: 10 - + - mountPoint: global.header/component importName: NotificationButton config: @@ -600,6 +623,7 @@ plugins: priority: 100 props: title: Settings + titleKey: profile.settings link: /settings icon: manageAccounts - mountPoint: global.header/profile @@ -608,6 +632,8 @@ plugins: priority: 90 props: title: My profile + titleKey: profile.myProfile + type: myProfile icon: account - mountPoint: global.header/profile importName: LogoutButton @@ -621,6 +647,9 @@ plugins: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-global-floating-action-button: + translationResources: + - importName: globalFloatingActionButtonTranslations + ref: globalFloatingActionButtonTranslationRef mountPoints: - mountPoint: application/listener importName: DynamicGlobalFloatingActionButton @@ -632,32 +661,80 @@ plugins: app: quickstart: - title: Set up authentication + titleKey: steps.setupAuthentication.title icon: Admin description: Set up secure login credentials to protect your account from unauthorized access. + descriptionKey: steps.setupAuthentication.description cta: text: Learn more + textKey: steps.setupAuthentication.ctaTitle link: https://docs.redhat.com/en/documentation/red_hat_developer_hub/latest/html/authentication_in_red_hat_developer_hub/ - title: Configure RBAC + titleKey: steps.configureRbac.title icon: Rbac description: Assign roles and permissions to control who can view, create, or edit resources, ensuring secure and efficient collaboration. + descriptionKey: steps.configureRbac.description cta: text: Manage access + textKey: steps.configureRbac.ctaTitle link: /rbac - title: Configure Git + titleKey: steps.configureGit.title icon: Git description: Connect your Git providers, such as GitHub to manage code, automate workflows, and integrate with platform features. + descriptionKey: steps.configureGit.description cta: text: Learn more + textKey: steps.configureGit.ctaTitle link: https://docs.redhat.com/en/documentation/red_hat_developer_hub/latest/html/integrating_red_hat_developer_hub_with_github/ - title: Manage plugins + titleKey: steps.managePlugins.title icon: Plugins description: Browse and install extensions to add features, connect with external tools, and customize your experience. + descriptionKey: steps.managePlugins.description cta: text: Explore plugins + textKey: steps.managePlugins.ctaTitle link: /extensions + - title: Import application + roles: + - developer + icon: Import + description: Import your existing code and services into the catalog to organize and access them through your developer portal. + cta: + text: Import + link: /bulk-import/repositories + - title: Learn about the Catalog + roles: + - developer + icon: Catalog + description: Discover all software components, services, and APIs, and view their owners and documentation. + cta: + text: View Catalog + link: /catalog + - title: Explore Self-service templates + roles: + - developer + icon: SelfService + description: Use our self-service templates to quickly set up new projects, services, or documentation. + cta: + text: Explore templates + link: /create + - title: Find all Learning Paths + roles: + - developer + icon: Learning + description: Integrate tailored e-learning into your workflows with Learning Paths to accelerate onboarding, close skill gaps, and promote best practices. + cta: + text: View Learning Paths + link: /learning-paths dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-quickstart: + translationResources: + - importName: quickstartTranslations + module: Alpha + ref: quickstartTranslationRef mountPoints: - mountPoint: application/provider importName: QuickstartDrawerProvider @@ -666,7 +743,7 @@ plugins: config: priority: 100 - # Homepage + # Group: Homepage - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page disabled: false pluginConfig: @@ -683,22 +760,22 @@ plugins: importName: OnboardingSection config: layouts: - xl: { w: 12, h: 5 } - lg: { w: 12, h: 5 } - md: { w: 12, h: 5 } - sm: { w: 12, h: 5 } - xs: { w: 12, h: 7 } - xxs: { w: 12, h: 13 } + xl: { w: 12, h: 6 } + lg: { w: 12, h: 6 } + md: { w: 12, h: 7 } + sm: { w: 12, h: 8 } + xs: { w: 12, h: 9 } + xxs: { w: 12, h: 14 } - mountPoint: home.page/cards importName: EntitySection config: layouts: - xl: { w: 12, h: 6 } - lg: { w: 12, h: 6 } - md: { w: 12, h: 6 } - sm: { w: 12, h: 6 } - xs: { w: 12, h: 10 } - xxs: { w: 12, h: 14.5 } + xl: { w: 12, h: 7 } + lg: { w: 12, h: 7 } + md: { w: 12, h: 8 } + sm: { w: 12, h: 9 } + xs: { w: 12, h: 11 } + xxs: { w: 12, h: 15 } - mountPoint: home.page/cards importName: TemplateSection config: @@ -709,8 +786,11 @@ plugins: sm: { w: 12, h: 5 } xs: { w: 12, h: 7.5 } xxs: { w: 12, h: 13.5 } + translationResources: + - importName: homepageTranslations + ref: homepageTranslationRef - # Techdocs + # Group: Techdocs - package: ./dynamic-plugins/dist/backstage-plugin-techdocs-backend-dynamic disabled: false pluginConfig: @@ -746,6 +826,7 @@ plugins: menuItem: icon: docs text: Docs + textKey: menuItem.docs - path: /docs/:namespace/:kind/:name/* importName: TechDocsReaderPage mountPoints: @@ -776,7 +857,7 @@ plugins: techdocsAddons: - importName: ReportIssue - # PagerDuty + # Group: PagerDuty - package: ./dynamic-plugins/dist/pagerduty-backstage-plugin disabled: true pluginConfig: @@ -805,7 +886,6 @@ plugins: subDomain: ${PAGERDUTY_SUBDOMAIN} # Standalone plugins - - package: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-gerrit-dynamic disabled: true @@ -824,12 +904,17 @@ plugins: - package: ./dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-regex-dynamic disabled: false + # Group: RBAC - package: ./dynamic-plugins/dist/backstage-community-plugin-rbac disabled: true pluginConfig: dynamicPlugins: frontend: backstage-community.plugin-rbac: + translationResources: + - importName: rbacTranslations + ref: rbacTranslationRef + module: Alpha appIcons: - name: rbacIcon importName: RbacIcon @@ -839,9 +924,10 @@ plugins: menuItem: icon: rbacIcon text: RBAC + textKey: menuItem.rbac menuItems: rbac: - parent: admin + parent: default.admin icon: rbacIcon - package: ./dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic @@ -888,6 +974,7 @@ plugins: timeout: minutes: 50 + # Group: BitBucket - package: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic disabled: true - package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic @@ -906,7 +993,6 @@ plugins: minutes: 1 timeout: minutes: 3 - - package: ./dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic disabled: true - package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic @@ -980,6 +1066,9 @@ plugins: dynamicPlugins: frontend: backstage-community.plugin-tekton: + translationResources: + - importName: tektonTranslations + ref: tektonTranslationRef mountPoints: - mountPoint: entity.page.ci/cards importName: TektonCI @@ -1068,7 +1157,8 @@ plugins: importName: LighthousePage menuItem: icon: lighthouse - text: Lighthouse + text: menuItem.lighthouse + textKey: menuItem.lighthouse mountPoints: - mountPoint: entity.page.overview/cards importName: EntityLastLighthouseAuditCard @@ -1081,6 +1171,7 @@ plugins: allOf: - isLighthouseAvailable + # Group: TechRadar - package: ./dynamic-plugins/dist/backstage-community-plugin-tech-radar disabled: true pluginConfig: @@ -1097,7 +1188,8 @@ plugins: importName: TechRadarPage menuItem: icon: techRadar - text: Tech Radar + text: menuItem.techRadar + textKey: menuItem.techRadar config: props: width: 1500 @@ -1108,7 +1200,6 @@ plugins: techRadar: url: ${TECH_RADAR_DATA_URL} - - package: ./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment disabled: false pluginConfig: @@ -1129,6 +1220,8 @@ plugins: writeKey: ${SEGMENT_WRITE_KEY} maskIP: true # prevents IP addresses from being sent if true testMode: ${SEGMENT_TEST_MODE} # prevents data from being sent if true + appVersion: ${RHDH_VERSION} # RHDH application version + backstageVersion: ${BACKSTAGE_VERSION} # Backstage version - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic disabled: true @@ -1157,7 +1250,27 @@ plugins: pluginConfig: catalog: providers: - ldapOrg: {} + ldapOrg: + default: + target: ${LDAP_TARGET_URL} + bind: + dn: ${LDAP_BIND_DN} + secret: ${LDAP_BIND_SECRET} + users: + - dn: ${LDAP_USERS_DN} + options: + filter: (uid=*) + groups: + - dn: ${LDAP_GROUPS_DN} + options: + filter: (cn=*) + schedule: + frequency: + minutes: 60 + initialDelay: + seconds: 15 + timeout: + minutes: 15 - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic disabled: true @@ -1165,6 +1278,7 @@ plugins: catalog: providers: pingIdentityOrg: {} + # Group: Marketplace - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic disabled: false @@ -1176,23 +1290,28 @@ plugins: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-marketplace: + translationResources: + - importName: marketplaceTranslations + ref: marketplaceTranslationRef + module: Alpha appIcons: - - name: marketplace - importName: MarketplaceIcon + - name: pluginsIcon + importName: PluginsIcon dynamicRoutes: - - path: /extensions/catalog + - path: /extensions importName: DynamicMarketplacePluginRouter - mountPoints: - - mountPoint: internal.plugins/tab - importName: DynamicMarketplacePluginContent - config: - path: marketplace - title: Catalog + menuItem: + icon: pluginsIcon + text: Extensions + textKey: menuItem.extensions + menuItems: + extensions: + parent: default.admin # Group: Orchestrator - - package: "@redhat/backstage-plugin-orchestrator@1.6.0" + - package: "@redhat/backstage-plugin-orchestrator@1.7.1" disabled: true - integrity: sha512-fOSJv2PgtD2urKwBM7p9W6gV/0UIHSf4pkZ9V/wQO0eg0Zi5Mys/CL1ba3nO9x9l84MX11UBZ2r7PPVJPrmOtw== + integrity: sha512-Cqu9EQwVQ4mpdgWTUA0MW89Gul0IklhvkkqVoO3CloQ1dnAj1XyXikCphzH5TmNDDd9K66dOpaKKCaW9KeJ4WA== pluginConfig: dynamicPlugins: frontend: @@ -1205,37 +1324,56 @@ plugins: menuItem: icon: orchestratorIcon text: Orchestrator + textKey: menuItem.orchestrator path: /orchestrator - - - package: "@redhat/backstage-plugin-orchestrator-backend-dynamic@1.6.0" + entityTabs: + - path: /workflows + title: Workflows + titleKey: catalog.entityPage.workflows.title + mountPoint: entity.page.workflows + mountPoints: + - mountPoint: entity.page.workflows/cards + importName: OrchestratorCatalogTab + config: + layout: + gridColumn: '1 / -1' + if: + anyOf: + - IsOrchestratorCatalogTabAvailable + - package: "@redhat/backstage-plugin-orchestrator-backend-dynamic@1.7.1" disabled: true - integrity: sha512-Kr55YbuVwEADwGef9o9wyimcgHmiwehPeAtVHa9g2RQYoSPEa6BeOlaPzB6W5Ke3M2bN/0j0XXtpLuvrlXQogA== + integrity: sha512-9cXbedr0lC7ns7SNqARrWSQI4JGcZFw5xpfpUzA1tJaMMUjzAdPHTXqljf62/fs4hYBK8TJsWJ2KJkGVMzbrHQ== pluginConfig: orchestrator: dataIndexService: url: http://sonataflow-platform-data-index-service - - package: "@redhat/backstage-plugin-scaffolder-backend-module-orchestrator-dynamic@1.6.0" + - package: "@redhat/backstage-plugin-scaffolder-backend-module-orchestrator-dynamic@1.7.1" disabled: true - integrity: sha512-Bueeix4661fXEnfJ9y31Yw91LXJgw6hJUG7lPVdESCi9VwBCjDB9Rm8u2yPqP8sriwr0OMtKtqD+Odn3LOPyVw== + integrity: sha512-J1sTjA5kj6DphG8D65go9KlpIfKyLN/wq+XlY5Cb5djEo8mvF3wn3Haf60OGFo5cP4OfRSWqFwT7LM5/dNVwAg== pluginConfig: orchestrator: dataIndexService: url: http://sonataflow-platform-data-index-service - - package: "@redhat/backstage-plugin-orchestrator-form-widgets@1.6.0" + - package: "@redhat/backstage-plugin-orchestrator-form-widgets@1.7.1" disabled: true - integrity: sha512-Tqn6HO21Q1TQ7TFUoRhwBVCtSBzbQYz+OaanzzIB0R24O6YtVx3wR7Chtr5TzC05Vz5GkBO1+FZid8BKpqljgA== + integrity: sha512-0KIXrZoJ+O4xNNzN/zB4+VMuaRPuiUviAmM+fIhTo/P9aLA36F9aIlyMbUbki49uaJ0zd8KXMBvmJSHZNrYkGQ== pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-orchestrator-form-widgets: { } + + # Group: Adoption Insights - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-adoption-insights disabled: false pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-adoption-insights: + translationResources: + - importName: adoptionInsightsTranslations + ref: adoptionInsightsTranslationRef appIcons: - name: adoptionInsightsIcon importName: AdoptionInsightsIcon @@ -1245,9 +1383,10 @@ plugins: menuItem: icon: adoptionInsightsIcon text: Adoption Insights + textKey: menuItem.adoptionInsights menuItems: adoption-insights: - parent: admin + parent: default.admin icon: adoptionInsightsIcon - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-adoption-insights-backend-dynamic disabled: false diff --git a/dynamic-plugins/.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch b/dynamic-plugins/.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch deleted file mode 100644 index 0f5992befe..0000000000 --- a/dynamic-plugins/.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch +++ /dev/null @@ -1,133 +0,0 @@ -diff --git a/dist/index.d.ts b/dist/index.d.ts -index 3b8fbc1280529bb4a09fd46f543b66bfebe5d4b4..d00c8911f184d73e29a7667998dc252c1d045dfe 100644 ---- a/dist/index.d.ts -+++ b/dist/index.d.ts -@@ -133,7 +133,7 @@ type AuthResolverContext = { - * - * See {@link AuthResolverCatalogUserQuery} for details. - */ -- signInWithCatalogUser(query: AuthResolverCatalogUserQuery): Promise; -+ signInWithCatalogUser(query: AuthResolverCatalogUserQuery, fallbackUserRef?: string | undefined, dangerouslyAllowSignInWithoutUserInCatalog?: boolean | undefined): Promise; - }; - /** - * Resolver interface for resolving the ownership entity references for entity -@@ -772,13 +772,17 @@ declare namespace commonSignInResolvers { - * A common sign-in resolver that looks up the user using their email address - * as email of the entity. - */ -- const emailMatchingUserEntityProfileEmail: SignInResolverFactory; -+ const emailMatchingUserEntityProfileEmail: SignInResolverFactory; - /** - * A common sign-in resolver that looks up the user using the local part of - * their email address as the entity name. - */ - const emailLocalPartMatchingUserEntityName: SignInResolverFactory; - } - -diff --git a/dist/sign-in/commonSignInResolvers.cjs.js b/dist/sign-in/commonSignInResolvers.cjs.js -index 6ed45a5cfbbb2a7a3b4e1d0a72d7e5ac52e587e1..de48fe02fcae8843f5d8156a9e6da092aaecf6f4 100644 ---- a/dist/sign-in/commonSignInResolvers.cjs.js -+++ b/dist/sign-in/commonSignInResolvers.cjs.js -@@ -8,7 +8,11 @@ const reEmail = /^([^@+]+)(\+[^@]+)?(@.*)$/; - exports.commonSignInResolvers = void 0; - ((commonSignInResolvers2) => { - commonSignInResolvers2.emailMatchingUserEntityProfileEmail = createSignInResolverFactory.createSignInResolverFactory({ -- create() { -+ optionsSchema: zod.z.object({ -+ allowedDomains: zod.z.array(zod.z.string()).optional(), -+ dangerouslyAllowSignInWithoutUserInCatalog: zod.z.boolean().optional() -+ }).optional(), -+ create(options = {}) { - return async (info, ctx) => { - const { profile } = info; - if (!profile.email) { -@@ -17,22 +21,30 @@ exports.commonSignInResolvers = void 0; - ); - } - try { -- return await ctx.signInWithCatalogUser({ -- filter: { -- "spec.profile.email": profile.email -- } -- }); -+ return await ctx.signInWithCatalogUser( -+ { -+ filter: { -+ "spec.profile.email": profile.email -+ } -+ }, -+ profile.email, -+ options?.dangerouslyAllowSignInWithoutUserInCatalog -+ ); - } catch (err) { - if (err?.name === "NotFoundError") { - const m = profile.email.match(reEmail); - if (m?.length === 4) { - const [_, name, _plus, domain] = m; - const noPlusEmail = `${name}${domain}`; -- return ctx.signInWithCatalogUser({ -- filter: { -- "spec.profile.email": noPlusEmail -- } -- }); -+ return ctx.signInWithCatalogUser( -+ { -+ filter: { -+ "spec.profile.email": noPlusEmail -+ } -+ }, -+ noPlusEmail, -+ options?.dangerouslyAllowSignInWithoutUserInCatalog -+ ); - } - } - throw err; -@@ -42,7 +54,8 @@ exports.commonSignInResolvers = void 0; - }); - commonSignInResolvers2.emailLocalPartMatchingUserEntityName = createSignInResolverFactory.createSignInResolverFactory({ - optionsSchema: zod.z.object({ -- allowedDomains: zod.z.array(zod.z.string()).optional() -+ allowedDomains: zod.z.array(zod.z.string()).optional(), -+ dangerouslyAllowSignInWithoutUserInCatalog: zod.z.boolean().optional() - }).optional(), - create(options = {}) { - const { allowedDomains } = options; -@@ -60,9 +73,11 @@ exports.commonSignInResolvers = void 0; - "Sign-in user email is not from an allowed domain" - ); - } -- return ctx.signInWithCatalogUser({ -- entityRef: { name: localPart } -- }); -+ return ctx.signInWithCatalogUser( -+ { entityRef: { name: localPart } }, -+ localPart, -+ options?.dangerouslyAllowSignInWithoutUserInCatalog -+ ); - }; - } - }); -diff --git a/dist/sign-in/commonSignInResolvers.cjs.js.map b/dist/sign-in/commonSignInResolvers.cjs.js.map -index b46a3deb872536cabc10680830ba3e4f67c6782d..82592701870a8201f0a5f31c212724484b5289c2 100644 ---- a/dist/sign-in/commonSignInResolvers.cjs.js.map -+++ b/dist/sign-in/commonSignInResolvers.cjs.js.map -@@ -1 +1 @@ --{"version":3,"file":"commonSignInResolvers.cjs.js","sources":["../../src/sign-in/commonSignInResolvers.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from 'zod';\nimport { createSignInResolverFactory } from './createSignInResolverFactory';\nimport { NotAllowedError } from '@backstage/errors';\n\n// This splits an email \"joe+work@acme.com\" into [\"joe\", \"+work\", \"@acme.com\"]\n// so that we can remove the plus addressing. May output a shorter array:\n// [\"joe\", \"@acme.com\"], if no plus addressing was found.\nconst reEmail = /^([^@+]+)(\\+[^@]+)?(@.*)$/;\n\n/**\n * A collection of common sign-in resolvers that work with any auth provider.\n *\n * @public\n */\nexport namespace commonSignInResolvers {\n /**\n * A common sign-in resolver that looks up the user using their email address\n * as email of the entity.\n */\n export const emailMatchingUserEntityProfileEmail =\n createSignInResolverFactory({\n create() {\n return async (info, ctx) => {\n const { profile } = info;\n\n if (!profile.email) {\n throw new Error(\n 'Login failed, user profile does not contain an email',\n );\n }\n\n try {\n return await ctx.signInWithCatalogUser({\n filter: {\n 'spec.profile.email': profile.email,\n },\n });\n } catch (err) {\n if (err?.name === 'NotFoundError') {\n // Try removing the plus addressing from the email address\n const m = profile.email.match(reEmail);\n if (m?.length === 4) {\n const [_, name, _plus, domain] = m;\n const noPlusEmail = `${name}${domain}`;\n\n return ctx.signInWithCatalogUser({\n filter: {\n 'spec.profile.email': noPlusEmail,\n },\n });\n }\n }\n // Email had no plus addressing or is missing in the catalog, forward failure\n throw err;\n }\n };\n },\n });\n\n /**\n * A common sign-in resolver that looks up the user using the local part of\n * their email address as the entity name.\n */\n export const emailLocalPartMatchingUserEntityName =\n createSignInResolverFactory({\n optionsSchema: z\n .object({\n allowedDomains: z.array(z.string()).optional(),\n })\n .optional(),\n create(options = {}) {\n const { allowedDomains } = options;\n return async (info, ctx) => {\n const { profile } = info;\n\n if (!profile.email) {\n throw new Error(\n 'Login failed, user profile does not contain an email',\n );\n }\n const [localPart] = profile.email.split('@');\n const domain = profile.email.slice(localPart.length + 1);\n\n if (allowedDomains && !allowedDomains.includes(domain)) {\n throw new NotAllowedError(\n 'Sign-in user email is not from an allowed domain',\n );\n }\n\n return ctx.signInWithCatalogUser({\n entityRef: { name: localPart },\n });\n };\n },\n });\n}\n"],"names":["commonSignInResolvers","createSignInResolverFactory","z","NotAllowedError"],"mappings":";;;;;;AAuBA,MAAM,OAAU,GAAA,2BAAA;AAOCA;AAAA,CAAV,CAAUA,sBAAV,KAAA;AAKE,EAAMA,sBAAAA,CAAA,sCACXC,uDAA4B,CAAA;AAAA,IAC1B,MAAS,GAAA;AACP,MAAO,OAAA,OAAO,MAAM,GAAQ,KAAA;AAC1B,QAAM,MAAA,EAAE,SAAY,GAAA,IAAA;AAEpB,QAAI,IAAA,CAAC,QAAQ,KAAO,EAAA;AAClB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA;AAGF,QAAI,IAAA;AACF,UAAO,OAAA,MAAM,IAAI,qBAAsB,CAAA;AAAA,YACrC,MAAQ,EAAA;AAAA,cACN,sBAAsB,OAAQ,CAAA;AAAA;AAChC,WACD,CAAA;AAAA,iBACM,GAAK,EAAA;AACZ,UAAI,IAAA,GAAA,EAAK,SAAS,eAAiB,EAAA;AAEjC,YAAA,MAAM,CAAI,GAAA,OAAA,CAAQ,KAAM,CAAA,KAAA,CAAM,OAAO,CAAA;AACrC,YAAI,IAAA,CAAA,EAAG,WAAW,CAAG,EAAA;AACnB,cAAA,MAAM,CAAC,CAAA,EAAG,IAAM,EAAA,KAAA,EAAO,MAAM,CAAI,GAAA,CAAA;AACjC,cAAA,MAAM,WAAc,GAAA,CAAA,EAAG,IAAI,CAAA,EAAG,MAAM,CAAA,CAAA;AAEpC,cAAA,OAAO,IAAI,qBAAsB,CAAA;AAAA,gBAC/B,MAAQ,EAAA;AAAA,kBACN,oBAAsB,EAAA;AAAA;AACxB,eACD,CAAA;AAAA;AACH;AAGF,UAAM,MAAA,GAAA;AAAA;AACR,OACF;AAAA;AACF,GACD,CAAA;AAMI,EAAMD,sBAAAA,CAAA,uCACXC,uDAA4B,CAAA;AAAA,IAC1B,aAAA,EAAeC,MACZ,MAAO,CAAA;AAAA,MACN,gBAAgBA,KAAE,CAAA,KAAA,CAAMA,MAAE,MAAO,EAAC,EAAE,QAAS;AAAA,KAC9C,EACA,QAAS,EAAA;AAAA,IACZ,MAAA,CAAO,OAAU,GAAA,EAAI,EAAA;AACnB,MAAM,MAAA,EAAE,gBAAmB,GAAA,OAAA;AAC3B,MAAO,OAAA,OAAO,MAAM,GAAQ,KAAA;AAC1B,QAAM,MAAA,EAAE,SAAY,GAAA,IAAA;AAEpB,QAAI,IAAA,CAAC,QAAQ,KAAO,EAAA;AAClB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA;AAEF,QAAA,MAAM,CAAC,SAAS,CAAA,GAAI,OAAQ,CAAA,KAAA,CAAM,MAAM,GAAG,CAAA;AAC3C,QAAA,MAAM,SAAS,OAAQ,CAAA,KAAA,CAAM,KAAM,CAAA,SAAA,CAAU,SAAS,CAAC,CAAA;AAEvD,QAAA,IAAI,cAAkB,IAAA,CAAC,cAAe,CAAA,QAAA,CAAS,MAAM,CAAG,EAAA;AACtD,UAAA,MAAM,IAAIC,sBAAA;AAAA,YACR;AAAA,WACF;AAAA;AAGF,QAAA,OAAO,IAAI,qBAAsB,CAAA;AAAA,UAC/B,SAAA,EAAW,EAAE,IAAA,EAAM,SAAU;AAAA,SAC9B,CAAA;AAAA,OACH;AAAA;AACF,GACD,CAAA;AAAA,CAhFY,EAAAH,6BAAA,KAAAA,6BAAA,GAAA,EAAA,CAAA,CAAA;;"} -\ No newline at end of file -+{"version":3,"file":"commonSignInResolvers.cjs.js","sources":["../../src/sign-in/commonSignInResolvers.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from 'zod';\nimport { createSignInResolverFactory } from './createSignInResolverFactory';\nimport { NotAllowedError } from '@backstage/errors';\n\n// This splits an email \"joe+work@acme.com\" into [\"joe\", \"+work\", \"@acme.com\"]\n// so that we can remove the plus addressing. May output a shorter array:\n// [\"joe\", \"@acme.com\"], if no plus addressing was found.\nconst reEmail = /^([^@+]+)(\\+[^@]+)?(@.*)$/;\n\n/**\n * A collection of common sign-in resolvers that work with any auth provider.\n *\n * @public\n */\nexport namespace commonSignInResolvers {\n /**\n * A common sign-in resolver that looks up the user using their email address\n * as email of the entity.\n */\n export const emailMatchingUserEntityProfileEmail =\n createSignInResolverFactory({\n optionsSchema: z\n .object({\n allowedDomains: z.array(z.string()).optional(),\n dangerouslyAllowSignInWithoutUserInCatalog: z.boolean().optional(),\n })\n .optional(),\n create(options = {}) {\n return async (info, ctx) => {\n const { profile } = info;\n\n if (!profile.email) {\n throw new Error(\n 'Login failed, user profile does not contain an email',\n );\n }\n\n try {\n return await ctx.signInWithCatalogUser(\n {\n filter: {\n 'spec.profile.email': profile.email,\n },\n },\n profile.email,\n options?.dangerouslyAllowSignInWithoutUserInCatalog,\n );\n } catch (err) {\n if (err?.name === 'NotFoundError') {\n // Try removing the plus addressing from the email address\n const m = profile.email.match(reEmail);\n if (m?.length === 4) {\n const [_, name, _plus, domain] = m;\n const noPlusEmail = `${name}${domain}`;\n\n return ctx.signInWithCatalogUser(\n {\n filter: {\n 'spec.profile.email': noPlusEmail,\n },\n },\n noPlusEmail,\n options?.dangerouslyAllowSignInWithoutUserInCatalog,\n );\n }\n }\n // Email had no plus addressing or is missing in the catalog, forward failure\n throw err;\n }\n };\n },\n });\n\n /**\n * A common sign-in resolver that looks up the user using the local part of\n * their email address as the entity name.\n */\n export const emailLocalPartMatchingUserEntityName =\n createSignInResolverFactory({\n optionsSchema: z\n .object({\n allowedDomains: z.array(z.string()).optional(),\n dangerouslyAllowSignInWithoutUserInCatalog: z.boolean().optional(),\n })\n .optional(),\n create(options = {}) {\n const { allowedDomains } = options;\n return async (info, ctx) => {\n const { profile } = info;\n\n if (!profile.email) {\n throw new Error(\n 'Login failed, user profile does not contain an email',\n );\n }\n const [localPart] = profile.email.split('@');\n const domain = profile.email.slice(localPart.length + 1);\n\n if (allowedDomains && !allowedDomains.includes(domain)) {\n throw new NotAllowedError(\n 'Sign-in user email is not from an allowed domain',\n );\n }\n return ctx.signInWithCatalogUser(\n { entityRef: { name: localPart } },\n localPart,\n options?.dangerouslyAllowSignInWithoutUserInCatalog,\n );\n };\n },\n });\n}\n"],"names":["commonSignInResolvers","createSignInResolverFactory","z","NotAllowedError"],"mappings":";;;;;;AAuBA,MAAM,OAAU,GAAA,2BAAA;AAOCA;AAAA,CAAV,CAAUA,sBAAV,KAAA;AAKE,EAAMA,sBAAAA,CAAA,sCACXC,uDAA4B,CAAA;AAAA,IAC1B,aAAA,EAAeC,MACZ,MAAO,CAAA;AAAA,MACN,gBAAgBA,KAAE,CAAA,KAAA,CAAMA,MAAE,MAAO,EAAC,EAAE,QAAS,EAAA;AAAA,MAC7C,0CAA4C,EAAAA,KAAA,CAAE,OAAQ,EAAA,CAAE,QAAS;AAAA,KAClE,EACA,QAAS,EAAA;AAAA,IACZ,MAAA,CAAO,OAAU,GAAA,EAAI,EAAA;AACnB,MAAO,OAAA,OAAO,MAAM,GAAQ,KAAA;AAC1B,QAAM,MAAA,EAAE,SAAY,GAAA,IAAA;AAEpB,QAAI,IAAA,CAAC,QAAQ,KAAO,EAAA;AAClB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA;AAGF,QAAI,IAAA;AACF,UAAA,OAAO,MAAM,GAAI,CAAA,qBAAA;AAAA,YACf;AAAA,cACE,MAAQ,EAAA;AAAA,gBACN,sBAAsB,OAAQ,CAAA;AAAA;AAChC,aACF;AAAA,YACA,OAAQ,CAAA,KAAA;AAAA,YACR,OAAS,EAAA;AAAA,WACX;AAAA,iBACO,GAAK,EAAA;AACZ,UAAI,IAAA,GAAA,EAAK,SAAS,eAAiB,EAAA;AAEjC,YAAA,MAAM,CAAI,GAAA,OAAA,CAAQ,KAAM,CAAA,KAAA,CAAM,OAAO,CAAA;AACrC,YAAI,IAAA,CAAA,EAAG,WAAW,CAAG,EAAA;AACnB,cAAA,MAAM,CAAC,CAAA,EAAG,IAAM,EAAA,KAAA,EAAO,MAAM,CAAI,GAAA,CAAA;AACjC,cAAA,MAAM,WAAc,GAAA,CAAA,EAAG,IAAI,CAAA,EAAG,MAAM,CAAA,CAAA;AAEpC,cAAA,OAAO,GAAI,CAAA,qBAAA;AAAA,gBACT;AAAA,kBACE,MAAQ,EAAA;AAAA,oBACN,oBAAsB,EAAA;AAAA;AACxB,iBACF;AAAA,gBACA,WAAA;AAAA,gBACA,OAAS,EAAA;AAAA,eACX;AAAA;AACF;AAGF,UAAM,MAAA,GAAA;AAAA;AACR,OACF;AAAA;AACF,GACD,CAAA;AAMI,EAAMF,sBAAAA,CAAA,uCACXC,uDAA4B,CAAA;AAAA,IAC1B,aAAA,EAAeC,MACZ,MAAO,CAAA;AAAA,MACN,gBAAgBA,KAAE,CAAA,KAAA,CAAMA,MAAE,MAAO,EAAC,EAAE,QAAS,EAAA;AAAA,MAC7C,0CAA4C,EAAAA,KAAA,CAAE,OAAQ,EAAA,CAAE,QAAS;AAAA,KAClE,EACA,QAAS,EAAA;AAAA,IACZ,MAAA,CAAO,OAAU,GAAA,EAAI,EAAA;AACnB,MAAM,MAAA,EAAE,gBAAmB,GAAA,OAAA;AAC3B,MAAO,OAAA,OAAO,MAAM,GAAQ,KAAA;AAC1B,QAAM,MAAA,EAAE,SAAY,GAAA,IAAA;AAEpB,QAAI,IAAA,CAAC,QAAQ,KAAO,EAAA;AAClB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA;AAEF,QAAA,MAAM,CAAC,SAAS,CAAA,GAAI,OAAQ,CAAA,KAAA,CAAM,MAAM,GAAG,CAAA;AAC3C,QAAA,MAAM,SAAS,OAAQ,CAAA,KAAA,CAAM,KAAM,CAAA,SAAA,CAAU,SAAS,CAAC,CAAA;AAEvD,QAAA,IAAI,cAAkB,IAAA,CAAC,cAAe,CAAA,QAAA,CAAS,MAAM,CAAG,EAAA;AACtD,UAAA,MAAM,IAAIC,sBAAA;AAAA,YACR;AAAA,WACF;AAAA;AAEF,QAAA,OAAO,GAAI,CAAA,qBAAA;AAAA,UACT,EAAE,SAAA,EAAW,EAAE,IAAA,EAAM,WAAY,EAAA;AAAA,UACjC,SAAA;AAAA,UACA,OAAS,EAAA;AAAA,SACX;AAAA,OACF;AAAA;AACF,GACD,CAAA;AAAA,CAhGY,EAAAH,6BAAA,KAAAA,6BAAA,GAAA,EAAA,CAAA,CAAA;;"} -\ No newline at end of file -diff --git a/dist/types.cjs.js.map b/dist/types.cjs.js.map -index 79383794d01275a8e914db4749b71c303e68e7fd..f99613a6881f173e61998cf8ea3f99134382ea4d 100644 ---- a/dist/types.cjs.js.map -+++ b/dist/types.cjs.js.map -@@ -1 +1 @@ --{"version":3,"file":"types.cjs.js","sources":["../src/types.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { EntityFilterQuery } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { JsonValue } from '@backstage/types';\nimport { Request, Response } from 'express';\n\n/**\n * A representation of a successful Backstage sign-in.\n *\n * Compared to the {@link BackstageIdentityResponse} this type omits\n * the decoded identity information embedded in the token.\n *\n * @public\n */\nexport interface BackstageSignInResult {\n /**\n * The token used to authenticate the user within Backstage.\n */\n token: string;\n}\n\n/**\n * Response object containing the {@link BackstageUserIdentity} and the token\n * from the authentication provider.\n *\n * @public\n */\nexport interface BackstageIdentityResponse extends BackstageSignInResult {\n /**\n * The number of seconds until the token expires. If not set, it can be assumed that the token does not expire.\n */\n expiresInSeconds?: number;\n\n /**\n * A plaintext description of the identity that is encapsulated within the token.\n */\n identity: BackstageUserIdentity;\n}\n\n/**\n * User identity information within Backstage.\n *\n * @public\n */\nexport type BackstageUserIdentity = {\n /**\n * The type of identity that this structure represents. In the frontend app\n * this will currently always be 'user'.\n */\n type: 'user';\n\n /**\n * The entityRef of the user in the catalog.\n * For example User:default/sandra\n */\n userEntityRef: string;\n\n /**\n * The user and group entities that the user claims ownership through\n */\n ownershipEntityRefs: string[];\n};\n\n/**\n * A query for a single user in the catalog.\n *\n * If `entityRef` is used, the default kind is `'User'`.\n *\n * If `annotations` are used, all annotations must be present and\n * match the provided value exactly. Only entities of kind `'User'` will be considered.\n *\n * If `filter` are used, only entities of kind `'User'` will be considered unless it is explicitly specified differently in the filter.\n *\n * Regardless of the query method, the query must match exactly one entity\n * in the catalog, or an error will be thrown.\n *\n * @public\n */\nexport type AuthResolverCatalogUserQuery =\n | {\n entityRef:\n | string\n | {\n kind?: string;\n namespace?: string;\n name: string;\n };\n }\n | {\n annotations: Record;\n }\n | {\n filter: EntityFilterQuery;\n };\n\n/**\n * Parameters used to issue new Backstage Tokens\n *\n * @public\n */\nexport type TokenParams = {\n /**\n * The claims that will be embedded within the token. At a minimum, this should include\n * the subject claim, `sub`. It is common to also list entity ownership relations in the\n * `ent` list. Additional claims may also be added at the developer's discretion except\n * for the following list, which will be overwritten by the TokenIssuer: `iss`, `aud`,\n * `iat`, and `exp`. The Backstage team also maintains the right add new claims in the future\n * without listing the change as a \"breaking change\".\n */\n claims: {\n /** The token subject, i.e. User ID */\n sub: string;\n /** A list of entity references that the user claims ownership through */\n ent?: string[];\n } & Record;\n};\n\n/**\n * The context that is used for auth processing.\n *\n * @public\n */\nexport type AuthResolverContext = {\n /**\n * Issues a Backstage token using the provided parameters.\n */\n issueToken(params: TokenParams): Promise<{ token: string }>;\n\n /**\n * Finds a single user in the catalog using the provided query.\n *\n * See {@link AuthResolverCatalogUserQuery} for details.\n */\n findCatalogUser(\n query: AuthResolverCatalogUserQuery,\n ): Promise<{ entity: Entity }>;\n\n /**\n * Finds a single user in the catalog using the provided query, and then\n * issues an identity for that user using default ownership resolution.\n *\n * See {@link AuthResolverCatalogUserQuery} for details.\n */\n signInWithCatalogUser(\n query: AuthResolverCatalogUserQuery,\n ): Promise;\n};\n\n/**\n * Resolver interface for resolving the ownership entity references for entity\n *\n * @public\n */\nexport interface AuthOwnershipResolver {\n resolveOwnershipEntityRefs(\n entity: Entity,\n ): Promise<{ ownershipEntityRefs: string[] }>;\n}\n\n/**\n * Any Auth provider needs to implement this interface which handles the routes in the\n * auth backend. Any auth API requests from the frontend reaches these methods.\n *\n * The routes in the auth backend API are tied to these methods like below\n *\n * `/auth/[provider]/start -> start`\n * `/auth/[provider]/handler/frame -> frameHandler`\n * `/auth/[provider]/refresh -> refresh`\n * `/auth/[provider]/logout -> logout`\n *\n * @public\n */\nexport interface AuthProviderRouteHandlers {\n /**\n * Handles the start route of the API. This initiates a sign in request with an auth provider.\n *\n * Request\n * - scopes for the auth request (Optional)\n * Response\n * - redirect to the auth provider for the user to sign in or consent.\n * - sets a nonce cookie and also pass the nonce as 'state' query parameter in the redirect request\n */\n start(req: Request, res: Response): Promise;\n\n /**\n * Once the user signs in or consents in the OAuth screen, the auth provider redirects to the\n * callbackURL which is handled by this method.\n *\n * Request\n * - to contain a nonce cookie and a 'state' query parameter\n * Response\n * - postMessage to the window with a payload that contains accessToken, expiryInSeconds?, idToken? and scope.\n * - sets a refresh token cookie if the auth provider supports refresh tokens\n */\n frameHandler(req: Request, res: Response): Promise;\n\n /**\n * (Optional) If the auth provider supports refresh tokens then this method handles\n * requests to get a new access token.\n *\n * Other types of providers may also use this method to implement its own logic to create new sessions\n * upon request. For example, this can be used to create a new session for a provider that handles requests\n * from an authenticating proxy.\n *\n * Request\n * - to contain a refresh token cookie and scope (Optional) query parameter.\n * Response\n * - payload with accessToken, expiryInSeconds?, idToken?, scope and user profile information.\n */\n refresh?(req: Request, res: Response): Promise;\n\n /**\n * (Optional) Handles sign out requests\n *\n * Response\n * - removes the refresh token cookie\n */\n logout?(req: Request, res: Response): Promise;\n}\n\n/**\n * @public\n * @deprecated Use top-level properties passed to `AuthProviderFactory` instead\n */\nexport type AuthProviderConfig = {\n /**\n * The protocol://domain[:port] where the app is hosted. This is used to construct the\n * callbackURL to redirect to once the user signs in to the auth provider.\n */\n baseUrl: string;\n\n /**\n * The base URL of the app as provided by app.baseUrl\n */\n appUrl: string;\n\n /**\n * A function that is called to check whether an origin is allowed to receive the authentication result.\n */\n isOriginAllowed: (origin: string) => boolean;\n\n /**\n * The function used to resolve cookie configuration based on the auth provider options.\n */\n cookieConfigurer?: CookieConfigurer;\n};\n\n/** @public */\nexport type AuthProviderFactory = (options: {\n providerId: string;\n /** @deprecated Use top-level properties instead */\n globalConfig: AuthProviderConfig;\n config: Config;\n logger: LoggerService;\n resolverContext: AuthResolverContext;\n /**\n * The protocol://domain[:port] where the app is hosted. This is used to construct the\n * callbackURL to redirect to once the user signs in to the auth provider.\n */\n baseUrl: string;\n\n /**\n * The base URL of the app as provided by app.baseUrl\n */\n appUrl: string;\n\n /**\n * A function that is called to check whether an origin is allowed to receive the authentication result.\n */\n isOriginAllowed: (origin: string) => boolean;\n\n /**\n * The function used to resolve cookie configuration based on the auth provider options.\n */\n cookieConfigurer?: CookieConfigurer;\n}) => AuthProviderRouteHandlers;\n\n/** @public */\nexport type ClientAuthResponse = {\n providerInfo: TProviderInfo;\n profile: ProfileInfo;\n backstageIdentity?: BackstageIdentityResponse;\n};\n\n/**\n * Type of sign in information context. Includes the profile information and\n * authentication result which contains auth related information.\n *\n * @public\n */\nexport type SignInInfo = {\n /**\n * The simple profile passed down for use in the frontend.\n */\n profile: ProfileInfo;\n\n /**\n * The authentication result that was received from the authentication\n * provider.\n */\n result: TAuthResult;\n};\n\n/**\n * Describes the function which handles the result of a successful\n * authentication. Must return a valid {@link @backstage/plugin-auth-node#BackstageSignInResult}.\n *\n * @public\n */\nexport type SignInResolver = (\n info: SignInInfo,\n context: AuthResolverContext,\n) => Promise;\n\n/**\n * Describes the function that transforms the result of a successful\n * authentication into a {@link ProfileInfo} object.\n *\n * This function may optionally throw an error in order to reject authentication.\n *\n * @public\n */\nexport type ProfileTransform = (\n result: TResult,\n context: AuthResolverContext,\n) => Promise<{ profile: ProfileInfo }>;\n\n/**\n * Used to display login information to user, i.e. sidebar popup.\n *\n * It is also temporarily used as the profile of the signed-in user's Backstage\n * identity, but we want to replace that with data from identity and/org catalog\n * service\n *\n * @public\n */\nexport type ProfileInfo = {\n /**\n * Email ID of the signed in user.\n */\n email?: string;\n /**\n * Display name that can be presented to the signed in user.\n */\n displayName?: string;\n /**\n * URL to an image that can be used as the display image or avatar of the\n * signed in user.\n */\n picture?: string;\n};\n\n/**\n * The callback used to resolve the cookie configuration for auth providers that use cookies.\n * @public\n */\nexport type CookieConfigurer = (ctx: {\n /** ID of the auth provider that this configuration applies to */\n providerId: string;\n /** The externally reachable base URL of the auth-backend plugin */\n baseUrl: string;\n /** The configured callback URL of the auth provider */\n callbackUrl: string;\n /** The origin URL of the app */\n appOrigin: string;\n}) => {\n domain: string;\n path: string;\n secure: boolean;\n sameSite?: 'none' | 'lax' | 'strict';\n};\n\n/**\n * Core properties of various token types.\n *\n * @public\n */\nexport const tokenTypes = Object.freeze({\n user: Object.freeze({\n typParam: 'vnd.backstage.user',\n audClaim: 'backstage',\n }),\n limitedUser: Object.freeze({\n typParam: 'vnd.backstage.limited-user',\n }),\n plugin: Object.freeze({\n typParam: 'vnd.backstage.plugin',\n }),\n});\n"],"names":[],"mappings":";;AA0Ya,MAAA,UAAA,GAAa,OAAO,MAAO,CAAA;AAAA,EACtC,IAAA,EAAM,OAAO,MAAO,CAAA;AAAA,IAClB,QAAU,EAAA,oBAAA;AAAA,IACV,QAAU,EAAA;AAAA,GACX,CAAA;AAAA,EACD,WAAA,EAAa,OAAO,MAAO,CAAA;AAAA,IACzB,QAAU,EAAA;AAAA,GACX,CAAA;AAAA,EACD,MAAA,EAAQ,OAAO,MAAO,CAAA;AAAA,IACpB,QAAU,EAAA;AAAA,GACX;AACH,CAAC;;;;"} -\ No newline at end of file -+{"version":3,"file":"types.cjs.js","sources":["../src/types.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { EntityFilterQuery } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { JsonValue } from '@backstage/types';\nimport { Request, Response } from 'express';\n\n/**\n * A representation of a successful Backstage sign-in.\n *\n * Compared to the {@link BackstageIdentityResponse} this type omits\n * the decoded identity information embedded in the token.\n *\n * @public\n */\nexport interface BackstageSignInResult {\n /**\n * The token used to authenticate the user within Backstage.\n */\n token: string;\n}\n\n/**\n * Response object containing the {@link BackstageUserIdentity} and the token\n * from the authentication provider.\n *\n * @public\n */\nexport interface BackstageIdentityResponse extends BackstageSignInResult {\n /**\n * The number of seconds until the token expires. If not set, it can be assumed that the token does not expire.\n */\n expiresInSeconds?: number;\n\n /**\n * A plaintext description of the identity that is encapsulated within the token.\n */\n identity: BackstageUserIdentity;\n}\n\n/**\n * User identity information within Backstage.\n *\n * @public\n */\nexport type BackstageUserIdentity = {\n /**\n * The type of identity that this structure represents. In the frontend app\n * this will currently always be 'user'.\n */\n type: 'user';\n\n /**\n * The entityRef of the user in the catalog.\n * For example User:default/sandra\n */\n userEntityRef: string;\n\n /**\n * The user and group entities that the user claims ownership through\n */\n ownershipEntityRefs: string[];\n};\n\n/**\n * A query for a single user in the catalog.\n *\n * If `entityRef` is used, the default kind is `'User'`.\n *\n * If `annotations` are used, all annotations must be present and\n * match the provided value exactly. Only entities of kind `'User'` will be considered.\n *\n * If `filter` are used, only entities of kind `'User'` will be considered unless it is explicitly specified differently in the filter.\n *\n * Regardless of the query method, the query must match exactly one entity\n * in the catalog, or an error will be thrown.\n *\n * @public\n */\nexport type AuthResolverCatalogUserQuery =\n | {\n entityRef:\n | string\n | {\n kind?: string;\n namespace?: string;\n name: string;\n };\n }\n | {\n annotations: Record;\n }\n | {\n filter: EntityFilterQuery;\n };\n\n/**\n * Parameters used to issue new Backstage Tokens\n *\n * @public\n */\nexport type TokenParams = {\n /**\n * The claims that will be embedded within the token. At a minimum, this should include\n * the subject claim, `sub`. It is common to also list entity ownership relations in the\n * `ent` list. Additional claims may also be added at the developer's discretion except\n * for the following list, which will be overwritten by the TokenIssuer: `iss`, `aud`,\n * `iat`, and `exp`. The Backstage team also maintains the right add new claims in the future\n * without listing the change as a \"breaking change\".\n */\n claims: {\n /** The token subject, i.e. User ID */\n sub: string;\n /** A list of entity references that the user claims ownership through */\n ent?: string[];\n } & Record;\n};\n\n/**\n * The context that is used for auth processing.\n *\n * @public\n */\nexport type AuthResolverContext = {\n /**\n * Issues a Backstage token using the provided parameters.\n */\n issueToken(params: TokenParams): Promise<{ token: string }>;\n\n /**\n * Finds a single user in the catalog using the provided query.\n *\n * See {@link AuthResolverCatalogUserQuery} for details.\n */\n findCatalogUser(\n query: AuthResolverCatalogUserQuery,\n ): Promise<{ entity: Entity }>;\n\n /**\n * Finds a single user in the catalog using the provided query, and then\n * issues an identity for that user using default ownership resolution.\n *\n * See {@link AuthResolverCatalogUserQuery} for details.\n */\n signInWithCatalogUser(\n query: AuthResolverCatalogUserQuery,\n fallbackUserRef?: string | undefined,\n dangerouslyAllowSignInWithoutUserInCatalog?: boolean | undefined,\n ): Promise;\n};\n\n/**\n * Resolver interface for resolving the ownership entity references for entity\n *\n * @public\n */\nexport interface AuthOwnershipResolver {\n resolveOwnershipEntityRefs(\n entity: Entity,\n ): Promise<{ ownershipEntityRefs: string[] }>;\n}\n\n/**\n * Any Auth provider needs to implement this interface which handles the routes in the\n * auth backend. Any auth API requests from the frontend reaches these methods.\n *\n * The routes in the auth backend API are tied to these methods like below\n *\n * `/auth/[provider]/start -> start`\n * `/auth/[provider]/handler/frame -> frameHandler`\n * `/auth/[provider]/refresh -> refresh`\n * `/auth/[provider]/logout -> logout`\n *\n * @public\n */\nexport interface AuthProviderRouteHandlers {\n /**\n * Handles the start route of the API. This initiates a sign in request with an auth provider.\n *\n * Request\n * - scopes for the auth request (Optional)\n * Response\n * - redirect to the auth provider for the user to sign in or consent.\n * - sets a nonce cookie and also pass the nonce as 'state' query parameter in the redirect request\n */\n start(req: Request, res: Response): Promise;\n\n /**\n * Once the user signs in or consents in the OAuth screen, the auth provider redirects to the\n * callbackURL which is handled by this method.\n *\n * Request\n * - to contain a nonce cookie and a 'state' query parameter\n * Response\n * - postMessage to the window with a payload that contains accessToken, expiryInSeconds?, idToken? and scope.\n * - sets a refresh token cookie if the auth provider supports refresh tokens\n */\n frameHandler(req: Request, res: Response): Promise;\n\n /**\n * (Optional) If the auth provider supports refresh tokens then this method handles\n * requests to get a new access token.\n *\n * Other types of providers may also use this method to implement its own logic to create new sessions\n * upon request. For example, this can be used to create a new session for a provider that handles requests\n * from an authenticating proxy.\n *\n * Request\n * - to contain a refresh token cookie and scope (Optional) query parameter.\n * Response\n * - payload with accessToken, expiryInSeconds?, idToken?, scope and user profile information.\n */\n refresh?(req: Request, res: Response): Promise;\n\n /**\n * (Optional) Handles sign out requests\n *\n * Response\n * - removes the refresh token cookie\n */\n logout?(req: Request, res: Response): Promise;\n}\n\n/**\n * @public\n * @deprecated Use top-level properties passed to `AuthProviderFactory` instead\n */\nexport type AuthProviderConfig = {\n /**\n * The protocol://domain[:port] where the app is hosted. This is used to construct the\n * callbackURL to redirect to once the user signs in to the auth provider.\n */\n baseUrl: string;\n\n /**\n * The base URL of the app as provided by app.baseUrl\n */\n appUrl: string;\n\n /**\n * A function that is called to check whether an origin is allowed to receive the authentication result.\n */\n isOriginAllowed: (origin: string) => boolean;\n\n /**\n * The function used to resolve cookie configuration based on the auth provider options.\n */\n cookieConfigurer?: CookieConfigurer;\n};\n\n/** @public */\nexport type AuthProviderFactory = (options: {\n providerId: string;\n /** @deprecated Use top-level properties instead */\n globalConfig: AuthProviderConfig;\n config: Config;\n logger: LoggerService;\n resolverContext: AuthResolverContext;\n /**\n * The protocol://domain[:port] where the app is hosted. This is used to construct the\n * callbackURL to redirect to once the user signs in to the auth provider.\n */\n baseUrl: string;\n\n /**\n * The base URL of the app as provided by app.baseUrl\n */\n appUrl: string;\n\n /**\n * A function that is called to check whether an origin is allowed to receive the authentication result.\n */\n isOriginAllowed: (origin: string) => boolean;\n\n /**\n * The function used to resolve cookie configuration based on the auth provider options.\n */\n cookieConfigurer?: CookieConfigurer;\n}) => AuthProviderRouteHandlers;\n\n/** @public */\nexport type ClientAuthResponse = {\n providerInfo: TProviderInfo;\n profile: ProfileInfo;\n backstageIdentity?: BackstageIdentityResponse;\n};\n\n/**\n * Type of sign in information context. Includes the profile information and\n * authentication result which contains auth related information.\n *\n * @public\n */\nexport type SignInInfo = {\n /**\n * The simple profile passed down for use in the frontend.\n */\n profile: ProfileInfo;\n\n /**\n * The authentication result that was received from the authentication\n * provider.\n */\n result: TAuthResult;\n};\n\n/**\n * Describes the function which handles the result of a successful\n * authentication. Must return a valid {@link @backstage/plugin-auth-node#BackstageSignInResult}.\n *\n * @public\n */\nexport type SignInResolver = (\n info: SignInInfo,\n context: AuthResolverContext,\n) => Promise;\n\n/**\n * Describes the function that transforms the result of a successful\n * authentication into a {@link ProfileInfo} object.\n *\n * This function may optionally throw an error in order to reject authentication.\n *\n * @public\n */\nexport type ProfileTransform = (\n result: TResult,\n context: AuthResolverContext,\n) => Promise<{ profile: ProfileInfo }>;\n\n/**\n * Used to display login information to user, i.e. sidebar popup.\n *\n * It is also temporarily used as the profile of the signed-in user's Backstage\n * identity, but we want to replace that with data from identity and/org catalog\n * service\n *\n * @public\n */\nexport type ProfileInfo = {\n /**\n * Email ID of the signed in user.\n */\n email?: string;\n /**\n * Display name that can be presented to the signed in user.\n */\n displayName?: string;\n /**\n * URL to an image that can be used as the display image or avatar of the\n * signed in user.\n */\n picture?: string;\n};\n\n/**\n * The callback used to resolve the cookie configuration for auth providers that use cookies.\n * @public\n */\nexport type CookieConfigurer = (ctx: {\n /** ID of the auth provider that this configuration applies to */\n providerId: string;\n /** The externally reachable base URL of the auth-backend plugin */\n baseUrl: string;\n /** The configured callback URL of the auth provider */\n callbackUrl: string;\n /** The origin URL of the app */\n appOrigin: string;\n}) => {\n domain: string;\n path: string;\n secure: boolean;\n sameSite?: 'none' | 'lax' | 'strict';\n};\n\n/**\n * Core properties of various token types.\n *\n * @public\n */\nexport const tokenTypes = Object.freeze({\n user: Object.freeze({\n typParam: 'vnd.backstage.user',\n audClaim: 'backstage',\n }),\n limitedUser: Object.freeze({\n typParam: 'vnd.backstage.limited-user',\n }),\n plugin: Object.freeze({\n typParam: 'vnd.backstage.plugin',\n }),\n});\n"],"names":[],"mappings":";;AA4Ya,MAAA,UAAA,GAAa,OAAO,MAAO,CAAA;AAAA,EACtC,IAAA,EAAM,OAAO,MAAO,CAAA;AAAA,IAClB,QAAU,EAAA,oBAAA;AAAA,IACV,QAAU,EAAA;AAAA,GACX,CAAA;AAAA,EACD,WAAA,EAAa,OAAO,MAAO,CAAA;AAAA,IACzB,QAAU,EAAA;AAAA,GACX,CAAA;AAAA,EACD,MAAA,EAAQ,OAAO,MAAO,CAAA;AAAA,IACpB,QAAU,EAAA;AAAA,GACX;AACH,CAAC;;;;"} -\ No newline at end of file diff --git a/dynamic-plugins/_utils/package.json b/dynamic-plugins/_utils/package.json index 410060e786..0e7c3657ed 100644 --- a/dynamic-plugins/_utils/package.json +++ b/dynamic-plugins/_utils/package.json @@ -12,8 +12,8 @@ "test": "backstage-cli package test --passWithNoTests --coverage" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "glob": "11.0.3", - "yaml": "2.8.0" + "yaml": "2.8.1" } } diff --git a/dynamic-plugins/backstage.json b/dynamic-plugins/backstage.json new file mode 100644 index 0000000000..6c12971cc4 --- /dev/null +++ b/dynamic-plugins/backstage.json @@ -0,0 +1,3 @@ +{ + "version": "1.42.5" +} diff --git a/dynamic-plugins/package.json b/dynamic-plugins/package.json index 4d53bfa4d5..d56aad6269 100644 --- a/dynamic-plugins/package.json +++ b/dynamic-plugins/package.json @@ -1,6 +1,6 @@ { "name": "dynamic-plugins-root", - "version": "1.7.0", + "version": "1.8.0", "private": true, "engines": { "node": "22" @@ -23,22 +23,15 @@ ] }, "devDependencies": { - "turbo": "2.5.4" + "@backstage/cli": "^0.34.1", + "turbo": "2.5.8" }, "resolutions": { "@types/react": "18.3.23", "@types/react-dom": "18.3.7", - "@rjsf/utils": "=5.24.12", "@aws-sdk/util-utf8-browser": "npm:@smithy/util-utf8@~2", "@kubernetes/client-node@npm:0.20.0/jsonpath-plus": "^10.3.0", - "@backstage/plugin-auth-node@^0.6.0": "patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch", - "@backstage/plugin-auth-node@0.6.0": "patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch", - "@backstage/plugin-auth-node@^0.5.6": "patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch", - "@backstage/plugin-auth-node@^0.5.1": "patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch", - "@backstage/plugin-auth-node@^0.4.17": "patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch", - "@backstage/plugin-auth-node@^0.4.13": "patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch", - "@backstage/plugin-auth-node@^0.5.2": "patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch", - "@backstage/plugin-auth-node@^0.4.16": "patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch", + "@backstage/plugin-auth-node": "0.6.6", "@backstage/plugin-scaffolder-node@^0.2.9": "^0.7.0" }, "packageManager": "yarn@3.8.7" diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-3scale-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-3scale-backend-dynamic/package.json index 292ef9d4da..82c4cfa817 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-3scale-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-3scale-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-3scale-backend", - "version": "3.6.1", + "version": "3.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "backstage-community-plugin-3scale-backend", "pluginPackages": [ "backstage-community-plugin-3scale-backend" @@ -38,12 +38,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-3scale-backend": "3.6.1" + "@backstage-community/plugin-3scale-backend": "3.8.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-acr/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-acr/package.json index 00543b28b3..ed5284a6cd 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-acr/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-acr/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-acr", - "version": "1.15.1", + "version": "1.17.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "acr", "pluginPackages": [ "backstage-community-plugin-acr" @@ -28,15 +28,15 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-acr": "1.15.1", - "@backstage/core-plugin-api": "1.10.7", + "@backstage-community/plugin-acr": "1.17.0", + "@backstage/core-plugin-api": "1.10.9", "@mui/icons-material": "5.18.0", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-analytics-provider-segment/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-analytics-provider-segment/package.json index 81798de0b7..f35a4c1423 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-analytics-provider-segment/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-analytics-provider-segment/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-analytics-provider-segment", - "version": "1.16.0", + "version": "1.18.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "backstage-community-analytics-provider-segment", "pluginPackages": [ "backstage-community-plugin-analytics-provider-segment" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-analytics-provider-segment": "1.16.0" + "@backstage-community/plugin-analytics-provider-segment": "1.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-azure-devops-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-azure-devops-backend-dynamic/package.json index 36b7e0f166..1856e3084a 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-azure-devops-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-azure-devops-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-azure-devops-backend", - "version": "0.17.1", + "version": "0.19.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "azure-devops", "pluginPackage": "backstage-community-plugin-azure-devops-backend", "pluginPackages": [ @@ -40,12 +40,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-azure-devops-backend": "0.17.1" + "@backstage-community/plugin-azure-devops-backend": "0.19.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-azure-devops/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-azure-devops/package.json index 6ee91d28a1..d3c3ed1bd0 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-azure-devops/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-azure-devops", - "version": "0.16.1", + "version": "0.18.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "azure-devops", "pluginPackage": "backstage-community-plugin-azure-devops", "pluginPackages": [ @@ -30,12 +30,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-azure-devops": "0.16.1" + "@backstage-community/plugin-azure-devops": "0.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-keycloak-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-keycloak-dynamic/package.json index 37ad0b58f8..5ceed9166e 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-keycloak-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-keycloak-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-catalog-backend-module-keycloak", - "version": "3.12.1", + "version": "3.14.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-catalog-backend-module-keycloak": "3.12.1" + "@backstage-community/plugin-catalog-backend-module-keycloak": "3.14.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic/package.json index 9501842abe..1004297f22 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-catalog-backend-module-pingidentity", - "version": "0.5.0", + "version": "0.7.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-catalog-backend-module-pingidentity": "0.5.0" + "@backstage-community/plugin-catalog-backend-module-pingidentity": "0.7.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic/package.json index 7c3ca6abe2..66fe3f098f 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor", - "version": "2.5.0", + "version": "2.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -32,16 +32,16 @@ "test": "backstage-cli package test --passWithNoTests --coverage", "clean": "backstage-cli package clean", "clean-dynamic-sources": "yarn clean && rm -Rf node_modules", - "export-dynamic": "janus-cli package export-dynamic-plugin --embed-package @backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor", + "export-dynamic": "janus-cli package export-dynamic-plugin --embed-package @backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor @backstage/plugin-notifications-node", "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor": "2.5.0" + "@backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor": "2.8.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-dynatrace/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-dynatrace/package.json index a1460b8ea7..af2169133e 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-dynatrace/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-dynatrace", - "version": "10.6.0", + "version": "10.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "dynatrace", "pluginPackages": [ "backstage-community-plugin-dynatrace" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-dynatrace": "10.6.0" + "@backstage-community/plugin-dynatrace": "10.8.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-github-actions/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-github-actions/package.json index 00a2656001..59ccc4fc36 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-github-actions/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-github-actions/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-github-actions", - "version": "0.11.1", + "version": "0.14.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "github-actions", "pluginPackages": [ "backstage-community-plugin-github-actions" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-github-actions": "0.11.1" + "@backstage-community/plugin-github-actions": "0.14.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-github-issues/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-github-issues/package.json index 8383fc5084..a5051eff8a 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-github-issues/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-github-issues/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-github-issues", - "version": "0.10.0", + "version": "0.13.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "github-issues", "pluginPackages": [ "backstage-community-plugin-github-issues" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-github-issues": "0.10.0" + "@backstage-community/plugin-github-issues": "0.13.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-jenkins-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-jenkins-backend-dynamic/package.json index 2a85dbe7da..20e21fbb7b 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-jenkins-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-jenkins-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-jenkins-backend", - "version": "0.15.0", + "version": "0.17.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "jenkins", "pluginPackages": [ "backstage-community-plugin-jenkins", @@ -39,12 +39,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-jenkins-backend": "0.15.0" + "@backstage-community/plugin-jenkins-backend": "0.17.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-jenkins/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-jenkins/package.json index 1b5f7485b6..8c3a8a3d37 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-jenkins/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-jenkins/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-jenkins", - "version": "0.20.0", + "version": "0.22.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "jenkins", "pluginPackages": [ "backstage-community-plugin-jenkins", @@ -29,12 +29,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-jenkins": "0.20.0" + "@backstage-community/plugin-jenkins": "0.22.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-jfrog-artifactory/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-jfrog-artifactory/package.json index b71b09c4dc..e58a58c99f 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-jfrog-artifactory/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-jfrog-artifactory/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-jfrog-artifactory", - "version": "1.15.3", + "version": "1.18.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "jfrog-artifactory", "pluginPackage": "backstage-community-plugin-jfrog-artifactory", "pluginPackages": [ @@ -29,13 +29,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-jfrog-artifactory": "1.15.3", + "@backstage-community/plugin-jfrog-artifactory": "1.18.2", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-lighthouse/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-lighthouse/package.json index 4ed7deb581..8afa964fb4 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-lighthouse/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-lighthouse/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-lighthouse", - "version": "0.10.0", + "version": "0.12.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "lighthouse", "pluginPackages": [ "backstage-community-plugin-lighthouse" @@ -28,13 +28,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-lighthouse": "0.10.0", + "@backstage-community/plugin-lighthouse": "0.12.0", "@mui/icons-material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-nexus-repository-manager/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-nexus-repository-manager/package.json index 063d0783fb..05b2c278fe 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-nexus-repository-manager/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-nexus-repository-manager/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-nexus-repository-manager", - "version": "1.14.1", + "version": "1.16.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "nexus-repository-manager", "pluginPackages": [ "backstage-community-plugin-nexus-repository-manager" @@ -27,13 +27,13 @@ "export-dynamic": "janus-cli package export-dynamic-plugin --in-place" }, "dependencies": { - "@backstage-community/plugin-nexus-repository-manager": "1.14.1", + "@backstage-community/plugin-nexus-repository-manager": "1.16.0", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-ocm-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-ocm-backend-dynamic/package.json index aed2ab53de..a878f7925a 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-ocm-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-ocm-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-ocm-backend", - "version": "5.7.0", + "version": "5.9.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "backstage-community-ocm-backend", "pluginPackages": [ "backstage-community-plugin-ocm-backend" @@ -38,12 +38,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-ocm-backend": "5.7.0" + "@backstage-community/plugin-ocm-backend": "5.9.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -63,6 +63,6 @@ "bugs": "https://issues.redhat.com/browse/RHIDP", "keywords": [ "support:production", - "lifecycle:active" + "lifecycle:deprecated" ] } diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-ocm/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-ocm/package.json index 0abd0304cc..c5d9662b10 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-ocm/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-ocm/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-ocm", - "version": "5.6.0", + "version": "5.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "backstage-community-plugin-ocm", "pluginPackages": [ "backstage-community-plugin-ocm" @@ -28,13 +28,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-ocm": "5.6.0", + "@backstage-community/plugin-ocm": "5.8.0", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -59,6 +59,6 @@ "bugs": "https://issues.redhat.com/browse/RHIDP", "keywords": [ "support:production", - "lifecycle:active" + "lifecycle:deprecated" ] } diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-quay/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-quay/package.json index 1f4ac40322..e51febaf42 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-quay/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-quay/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-quay", - "version": "1.21.1", + "version": "1.24.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "backstage-community-quay", "pluginPackage": "backstage-community-quay", "pluginPackages": [ @@ -29,13 +29,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-quay": "1.21.1", + "@backstage-community/plugin-quay": "1.24.0", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-rbac/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-rbac/package.json index fc9d65e1de..4487387cf8 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-rbac/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-rbac/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-rbac", - "version": "1.42.0", + "version": "1.45.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,13 +11,28 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "rbac", "pluginPackages": [ "backstage-community-plugin-rbac" ] }, "sideEffects": false, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } + }, "scripts": { "tsc": "tsc", "build": "backstage-cli package build", @@ -28,13 +43,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-rbac": "1.42.0", + "@backstage-community/plugin-rbac": "1.45.1", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -43,7 +58,8 @@ "scalprum": { "name": "backstage-community.plugin-rbac", "exposedModules": { - "PluginRoot": "./src/index.ts" + "PluginRoot": "./src/index.ts", + "Alpha": "./src/alpha.ts" } }, "repository": { diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-rbac/src/alpha.ts b/dynamic-plugins/wrappers/backstage-community-plugin-rbac/src/alpha.ts new file mode 100644 index 0000000000..a1aca0bc99 --- /dev/null +++ b/dynamic-plugins/wrappers/backstage-community-plugin-rbac/src/alpha.ts @@ -0,0 +1 @@ +export * from '@backstage-community/plugin-rbac/alpha'; diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-redhat-argocd/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-redhat-argocd/package.json index 7b7c2294f3..1c932bf657 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-redhat-argocd/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-redhat-argocd/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-redhat-argocd", - "version": "1.21.2", + "version": "2.0.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "redhat-argocd", "pluginPackages": [ "backstage-community-plugin-redhat-argocd" @@ -18,10 +18,14 @@ }, "exports": { ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, "typesVersions": { "*": { + "alpha": [ + "src/alpha.ts" + ], "package.json": [ "package.json" ] @@ -39,13 +43,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-redhat-argocd": "1.21.2", + "@backstage-community/plugin-redhat-argocd": "2.0.0", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -54,7 +58,8 @@ "scalprum": { "name": "backstage-community.plugin-redhat-argocd", "exposedModules": { - "PluginRoot": "./src/index.ts" + "PluginRoot": "./src/index.ts", + "Alpha": "./src/alpha.ts" } }, "repository": { diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-redhat-argocd/src/alpha.ts b/dynamic-plugins/wrappers/backstage-community-plugin-redhat-argocd/src/alpha.ts new file mode 100644 index 0000000000..fa33c4fd4a --- /dev/null +++ b/dynamic-plugins/wrappers/backstage-community-plugin-redhat-argocd/src/alpha.ts @@ -0,0 +1 @@ +export * from '@backstage-community/plugin-redhat-argocd/alpha'; diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-kubernetes-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-kubernetes-dynamic/package.json index 49b4269ed8..f07d5bc720 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-kubernetes-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-kubernetes-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-scaffolder-backend-module-kubernetes", - "version": "2.8.1", + "version": "2.10.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-scaffolder-backend-module-kubernetes": "2.8.1" + "@backstage-community/plugin-scaffolder-backend-module-kubernetes": "2.10.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-quay-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-quay-dynamic/package.json index 51a4633bca..5b2b60e165 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-quay-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-quay-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-scaffolder-backend-module-quay", - "version": "2.9.1", + "version": "2.11.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-scaffolder-backend-module-quay": "2.9.1" + "@backstage-community/plugin-scaffolder-backend-module-quay": "2.11.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-regex-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-regex-dynamic/package.json index cccbf4b803..2c92118a2f 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-regex-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-regex-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-scaffolder-backend-module-regex", - "version": "2.7.0", + "version": "2.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-scaffolder-backend-module-regex": "2.7.0" + "@backstage-community/plugin-scaffolder-backend-module-regex": "2.8.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic/package.json index e02983e7c2..ffe73b89b1 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-scaffolder-backend-module-servicenow", - "version": "2.7.0", + "version": "2.8.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,7 +36,7 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-scaffolder-backend-module-servicenow": "2.7.0" + "@backstage-community/plugin-scaffolder-backend-module-servicenow": "2.8.1" }, "files": [ "dist", @@ -59,8 +59,8 @@ "lifecycle:active" ], "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" } } diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic/package.json index 3924753425..7c98b6da4f 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-scaffolder-backend-module-sonarqube", - "version": "2.7.1", + "version": "2.8.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-scaffolder-backend-module-sonarqube": "2.7.1" + "@backstage-community/plugin-scaffolder-backend-module-sonarqube": "2.8.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-sonarqube-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-sonarqube-backend-dynamic/package.json index 7c714827e8..1abb23fa87 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-sonarqube-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-sonarqube-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-sonarqube-backend", - "version": "0.9.2", + "version": "0.12.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "sonarqube", "pluginPackages": [ "backstage-community-plugin-sonarqube", @@ -39,12 +39,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-sonarqube-backend": "0.9.2" + "@backstage-community/plugin-sonarqube-backend": "0.12.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-sonarqube/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-sonarqube/package.json index f995352bc9..f3cf92d089 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-sonarqube/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-sonarqube/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-sonarqube", - "version": "0.13.0", + "version": "0.18.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "sonarqube", "pluginPackages": [ "backstage-community-plugin-sonarqube", @@ -29,12 +29,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-sonarqube": "0.13.0" + "@backstage-community/plugin-sonarqube": "0.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-tech-radar-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-tech-radar-backend-dynamic/package.json index 18d91a8234..37445261e4 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-tech-radar-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-tech-radar-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-tech-radar-backend", - "version": "1.6.0", + "version": "1.10.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -14,7 +14,7 @@ "backstage-community-plugin-tech-radar", "backstage-community-plugin-tech-radar-backend" ], - "supported-versions": "1.39.1" + "supported-versions": "1.42.5" }, "exports": { ".": "./src/index.ts", @@ -39,12 +39,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-tech-radar-backend": "1.6.0" + "@backstage-community/plugin-tech-radar-backend": "1.9.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-tech-radar/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-tech-radar/package.json index fab8eca390..dfb2020372 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-tech-radar/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-tech-radar/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-tech-radar", - "version": "1.7.0", + "version": "1.11.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "tech-radar", "pluginPackages": [ "backstage-community-plugin-tech-radar", @@ -29,15 +29,15 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-tech-radar": "1.7.0", - "@backstage-community/plugin-tech-radar-common": "1.6.0", - "@backstage/core-plugin-api": "1.10.7", + "@backstage-community/plugin-tech-radar": "1.11.0", + "@backstage-community/plugin-tech-radar-common": "1.10.0", + "@backstage/core-plugin-api": "1.10.9", "@mui/icons-material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-tekton/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-tekton/package.json index 3f3c473ba2..e7245ec906 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-tekton/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-tekton/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-tekton", - "version": "3.26.2", + "version": "3.29.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "tekton", "pluginPackages": [ "backstage-community-plugin-tekton" @@ -28,13 +28,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-tekton": "3.26.2", + "@backstage-community/plugin-tekton": "3.29.0", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-topology/package.json b/dynamic-plugins/wrappers/backstage-community-plugin-topology/package.json index 55d73bac3c..fe23c89d9e 100644 --- a/dynamic-plugins/wrappers/backstage-community-plugin-topology/package.json +++ b/dynamic-plugins/wrappers/backstage-community-plugin-topology/package.json @@ -1,6 +1,6 @@ { "name": "backstage-community-plugin-topology", - "version": "2.2.2", + "version": "2.7.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "topology", "pluginPackages": [ "backstage-community-plugin-topology" @@ -18,10 +18,14 @@ }, "exports": { ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, "typesVersions": { "*": { + "alpha": [ + "src/alpha.ts" + ], "package.json": [ "package.json" ] @@ -39,13 +43,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage-community/plugin-topology": "2.2.2", + "@backstage-community/plugin-topology": "2.7.0", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -54,7 +58,8 @@ "scalprum": { "name": "backstage-community.plugin-topology", "exposedModules": { - "PluginRoot": "./src/index.ts" + "PluginRoot": "./src/index.ts", + "Alpha": "./src/alpha.ts" } }, "repository": { diff --git a/dynamic-plugins/wrappers/backstage-community-plugin-topology/src/alpha.ts b/dynamic-plugins/wrappers/backstage-community-plugin-topology/src/alpha.ts new file mode 100644 index 0000000000..f67e36c5bf --- /dev/null +++ b/dynamic-plugins/wrappers/backstage-community-plugin-topology/src/alpha.ts @@ -0,0 +1 @@ +export * from "@backstage-community/plugin-topology/alpha"; diff --git a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic/package.json index b03a6fcba0..e4ebfa3694 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-catalog-backend-module-bitbucket-cloud", - "version": "0.4.8", + "version": "0.5.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.4.8" + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.5.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic/package.json index 3dc46d1acc..6a1fb0ec8e 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-catalog-backend-module-bitbucket-server", - "version": "0.4.1", + "version": "0.5.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.4.1" + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.5.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-github-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-github-dynamic/package.json index e7d305e113..013855de2d 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-github-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-github-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-catalog-backend-module-github", - "version": "0.9.0", + "version": "0.10.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-catalog-backend-module-github": "0.9.0" + "@backstage/plugin-catalog-backend-module-github": "0.10.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-github-org-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-github-org-dynamic/package.json index ff27e7f49e..dee9e2eb65 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-github-org-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-github-org-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-catalog-backend-module-github-org", - "version": "0.3.10", + "version": "0.3.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,13 +36,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-catalog-backend-module-github": "0.9.0", - "@backstage/plugin-catalog-backend-module-github-org": "0.3.10" + "@backstage/plugin-catalog-backend-module-github": "0.10.2", + "@backstage/plugin-catalog-backend-module-github-org": "0.3.13" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-gitlab-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-gitlab-dynamic/package.json index 828c139cac..76e720092f 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-gitlab-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-gitlab-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-catalog-backend-module-gitlab", - "version": "0.6.6", + "version": "0.7.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-catalog-backend-module-gitlab": "0.6.6" + "@backstage/plugin-catalog-backend-module-gitlab": "0.7.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-gitlab-org-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-gitlab-org-dynamic/package.json index b542d68973..a22e06c626 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-gitlab-org-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-gitlab-org-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-catalog-backend-module-gitlab-org", - "version": "0.2.9", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,13 +36,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-catalog-backend-module-gitlab": "0.6.6", - "@backstage/plugin-catalog-backend-module-gitlab-org": "0.2.9" + "@backstage/plugin-catalog-backend-module-gitlab": "0.7.2", + "@backstage/plugin-catalog-backend-module-gitlab-org": "0.2.12" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-ldap-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-ldap-dynamic/package.json index 5ddc543315..10f64d7286 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-ldap-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-ldap-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-catalog-backend-module-ldap", - "version": "0.11.5", + "version": "0.11.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-catalog-backend-module-ldap": "0.11.5" + "@backstage/plugin-catalog-backend-module-ldap": "0.11.8" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-msgraph-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-msgraph-dynamic/package.json index 3c8ed22a94..10e960e0d9 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-msgraph-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-catalog-backend-module-msgraph-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-catalog-backend-module-msgraph", - "version": "0.7.0", + "version": "0.7.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-catalog-backend-module-msgraph": "0.7.0" + "@backstage/plugin-catalog-backend-module-msgraph": "0.7.3" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -60,7 +60,7 @@ "homepage": "https://red.ht/rhdh", "bugs": "https://issues.redhat.com/browse/RHIDP", "keywords": [ - "support:tech-preview", + "support:production", "lifecycle:active" ] } diff --git a/dynamic-plugins/wrappers/backstage-plugin-kubernetes-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-kubernetes-backend-dynamic/package.json index 113531609a..3ace6140ab 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-kubernetes-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-kubernetes-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-kubernetes-backend", - "version": "0.19.6", + "version": "0.20.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "kubernetes", "pluginPackages": [ "backstage-plugin-kubernetes", @@ -39,12 +39,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-kubernetes-backend": "0.19.6" + "@backstage/plugin-kubernetes-backend": "0.20.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-kubernetes-backend-dynamic/src/index.ts b/dynamic-plugins/wrappers/backstage-plugin-kubernetes-backend-dynamic/src/index.ts index 27fc2c940d..80845110ac 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-kubernetes-backend-dynamic/src/index.ts +++ b/dynamic-plugins/wrappers/backstage-plugin-kubernetes-backend-dynamic/src/index.ts @@ -1 +1 @@ -export { default } from '@backstage/plugin-kubernetes-backend/alpha'; +export { default } from '@backstage/plugin-kubernetes-backend'; diff --git a/dynamic-plugins/wrappers/backstage-plugin-kubernetes/package.json b/dynamic-plugins/wrappers/backstage-plugin-kubernetes/package.json index 6859aa3649..8fc55c19da 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-kubernetes/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-kubernetes", - "version": "0.12.7", + "version": "0.12.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "kubernetes", "pluginPackages": [ "backstage-plugin-kubernetes", @@ -29,13 +29,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/core-plugin-api": "1.10.7", - "@backstage/plugin-kubernetes": "0.12.7" + "@backstage/core-plugin-api": "1.10.9", + "@backstage/plugin-kubernetes": "0.12.10" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-notifications-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-notifications-backend-dynamic/package.json index e5bc550560..71341634a1 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-notifications-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-notifications-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-notifications-backend", - "version": "0.5.6", + "version": "0.5.9", "main": "./dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "notifications", "pluginPackages": [ "backstage-plugin-notifications", @@ -40,13 +40,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-notifications-backend": "0.5.6", - "@backstage/plugin-signals-node": "0.1.20" + "@backstage/plugin-notifications-backend": "0.5.9", + "@backstage/plugin-signals-node": "0.1.23" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-notifications-backend-module-email-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-notifications-backend-module-email-dynamic/package.json index e1611564a0..3c18bdddf9 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-notifications-backend-module-email-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-notifications-backend-module-email-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-notifications-backend-module-email", - "version": "0.3.9", + "version": "0.3.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -9,7 +9,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "notifications", "pluginPackage": "@backstage/plugin-notifications-backend" }, @@ -35,12 +35,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-notifications-backend-module-email": "0.3.9" + "@backstage/plugin-notifications-backend-module-email": "0.3.12" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-notifications/package.json b/dynamic-plugins/wrappers/backstage-plugin-notifications/package.json index 011f4ccb86..412d4d18ac 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-notifications/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-notifications/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-notifications", - "version": "0.5.5", + "version": "0.5.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "notifications", "pluginPackages": [ "backstage-plugin-notifications", @@ -29,13 +29,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-notifications": "0.5.5", + "@backstage/plugin-notifications": "0.5.9", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-azure-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-azure-dynamic/package.json index 106489be77..ddb38955a6 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-azure-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-azure-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-scaffolder-backend-module-azure", - "version": "0.2.9", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-scaffolder-backend-module-azure": "0.2.9" + "@backstage/plugin-scaffolder-backend-module-azure": "0.2.12" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic/package.json index c91b90bd36..65ecef7a1c 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-scaffolder-backend-module-bitbucket-cloud", - "version": "0.2.9", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.9" + "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.12" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic/package.json index 594c373608..cb8ef999be 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-scaffolder-backend-module-bitbucket-server", - "version": "0.2.9", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.9" + "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.12" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-gerrit-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-gerrit-dynamic/package.json index 9113b215c3..89911c5a52 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-gerrit-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-gerrit-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-scaffolder-backend-module-gerrit", - "version": "0.2.9", + "version": "0.2.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.9" + "@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.12" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-github-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-github-dynamic/package.json index de3ebf416f..d1b1e6b7be 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-github-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-github-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-scaffolder-backend-module-github", - "version": "0.7.1", + "version": "0.8.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-scaffolder-backend-module-github": "0.7.1" + "@backstage/plugin-scaffolder-backend-module-github": "0.8.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-gitlab-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-gitlab-dynamic/package.json index b27028b36e..690a9e85a2 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-gitlab-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-scaffolder-backend-module-gitlab-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-scaffolder-backend-module-gitlab", - "version": "0.9.1", + "version": "0.9.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-scaffolder-backend-module-gitlab": "0.9.1" + "@backstage/plugin-scaffolder-backend-module-gitlab": "0.9.4" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-signals-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-signals-backend-dynamic/package.json index f9067a8e65..69d6486fd8 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-signals-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-signals-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-signals-backend", - "version": "0.3.4", + "version": "0.3.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -9,7 +9,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "signals", "pluginPackages": [ "backstage-plugin-signals", @@ -38,12 +38,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-signals-backend": "0.3.4" + "@backstage/plugin-signals-backend": "0.3.7" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-signals/package.json b/dynamic-plugins/wrappers/backstage-plugin-signals/package.json index 647c921a06..072306df8c 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-signals/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-signals/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-signals", - "version": "0.0.19", + "version": "0.0.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "signals", "pluginPackages": [ "backstage-plugin-signals", @@ -29,13 +29,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-signals": "0.0.19", + "@backstage/plugin-signals": "0.0.22", "@mui/material": "5.18.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-techdocs-backend-dynamic/package.json b/dynamic-plugins/wrappers/backstage-plugin-techdocs-backend-dynamic/package.json index c7abd3e5ed..23a7a9d4a9 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-techdocs-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-techdocs-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-techdocs-backend", - "version": "2.0.2", + "version": "2.0.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "techdocs", "pluginPackages": [ "backstage-plugin-techdocs", @@ -39,14 +39,14 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/backend-plugin-api": "1.3.1", - "@backstage/plugin-search-backend-module-techdocs": "0.4.2", - "@backstage/plugin-techdocs-backend": "2.0.2" + "@backstage/backend-plugin-api": "1.4.2", + "@backstage/plugin-search-backend-module-techdocs": "0.4.5", + "@backstage/plugin-techdocs-backend": "2.0.5" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-techdocs-module-addons-contrib/package.json b/dynamic-plugins/wrappers/backstage-plugin-techdocs-module-addons-contrib/package.json index 0521a239e6..6ef0c2f99e 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-techdocs-module-addons-contrib/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-techdocs-module-addons-contrib/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-techdocs-module-addons-contrib", - "version": "1.1.24", + "version": "1.1.27", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "techdocs", "pluginPackage": "backstage-plugin-techdocs" }, @@ -26,8 +26,8 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/plugin-techdocs-module-addons-contrib": "1.1.24", - "@backstage/plugin-techdocs-react": "1.2.17", + "@backstage/plugin-techdocs-module-addons-contrib": "1.1.27", + "@backstage/plugin-techdocs-react": "1.3.2", "@material-ui/core": "4.12.4", "jss": "10.10.0" }, @@ -35,10 +35,10 @@ "react": "16.13.1 || ^17.0.0 || ^18.0.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", "react": "18.3.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/backstage-plugin-techdocs/package.json b/dynamic-plugins/wrappers/backstage-plugin-techdocs/package.json index 142729341c..021cb426ac 100644 --- a/dynamic-plugins/wrappers/backstage-plugin-techdocs/package.json +++ b/dynamic-plugins/wrappers/backstage-plugin-techdocs/package.json @@ -1,6 +1,6 @@ { "name": "backstage-plugin-techdocs", - "version": "1.12.6", + "version": "1.14.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "techdocs", "pluginPackages": [ "backstage-plugin-techdocs", @@ -29,20 +29,20 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/core-plugin-api": "1.10.7", - "@backstage/plugin-catalog-react": "1.18.0", - "@backstage/plugin-search-react": "1.9.0", - "@backstage/plugin-techdocs": "1.12.6", - "@backstage/plugin-techdocs-react": "1.2.17" + "@backstage/core-plugin-api": "1.10.9", + "@backstage/plugin-catalog-react": "1.20.1", + "@backstage/plugin-search-react": "1.9.3", + "@backstage/plugin-techdocs": "1.14.1", + "@backstage/plugin-techdocs-react": "1.3.2" }, "peerDependencies": { "react": "16.13.1 || ^17.0.0 || ^18.0.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", "react": "18.3.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/immobiliarelabs-backstage-plugin-gitlab-backend-dynamic/package.json b/dynamic-plugins/wrappers/immobiliarelabs-backstage-plugin-gitlab-backend-dynamic/package.json index b6219a8158..0a7d49b569 100644 --- a/dynamic-plugins/wrappers/immobiliarelabs-backstage-plugin-gitlab-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/immobiliarelabs-backstage-plugin-gitlab-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "immobiliarelabs-backstage-plugin-gitlab-backend", - "version": "6.12.0", + "version": "6.13.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "immobiliarelabs-gitlab", "pluginPackages": [ "immobiliarelabs-backstage-plugin-gitlab", @@ -39,13 +39,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@backstage/backend-plugin-api": "1.3.0", - "@immobiliarelabs/backstage-plugin-gitlab-backend": "6.12.0" + "@backstage/backend-plugin-api": "1.4.2", + "@immobiliarelabs/backstage-plugin-gitlab-backend": "6.13.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/immobiliarelabs-backstage-plugin-gitlab/package.json b/dynamic-plugins/wrappers/immobiliarelabs-backstage-plugin-gitlab/package.json index d3acb6d81c..bb49e5652b 100644 --- a/dynamic-plugins/wrappers/immobiliarelabs-backstage-plugin-gitlab/package.json +++ b/dynamic-plugins/wrappers/immobiliarelabs-backstage-plugin-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "immobiliarelabs-backstage-plugin-gitlab", - "version": "6.12.0", + "version": "6.13.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "immobiliarelabs-gitlab", "pluginPackages": [ "immobiliarelabs-backstage-plugin-gitlab", @@ -29,12 +29,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@immobiliarelabs/backstage-plugin-gitlab": "6.12.0" + "@immobiliarelabs/backstage-plugin-gitlab": "6.13.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/pagerduty-backstage-plugin-backend-dynamic/package.json b/dynamic-plugins/wrappers/pagerduty-backstage-plugin-backend-dynamic/package.json index 0167c6d3c4..859a324739 100644 --- a/dynamic-plugins/wrappers/pagerduty-backstage-plugin-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/pagerduty-backstage-plugin-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "pagerduty-backstage-plugin-backend", - "version": "0.9.6", + "version": "0.9.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "pagerduty", "pluginPackages": [ "pagerduty-backstage-plugin", @@ -39,12 +39,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@pagerduty/backstage-plugin-backend": "0.9.6" + "@pagerduty/backstage-plugin-backend": "0.9.11" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "resolutions": { "@types/react": "18.3.23", diff --git a/dynamic-plugins/wrappers/pagerduty-backstage-plugin/package.json b/dynamic-plugins/wrappers/pagerduty-backstage-plugin/package.json index bac347d22b..69943dd552 100644 --- a/dynamic-plugins/wrappers/pagerduty-backstage-plugin/package.json +++ b/dynamic-plugins/wrappers/pagerduty-backstage-plugin/package.json @@ -1,6 +1,6 @@ { "name": "pagerduty-backstage-plugin", - "version": "0.15.5", + "version": "0.16.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "pagerduty", "pluginPackages": [ "pagerduty-backstage-plugin", @@ -29,12 +29,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@pagerduty/backstage-plugin": "0.15.5" + "@pagerduty/backstage-plugin": "0.16.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/parfuemerie-douglas-scaffolder-backend-module-azure-repositories-dynamic/package.json b/dynamic-plugins/wrappers/parfuemerie-douglas-scaffolder-backend-module-azure-repositories-dynamic/package.json index 2b26641077..7e52e3e697 100644 --- a/dynamic-plugins/wrappers/parfuemerie-douglas-scaffolder-backend-module-azure-repositories-dynamic/package.json +++ b/dynamic-plugins/wrappers/parfuemerie-douglas-scaffolder-backend-module-azure-repositories-dynamic/package.json @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -39,9 +39,9 @@ "@parfuemerie-douglas/scaffolder-backend-module-azure-repositories": "0.3.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights-backend-dynamic/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights-backend-dynamic/package.json index a2e24348d8..cbdea83ef6 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-adoption-insights-backend", - "version": "0.2.2", + "version": "0.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-adoption-insights-backend", "pluginPackages": [ "red-hat-developer-hub-backstage-plugin-adoption-insights", @@ -38,13 +38,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@red-hat-developer-hub/backstage-plugin-adoption-insights-backend": "0.2.2", - "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": "0.3.0" + "@red-hat-developer-hub/backstage-plugin-adoption-insights-backend": "0.3.0", + "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": "0.4.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -63,7 +63,7 @@ "homepage": "https://red.ht/rhdh", "bugs": "https://issues.redhat.com/browse/RHIDP", "keywords": [ - "support:tech-preview", + "support:production", "lifecycle:active" ] } diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights/package.json index a08f1b3f05..9384d5f354 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-adoption-insights", - "version": "0.2.1", + "version": "0.3.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-adoption-insights", "pluginPackages": [ "red-hat-developer-hub-backstage-plugin-adoption-insights", @@ -30,12 +30,12 @@ }, "dependencies": { "@mui/material": "5.18.0", - "@red-hat-developer-hub/backstage-plugin-adoption-insights": "0.2.1" + "@red-hat-developer-hub/backstage-plugin-adoption-insights": "0.3.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "app-config.dynamic.yaml", diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights-dynamic/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights-dynamic/package.json index 00bd32dd1f..4f5a92d15a 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights-dynamic/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights", - "version": "0.2.0", + "version": "0.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "frontend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights", "pluginPackage": "@redhat-developer-hub/backstage-plugin-analytics-module-adoption-insights" }, @@ -42,13 +42,13 @@ } }, "dependencies": { - "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": "0.3.0", - "@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights": "0.2.0" + "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": "0.4.0", + "@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights": "0.3.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -68,7 +68,7 @@ "homepage": "https://red.ht/rhdh", "bugs": "https://issues.redhat.com/browse/RHIDP", "keywords": [ - "support:tech-preview", + "support:production", "lifecycle:active" ] } diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic/package.json index ab3e4956d3..4761a4afc0 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-bulk-import-backend", - "version": "6.1.3", + "version": "6.5.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-bulk-import-backend", "pluginPackages": [ "red-hat-developer-hub-backstage-plugin-bulk-import", @@ -39,12 +39,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@red-hat-developer-hub/backstage-plugin-bulk-import-backend": "6.1.3" + "@red-hat-developer-hub/backstage-plugin-bulk-import-backend": "6.5.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import/package.json index 5a7241b569..b4e4e1efb2 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import/package.json @@ -1,17 +1,30 @@ { "name": "red-hat-developer-hub-backstage-plugin-bulk-import", - "version": "1.13.3", + "version": "1.18.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-bulk-import", "pluginPackages": [ "red-hat-developer-hub-backstage-plugin-bulk-import", @@ -30,12 +43,12 @@ }, "dependencies": { "@mui/material": "5.18.0", - "@red-hat-developer-hub/backstage-plugin-bulk-import": "1.13.3" + "@red-hat-developer-hub/backstage-plugin-bulk-import": "1.18.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -44,7 +57,8 @@ "scalprum": { "name": "red-hat-developer-hub.backstage-plugin-bulk-import", "exposedModules": { - "PluginRoot": "./src/index.ts" + "PluginRoot": "./src/index.ts", + "Alpha": "./src/alpha.ts" } }, "repository": { diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import/src/alpha.ts b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import/src/alpha.ts new file mode 100644 index 0000000000..1d0154d342 --- /dev/null +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-bulk-import/src/alpha.ts @@ -0,0 +1 @@ +export * from '@red-hat-developer-hub/backstage-plugin-bulk-import/alpha'; diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic/package.json index d3d496d881..75db9e0efc 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace", - "version": "0.3.3", + "version": "0.7.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "catalog", "pluginPackage": "@backstage/plugin-catalog-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace": "0.3.3" + "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace": "0.7.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page/package.json index 8051fce0ef..89dfea045d 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-dynamic-home-page", - "version": "1.5.0", + "version": "1.9.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-dynamic-home-page", "pluginPackages": [ "red-hat-developer-hub-backstage-plugin-dynamic-home-page" @@ -29,12 +29,12 @@ }, "dependencies": { "@mui/material": "5.18.0", - "@red-hat-developer-hub/backstage-plugin-dynamic-home-page": "1.5.0" + "@red-hat-developer-hub/backstage-plugin-dynamic-home-page": "1.9.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-floating-action-button/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-floating-action-button/package.json index 2aec83b941..36a529edf7 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-floating-action-button/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-floating-action-button/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-global-floating-action-button", - "version": "1.2.1", + "version": "1.5.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-global-floating-action-button", "pluginPackages": [ "red-hat-developer-hub-backstage-plugin-global-floating-action-button" @@ -29,12 +29,12 @@ }, "dependencies": { "@mui/material": "5.18.0", - "@red-hat-developer-hub/backstage-plugin-global-floating-action-button": "1.2.1" + "@red-hat-developer-hub/backstage-plugin-global-floating-action-button": "1.5.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "scalprum": { "name": "red-hat-developer-hub.backstage-plugin-global-floating-action-button", diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-header/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-header/package.json index 7246f30ac3..efdec80541 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-header/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-global-header/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-global-header", - "version": "1.14.0", + "version": "1.18.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-global-header", "pluginPackages": [ "red-hat-developer-hub-backstage-plugin-global-header" @@ -29,12 +29,12 @@ }, "dependencies": { "@mui/material": "5.18.0", - "@red-hat-developer-hub/backstage-plugin-global-header": "1.14.0" + "@red-hat-developer-hub/backstage-plugin-global-header": "1.18.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic/package.json index 0c293bd62a..c9067a43d0 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-marketplace-backend", - "version": "0.6.0", + "version": "0.11.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-marketplace-backend", "pluginPackages": [ "red-hat-developer-hub-backstage-plugin-marketplace", @@ -39,13 +39,13 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@red-hat-developer-hub/backstage-plugin-marketplace-backend": "0.6.0", - "@red-hat-developer-hub/backstage-plugin-marketplace-common": "0.6.0" + "@red-hat-developer-hub/backstage-plugin-marketplace-backend": "0.11.0", + "@red-hat-developer-hub/backstage-plugin-marketplace-common": "0.10.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace/package.json index 41920012b4..be7d26f593 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace/package.json @@ -1,17 +1,30 @@ { "name": "red-hat-developer-hub-backstage-plugin-marketplace", - "version": "0.7.0", + "version": "0.11.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-marketplace", "pluginPackages": [ "@red-hat-developer-hub/backstage-plugin-marketplace", @@ -30,12 +43,12 @@ }, "dependencies": { "@mui/material": "5.18.0", - "@red-hat-developer-hub/backstage-plugin-marketplace": "0.7.0" + "@red-hat-developer-hub/backstage-plugin-marketplace": "0.11.4" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "app-config.dynamic.yaml", @@ -45,7 +58,8 @@ "scalprum": { "name": "red-hat-developer-hub.backstage-plugin-marketplace", "exposedModules": { - "PluginRoot": "./src/index.ts" + "PluginRoot": "./src/index.ts", + "Alpha": "./src/alpha.ts" } }, "repository": { diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace/src/alpha.ts b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace/src/alpha.ts new file mode 100644 index 0000000000..d0fc600ef1 --- /dev/null +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-marketplace/src/alpha.ts @@ -0,0 +1 @@ +export * from "@red-hat-developer-hub/backstage-plugin-marketplace/alpha"; diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/package.json b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/package.json index 6e10a6b3c6..e4feb16599 100644 --- a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/package.json +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/package.json @@ -1,6 +1,6 @@ { "name": "red-hat-developer-hub-backstage-plugin-quickstart", - "version": "1.1.0", + "version": "1.6.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -9,9 +9,24 @@ "main": "dist/index.cjs.js", "types": "dist/index.d.ts" }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } + }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "red-hat-developer-hub-backstage-plugin-quickstart", "pluginPackages": [ "@red-hat-developer-hub/backstage-plugin-quickstart" @@ -29,12 +44,12 @@ }, "dependencies": { "@mui/material": "5.18.0", - "@red-hat-developer-hub/backstage-plugin-quickstart": "1.1.0" + "@red-hat-developer-hub/backstage-plugin-quickstart": "1.6.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", @@ -43,7 +58,8 @@ "scalprum": { "name": "red-hat-developer-hub.backstage-plugin-quickstart", "exposedModules": { - "PluginRoot": "./src/index.ts" + "PluginRoot": "./src/index.ts", + "Alpha": "./src/alpha.ts" } }, "repository": { diff --git a/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/src/alpha.ts b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/src/alpha.ts new file mode 100644 index 0000000000..cbbf96805b --- /dev/null +++ b/dynamic-plugins/wrappers/red-hat-developer-hub-backstage-plugin-quickstart/src/alpha.ts @@ -0,0 +1 @@ +export * from "@red-hat-developer-hub/backstage-plugin-quickstart/alpha"; diff --git a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic/package.json b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic/package.json index a322dfc301..83601bdb7c 100644 --- a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic/package.json +++ b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-backstage-plugin-argo-cd-backend", - "version": "4.3.1", + "version": "4.4.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "roadiehq-argo-cd", "pluginPackages": [ "roadiehq-backstage-plugin-argo-cd", @@ -39,12 +39,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/backstage-plugin-argo-cd-backend": "4.3.1" + "@roadiehq/backstage-plugin-argo-cd-backend": "4.4.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic/src/index.ts b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic/src/index.ts index 4835ebcebe..e2993e3d5a 100644 --- a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic/src/index.ts +++ b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic/src/index.ts @@ -1 +1 @@ -export { default } from "@roadiehq/backstage-plugin-argo-cd-backend/alpha"; +export { default } from "@roadiehq/backstage-plugin-argo-cd-backend"; diff --git a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-datadog/package.json b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-datadog/package.json index 1a6a3d20db..51e5a0d899 100644 --- a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-datadog/package.json +++ b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-datadog/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-backstage-plugin-datadog", - "version": "2.4.3", + "version": "2.5.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "roadiehq-datadog", "pluginPackages": [ "roadiehq-backstage-plugin-datadog" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/backstage-plugin-datadog": "2.4.3" + "@roadiehq/backstage-plugin-datadog": "2.5.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-github-insights/package.json b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-github-insights/package.json index fda94d54d8..0db5191a94 100644 --- a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-github-insights/package.json +++ b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-github-insights/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-backstage-plugin-github-insights", - "version": "3.1.4", + "version": "3.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "roadiehq-github-insights", "pluginPackages": [ "roadiehq-backstage-plugin-github-insights" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/backstage-plugin-github-insights": "3.1.4" + "@roadiehq/backstage-plugin-github-insights": "3.2.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-github-pull-requests/package.json b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-github-pull-requests/package.json index b11e19fc0c..5d721921df 100644 --- a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-github-pull-requests/package.json +++ b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-github-pull-requests/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-backstage-plugin-github-pull-requests", - "version": "3.4.2", + "version": "3.5.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "roadiehq-github-pull-requests", "pluginPackages": [ "roadiehq-backstage-plugin-github-pull-requests" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/backstage-plugin-github-pull-requests": "3.4.2" + "@roadiehq/backstage-plugin-github-pull-requests": "3.5.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-jira/package.json b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-jira/package.json index 1215625e0c..f6b2234674 100644 --- a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-jira/package.json +++ b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-jira/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-backstage-plugin-jira", - "version": "2.9.0", + "version": "2.13.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "roadiehq-jira", "pluginPackages": [ "roadiehq-backstage-plugin-jira" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/backstage-plugin-jira": "2.9.0" + "@roadiehq/backstage-plugin-jira": "2.13.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-security-insights/package.json b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-security-insights/package.json index a2e7c2e234..0eb40e4ebf 100644 --- a/dynamic-plugins/wrappers/roadiehq-backstage-plugin-security-insights/package.json +++ b/dynamic-plugins/wrappers/roadiehq-backstage-plugin-security-insights/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-backstage-plugin-security-insights", - "version": "3.1.3", + "version": "3.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -11,7 +11,7 @@ }, "backstage": { "role": "frontend-plugin", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "roadiehq-security-insights", "pluginPackages": [ "roadiehq-backstage-plugin-security-insights" @@ -28,12 +28,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/backstage-plugin-security-insights": "3.1.3" + "@roadiehq/backstage-plugin-security-insights": "3.2.0" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-argocd-dynamic/package.json b/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-argocd-dynamic/package.json index 41ffcf5874..c47d638f93 100644 --- a/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-argocd-dynamic/package.json +++ b/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-argocd-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-scaffolder-backend-argocd", - "version": "1.6.0", + "version": "1.7.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/scaffolder-backend-argocd": "1.6.0" + "@roadiehq/scaffolder-backend-argocd": "1.7.1" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-module-http-request-dynamic/package.json b/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-module-http-request-dynamic/package.json index b9f59161f5..815089d243 100644 --- a/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-module-http-request-dynamic/package.json +++ b/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-module-http-request-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-scaffolder-backend-module-http-request", - "version": "5.3.3", + "version": "5.4.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/scaffolder-backend-module-http-request": "5.3.3" + "@roadiehq/scaffolder-backend-module-http-request": "5.4.2" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-module-utils-dynamic/package.json b/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-module-utils-dynamic/package.json index 0a73815f0d..da0c624795 100644 --- a/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-module-utils-dynamic/package.json +++ b/dynamic-plugins/wrappers/roadiehq-scaffolder-backend-module-utils-dynamic/package.json @@ -1,6 +1,6 @@ { "name": "roadiehq-scaffolder-backend-module-utils", - "version": "3.5.0", + "version": "4.0.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -10,7 +10,7 @@ }, "backstage": { "role": "backend-plugin-module", - "supported-versions": "1.39.1", + "supported-versions": "1.42.5", "pluginId": "scaffolder", "pluginPackage": "@backstage/plugin-scaffolder-backend" }, @@ -36,12 +36,12 @@ "export-dynamic:clean": "run export-dynamic --clean" }, "dependencies": { - "@roadiehq/scaffolder-backend-module-utils": "3.5.0" + "@roadiehq/scaffolder-backend-module-utils": "4.0.3" }, "devDependencies": { - "@backstage/cli": "0.30.0", + "@backstage/cli": "^0.34.1", "@janus-idp/cli": "3.6.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist", diff --git a/dynamic-plugins/yarn.lock b/dynamic-plugins/yarn.lock index 141e0f939b..f65ede8c38 100644 --- a/dynamic-plugins/yarn.lock +++ b/dynamic-plugins/yarn.lock @@ -61,14 +61,14 @@ __metadata: languageName: node linkType: hard -"@apidevtools/json-schema-ref-parser@npm:^12.0.1": - version: 12.0.2 - resolution: "@apidevtools/json-schema-ref-parser@npm:12.0.2" +"@apidevtools/json-schema-ref-parser@npm:^14.0.3": + version: 14.2.0 + resolution: "@apidevtools/json-schema-ref-parser@npm:14.2.0" dependencies: - "@jsdevtools/ono": ^7.1.3 - "@types/json-schema": ^7.0.15 js-yaml: ^4.1.0 - checksum: b5b4df8adad66d9529a98a3c2513abdd7da5da889b82062dc55248697a908eba1d8f91a78c1a2cde782d23392bdbd7ae6e2ce0bbf829098e1ff3b15c82e8daea + peerDependencies: + "@types/json-schema": ^7.0.15 + checksum: fff43815d0957718b0e66c066944396a9f30e312516d60a0ce3eb4d8f6f8833bdeca059565b0e1a35da89645e4123bd5357249effe04997dc40b4e8b3a0f6981 languageName: node linkType: hard @@ -1709,17 +1709,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.8.3": - version: 7.25.9 - resolution: "@babel/code-frame@npm:7.25.9" - dependencies: - "@babel/highlight": ^7.25.9 - picocolors: ^1.0.0 - checksum: 458015f42f130bc70a19aaf016eaabb51e8c6508feb65394115972621bf864c2cc6b07ee547b1d95e2fde958e14243f79a4d0223ef6d52963820cafcf6fcf11b - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.27.1": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.8.3": version: 7.27.1 resolution: "@babel/code-frame@npm:7.27.1" dependencies: @@ -1985,13 +1975,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-string-parser@npm:7.25.9" - checksum: 6435ee0849e101681c1849868278b5aee82686ba2c1e27280e5e8aca6233af6810d39f8e4e693d2f2a44a3728a6ccfd66f72d71826a94105b86b731697cdfa99 - languageName: node - linkType: hard - "@babel/helper-string-parser@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-string-parser@npm:7.27.1" @@ -1999,14 +1982,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.24.7, @babel/helper-validator-identifier@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-validator-identifier@npm:7.25.9" - checksum: 5b85918cb1a92a7f3f508ea02699e8d2422fe17ea8e82acd445006c0ef7520fbf48e3dbcdaf7b0a1d571fc3a2715a29719e5226636cb6042e15fe6ed2a590944 - languageName: node - linkType: hard - -"@babel/helper-validator-identifier@npm:^7.27.1": +"@babel/helper-validator-identifier@npm:^7.24.7, @babel/helper-validator-identifier@npm:^7.25.9, @babel/helper-validator-identifier@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-validator-identifier@npm:7.27.1" checksum: 3c7e8391e59d6c85baeefe9afb86432f2ab821c6232b00ea9082a51d3e7e95a2f3fb083d74dc1f49ac82cf238e1d2295dafcb001f7b0fab479f3f56af5eaaa47 @@ -2042,7 +2018,7 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.0.0, @babel/highlight@npm:^7.25.9": +"@babel/highlight@npm:^7.0.0": version: 7.25.9 resolution: "@babel/highlight@npm:7.25.9" dependencies: @@ -2054,18 +2030,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.5": - version: 7.26.5 - resolution: "@babel/parser@npm:7.26.5" - dependencies: - "@babel/types": ^7.26.5 - bin: - parser: ./bin/babel-parser.js - checksum: 663aebf27c1dc04813e6c1d6e8e8fcb2954163ec297a95bdb3f1d0c2a0f04b504bddc09588fe4b176b43fad28c8a4b2914838a1edffdd426537a42f3ac644f1e - languageName: node - linkType: hard - -"@babel/parser@npm:^7.27.2": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.5, @babel/parser@npm:^7.27.2": version: 7.28.0 resolution: "@babel/parser@npm:7.28.0" dependencies: @@ -3160,34 +3125,14 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.6, @babel/runtime@npm:^7.24.8, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.27.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.27.0 - resolution: "@babel/runtime@npm:7.27.0" - dependencies: - regenerator-runtime: ^0.14.0 - checksum: 3e73d9e65f76fad8f99802b5364c941f4a60c693b3eca66147bb0bfa54cf0fbe017232155e16e3fd83c0a049b51b8d7239efbd73626534abe8b54a6dd57dcb1b - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.18.9": - version: 7.27.6 - resolution: "@babel/runtime@npm:7.27.6" - checksum: 3f7b879df1823c0926bd5dbc941c62f5d60faa790c1aab9758c04799e1f04ee8d93553be9ec059d4e5882f19fe03cbe8933ee4f46212dced0f6d8205992c9c9a +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.19.0, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.24.1, @babel/runtime@npm:^7.24.6, @babel/runtime@npm:^7.24.8, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.26.10, @babel/runtime@npm:^7.28.3, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": + version: 7.28.4 + resolution: "@babel/runtime@npm:7.28.4" + checksum: 934b0a0460f7d06637d93fcd1a44ac49adc33518d17253b5a0b55ff4cb90a45d8fe78bf034b448911dbec7aff2a90b918697559f78d21c99ff8dbadae9565b55 languageName: node linkType: hard -"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.9, @babel/template@npm:^7.3.3": - version: 7.25.9 - resolution: "@babel/template@npm:7.25.9" - dependencies: - "@babel/code-frame": ^7.25.9 - "@babel/parser": ^7.25.9 - "@babel/types": ^7.25.9 - checksum: 103641fea19c7f4e82dc913aa6b6ac157112a96d7c724d513288f538b84bae04fb87b1f1e495ac1736367b1bc30e10f058b30208fb25f66038e1f1eb4e426472 - languageName: node - linkType: hard - -"@babel/template@npm:^7.27.2": +"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.9, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": version: 7.27.2 resolution: "@babel/template@npm:7.27.2" dependencies: @@ -3213,17 +3158,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": - version: 7.26.5 - resolution: "@babel/types@npm:7.26.5" - dependencies: - "@babel/helper-string-parser": ^7.25.9 - "@babel/helper-validator-identifier": ^7.25.9 - checksum: 65dc14aa32ace22655c5edadeb99df80776c09cd93c105feaf49cc0583f3116aff0581b7eab630888c39ba61151f251c1399ec982b93585b0d1d1bf4a45b54f9 - languageName: node - linkType: hard - -"@babel/types@npm:^7.27.1, @babel/types@npm:^7.27.6, @babel/types@npm:^7.28.0": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.5, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.6, @babel/types@npm:^7.28.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": version: 7.28.0 resolution: "@babel/types@npm:7.28.0" dependencies: @@ -3233,49 +3168,49 @@ __metadata: languageName: node linkType: hard -"@backstage-community/plugin-3scale-backend@npm:3.6.1": - version: 3.6.1 - resolution: "@backstage-community/plugin-3scale-backend@npm:3.6.1" +"@backstage-community/plugin-3scale-backend@npm:3.8.0": + version: 3.8.0 + resolution: "@backstage-community/plugin-3scale-backend@npm:3.8.0" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-node": ^1.17.0 + "@backstage/plugin-catalog-node": ^1.18.0 atlassian-openapi: ^1.0.19 openapi-merge: ^1.3.3 swagger-converter: 2.1.0 swagger2openapi: ^7.0.4 - checksum: 9cc03a9992fe722181604b8d35cc5f9333c0ad68ce7695aa964672f4b96394be11410296dcef103930dd01683aba62b4f28f3924975641449e794f45cc208c02 + checksum: d2f15f6d329ab756188031d044d2f19f3502f98d366f60f7e7fd0150eaf5db6b9767defab7602614395c4bfb529b9e072fc416cff9d02ff902d275f743a4032f languageName: node linkType: hard -"@backstage-community/plugin-acr@npm:1.15.1": - version: 1.15.1 - resolution: "@backstage-community/plugin-acr@npm:1.15.1" - dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/theme": ^0.6.6 - "@janus-idp/shared-react": ^2.16.0 +"@backstage-community/plugin-acr@npm:1.17.0": + version: 1.17.0 + resolution: "@backstage-community/plugin-acr@npm:1.17.0" + dependencies: + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.11.3 + luxon: ^3.6.1 react-use: ^17.4.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: edb686048387ffbe0db50b0b1e23e41432d65d9a42ecd7fea3ab81bffec3389d8764a2dc3da9edc829c0cc6f7b1e23674ba96040f6b0ce07be07ba6996b87972 + checksum: 3e531c56e62cfad3bcde752a926e54310307cf678661d76504f47dae73d12fbb0a71c0e3d6a97fa110693b2abff39d3defb0d0e4de504ab8ac88fa42c87da511 languageName: node linkType: hard -"@backstage-community/plugin-analytics-provider-segment@npm:1.16.0": - version: 1.16.0 - resolution: "@backstage-community/plugin-analytics-provider-segment@npm:1.16.0" +"@backstage-community/plugin-analytics-provider-segment@npm:1.18.0": + version: 1.18.0 + resolution: "@backstage-community/plugin-analytics-provider-segment@npm:1.18.0" dependencies: "@backstage/config": ^1.3.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 + "@backstage/core-components": ^0.17.3 + "@backstage/core-plugin-api": ^1.10.8 "@backstage/theme": ^0.6.6 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.11.3 @@ -3287,60 +3222,60 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: e3b735ab3b553edc0424093422559edffac0f776f38478c2895bc45259fe549be4dda29e9e3c4c3343a082efb1f95f1892936edf1235b8b0c8209d3c6006f678 + checksum: 5139abf1679f1eb98c0a2027c911e1c349cebe479074242288b93055a786dd81d7fd0a38c429c62a7722baba0004253921c8a388718237fe035023ebd87073d1 languageName: node linkType: hard -"@backstage-community/plugin-azure-devops-backend@npm:0.17.1": - version: 0.17.1 - resolution: "@backstage-community/plugin-azure-devops-backend@npm:0.17.1" +"@backstage-community/plugin-azure-devops-backend@npm:0.19.0": + version: 0.19.0 + resolution: "@backstage-community/plugin-azure-devops-backend@npm:0.19.0" dependencies: - "@backstage-community/plugin-azure-devops-common": ^0.11.1 - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage-community/plugin-azure-devops-common": ^0.13.0 + "@backstage/backend-defaults": ^0.11.1 + "@backstage/backend-plugin-api": ^1.4.1 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-auth-node": ^0.6.3 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.0 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-auth-node": ^0.6.5 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.17.2 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.2 "@types/express": ^4.17.6 azure-devops-node-api: ^13.0.0 express: ^4.17.1 express-promise-router: ^4.1.0 mime-types: ^2.1.27 p-limit: ^3.1.0 - checksum: 3f554b301644b976932f3b31676334225a8bdae8282466d75698c5e9f9ece67a4e7d5ade9eefe1cd5748d05fe65191ca67e1598dd51c54ae66521eea1569d69c + checksum: bd586231f045d48471a3a810ef25d70cf7a0d708738ab6686edb9f440fe137980b324c7665806539d4d2756a9905e160d458bf0d25b098007176a0932d67c9a0 languageName: node linkType: hard -"@backstage-community/plugin-azure-devops-common@npm:^0.11.1": - version: 0.11.1 - resolution: "@backstage-community/plugin-azure-devops-common@npm:0.11.1" +"@backstage-community/plugin-azure-devops-common@npm:^0.13.0": + version: 0.13.0 + resolution: "@backstage-community/plugin-azure-devops-common@npm:0.13.0" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-permission-common": ^0.9.0 - checksum: 8e85f574b670e9590a933303a7a317ba39d0af9213286c0b10d86f6076e6338c1bde393b1312b122c9857c929112c537b3f32bed85371817ac4ec0c7ee2ed00e + "@backstage/catalog-model": ^1.7.5 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-permission-common": ^0.9.1 + checksum: e6acccff0852bc9b8c09b53e7f1dbccb3a7636c5169627caa7d3d3fbef0dea3e491ab75e6de9df8f1a0a00b2ffd38ea117ce6157d5dca032756f0d66143ed668 languageName: node linkType: hard -"@backstage-community/plugin-azure-devops@npm:0.16.1": - version: 0.16.1 - resolution: "@backstage-community/plugin-azure-devops@npm:0.16.1" +"@backstage-community/plugin-azure-devops@npm:0.18.0": + version: 0.18.0 + resolution: "@backstage-community/plugin-azure-devops@npm:0.18.0" dependencies: - "@backstage-community/plugin-azure-devops-common": ^0.11.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 + "@backstage-community/plugin-azure-devops-common": ^0.13.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.4.4 + "@backstage/core-components": ^0.17.4 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-permission-react": ^0.4.34 + "@backstage/frontend-plugin-api": ^0.10.4 + "@backstage/plugin-catalog-react": ^1.19.1 + "@backstage/plugin-permission-react": ^0.4.36 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -3351,86 +3286,90 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: d21c9d0a0f878fc021bb2c7c8283d9db750b8e68c22fc001e1b4792894b0720b2cea11109ea27f14dbbb63e651a8c3632b3d180538989624014330a13d5b38fa + checksum: 7840c13a9abf93ac19706eefb2f5137a5d24b01110d8e8a59e5261f27604f3892ec46e42533b860253021db84d9ecf2e806bda6d5a56d34d48e1ec82267bc172 languageName: node linkType: hard -"@backstage-community/plugin-catalog-backend-module-keycloak@npm:3.12.1": - version: 3.12.1 - resolution: "@backstage-community/plugin-catalog-backend-module-keycloak@npm:3.12.1" +"@backstage-community/plugin-catalog-backend-module-keycloak@npm:3.14.2": + version: 3.14.2 + resolution: "@backstage-community/plugin-catalog-backend-module-keycloak@npm:3.14.2" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-backend-module-logs": ^0.1.10 - "@backstage/plugin-catalog-node": ^1.17.0 - "@keycloak/keycloak-admin-client": 26.1.4 + "@backstage/plugin-catalog-backend-module-logs": ^0.1.13 + "@backstage/plugin-catalog-node": ^1.18.0 + "@keycloak/keycloak-admin-client": 26.3.4 "@opentelemetry/api": ^1.9.0 jsonwebtoken: ^9.0.0 lodash: ^4.17.21 p-limit: ^6.1.0 pg-format: ^1.0.4 uuid: ^9.0.1 - checksum: 7f9f914bd7cbb91d759035ceef4809980dbbf30a3b348681576367be0a926fa09d0d3832508c2cc85caa7300292a3d75da79e2cb4e8e091ed293de30abbe737b + checksum: e2c1f6abfa30aaf44a9e7eeb288e399343871d8a76961d7168f8d1356a612c7e382c66563e0a0b00f0bf846006c3daf2630a29affd6225265cf7ebe516942666 languageName: node linkType: hard -"@backstage-community/plugin-catalog-backend-module-pingidentity@npm:0.5.0": - version: 0.5.0 - resolution: "@backstage-community/plugin-catalog-backend-module-pingidentity@npm:0.5.0" +"@backstage-community/plugin-catalog-backend-module-pingidentity@npm:0.7.0": + version: 0.7.0 + resolution: "@backstage-community/plugin-catalog-backend-module-pingidentity@npm:0.7.0" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/plugin-catalog-node": ^1.17.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/plugin-catalog-node": ^1.18.0 node-fetch: ^2.6.7 uuid: ^10.0.0 - checksum: 2859c91756fbf687c4dc40b9d413537c3baf8858c48ade362dbfd82725279961a56bf4f2b3dc06f1a2c068ff08a19b4d8d6b1ba678b3b2730467ce4876eccebb + checksum: 0f647db2b3bfd0a9a250f10a918aa8884aa64a1f499cd87671386fae2b10ca5cbddc367b4bb63200e43a9066e9430d873207042bc9f772a1e853763f334197cb languageName: node linkType: hard -"@backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor@npm:2.5.0": - version: 2.5.0 - resolution: "@backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor@npm:2.5.0" +"@backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor@npm:2.8.0": + version: 2.8.0 + resolution: "@backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor@npm:2.8.0" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/plugin-catalog-node": ^1.17.0 - checksum: f7c6de02a254ad026c78d6212214187685f2d1d3158922e9d93ffe96a0a4014f9d1dbafe9f91057e5b9a5dd18218b3ae44561b546a97cda6990747dcd057b5ba + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-events-node": ^0.4.14 + "@backstage/plugin-notifications-common": ^0.1.0 + "@backstage/plugin-notifications-node": ^0.2.18 + checksum: 8d196e320f79bc697535b12dca4303bf2fbcd65c6142d88f9a40c1c7e9c2c943dfc56eb712a8e45d7a10bc332483eaa79f14e1d42b5704052de47ec202181c91 languageName: node linkType: hard -"@backstage-community/plugin-dynatrace@npm:10.6.0": - version: 10.6.0 - resolution: "@backstage-community/plugin-dynatrace@npm:10.6.0" +"@backstage-community/plugin-dynatrace@npm:10.8.0": + version: 10.8.0 + resolution: "@backstage-community/plugin-dynatrace@npm:10.8.0" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.4 + "@backstage/core-plugin-api": ^1.10.9 "@material-ui/core": ^4.12.2 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react-use: ^17.2.4 peerDependencies: - "@backstage/plugin-catalog-react": ^1.18.0 + "@backstage/plugin-catalog-react": ^1.19.1 react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 92e8d420986629f474da629ff599b39127ea36e68fd462f5d4de95820c77c6e1524adb5f78e6b3ba8ea0ae2a207fbf46dd8f4f3af511e4b15016da3278c0b655 + checksum: 215bb1d816ac0f50a84c0cb184457d675dc7342d315bb10d22f628ec7932878fcc462e32bed84aa804b997cdc9b9bac7ee5ec73049fa9bf8984d45e2f8186a08 languageName: node linkType: hard -"@backstage-community/plugin-github-actions@npm:0.11.1": - version: 0.11.1 - resolution: "@backstage-community/plugin-github-actions@npm:0.11.1" - dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/integration": ^1.17.0 - "@backstage/integration-react": ^1.2.7 - "@backstage/plugin-catalog-react": ^1.18.0 +"@backstage-community/plugin-github-actions@npm:0.14.0": + version: 0.14.0 + resolution: "@backstage-community/plugin-github-actions@npm:0.14.0" + dependencies: + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.5.1 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/integration": ^1.17.1 + "@backstage/integration-react": ^1.2.9 + "@backstage/plugin-catalog-react": ^1.20.1 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -3443,23 +3382,23 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 94733ee98777a8104284515a81e71600fc82673b692f24aaf1106d1bee834969a82232ad582b5299ed82eb0490962795933e52648d0128225f46284408fa306c + checksum: dab379a63d24f83020cd55a90179923d6f30a6c6f97eb1940e4ebc2f3975bc87ec73d3fb65c5da0e7db3ea7f84aa4d556a4e2ca43a9c58fdd810eded479a54fe languageName: node linkType: hard -"@backstage-community/plugin-github-issues@npm:0.10.0": - version: 0.10.0 - resolution: "@backstage-community/plugin-github-issues@npm:0.10.0" +"@backstage-community/plugin-github-issues@npm:0.13.0": + version: 0.13.0 + resolution: "@backstage-community/plugin-github-issues@npm:0.13.0" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.5.1 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/integration": ^1.17.0 - "@backstage/integration-react": ^1.2.7 - "@backstage/plugin-catalog-react": ^1.18.0 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/integration": ^1.17.1 + "@backstage/integration-react": ^1.2.9 + "@backstage/plugin-catalog-react": ^1.20.1 "@material-ui/core": ^4.12.4 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -3471,56 +3410,56 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 8bffb3d3c5352ddd84bb3cca3e33649b8ab07928e986dfb66081ca6a4c29c213b8277f0457b6321cb49a4e9db3e8489596932fd70e1205b418e1e171129e3c73 + checksum: 9f1feaa8a9c05432aee179e183c796f33d025fcebc86bca91541d717aeb08f1b06ab5e8c6f7f715e6127f2788ad59fc3e22843f50bed2ecf466c5a457a392665 languageName: node linkType: hard -"@backstage-community/plugin-jenkins-backend@npm:0.15.0": - version: 0.15.0 - resolution: "@backstage-community/plugin-jenkins-backend@npm:0.15.0" - dependencies: - "@backstage-community/plugin-jenkins-common": ^0.7.0 - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 +"@backstage-community/plugin-jenkins-backend@npm:0.17.0": + version: 0.17.0 + resolution: "@backstage-community/plugin-jenkins-backend@npm:0.17.0" + dependencies: + "@backstage-community/plugin-jenkins-common": ^0.9.0 + "@backstage/backend-defaults": ^0.11.1 + "@backstage/backend-plugin-api": ^1.4.1 + "@backstage/catalog-client": ^1.10.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.0 + "@backstage/plugin-catalog-node": ^1.17.2 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.2 "@types/express": ^4.17.6 express: ^4.17.1 express-promise-router: ^4.1.0 jenkins: ^1.0.0 node-fetch: ^2.6.7 yn: ^4.0.0 - checksum: bd0a9049badb691f714121faf6c8b9ea1e4a71a6ad63275906d315fccfe46b5d41007aa497d88a481585b76937b0b81857f54a4d6e57f1a096d9f9baf1a25c6d + checksum: 69ed44d2582b5f07fb7ee5eed419bcbb806cd70e7fc326d3ad30dadbfa1302625008502a52356d4060f41a54a455025c4ffb1cc70801285cd813b1e4f9463286 languageName: node linkType: hard -"@backstage-community/plugin-jenkins-common@npm:^0.7.0": - version: 0.7.0 - resolution: "@backstage-community/plugin-jenkins-common@npm:0.7.0" +"@backstage-community/plugin-jenkins-common@npm:^0.9.0": + version: 0.9.0 + resolution: "@backstage-community/plugin-jenkins-common@npm:0.9.0" dependencies: - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-permission-common": ^0.9.0 - checksum: baaedba99922f1ada3d86ee6ae15821777f58dfa21fc5fbf920c59385e2130a8bcf059df09ccc86dbec68cfb2b7b454ece401a06483877c8850c1e4a69352439 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-permission-common": ^0.9.1 + checksum: 02d60a2b1e89aa78206b2015ed6712234a35254a0adcf788ff5ec30b77c9f7e782a3d3c0c491e023ccde7b56010741e3bb8778cf2f49b85330a69754977fa70c languageName: node linkType: hard -"@backstage-community/plugin-jenkins@npm:0.20.0": - version: 0.20.0 - resolution: "@backstage-community/plugin-jenkins@npm:0.20.0" +"@backstage-community/plugin-jenkins@npm:0.22.0": + version: 0.22.0 + resolution: "@backstage-community/plugin-jenkins@npm:0.22.0" dependencies: - "@backstage-community/plugin-jenkins-common": ^0.7.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 + "@backstage-community/plugin-jenkins-common": ^0.9.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.4.4 + "@backstage/core-components": ^0.17.4 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/plugin-catalog-react": ^1.18.0 + "@backstage/frontend-plugin-api": ^0.10.4 + "@backstage/plugin-catalog-react": ^1.19.1 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -3530,49 +3469,49 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: d4f6108cd14ea04a34a68848b5a49c6d04b3ab2e0a79c168f8a5c3ef0aac354f5b2bc9327d04c558118d0673ccc8de504f5502f6b05ea92469115ea41a64e60a + checksum: 1141e25d21a666699a6bbde045b609a9dddda64f3c54c1dadbeabd03a1f735ff04b82ed5a36a37c5f98d1425e922ab222e0c987e29a76a81549a03f3b91d0f47 languageName: node linkType: hard -"@backstage-community/plugin-jfrog-artifactory@npm:1.15.3": - version: 1.15.3 - resolution: "@backstage-community/plugin-jfrog-artifactory@npm:1.15.3" +"@backstage-community/plugin-jfrog-artifactory@npm:1.18.2": + version: 1.18.2 + resolution: "@backstage-community/plugin-jfrog-artifactory@npm:1.18.2" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/theme": ^0.6.6 - "@janus-idp/shared-react": ^2.16.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.4 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.19.1 + "@backstage/theme": ^0.6.7 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.11.3 filesize: ^10.1.6 + luxon: ^3.6.1 react-use: ^17.4.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: c6cd3bc5a239175e0befb07ab5b58e87dcdfa8e85f3a584463f9482b487af58fddc3ae99f618eef5b0a9e8d1a4a22d420f1ee4c554ab8aebbadd76dd43497a55 + checksum: 70da147c7aeaaf17980594dea6a7c4a5887054252b907539c59a4a5329a89cbb7189776f32b25ea5d344071524d2aaa8c8c72bd06d9bc2ff8c818cb586e37a71 languageName: node linkType: hard -"@backstage-community/plugin-lighthouse-common@npm:^0.7.0": - version: 0.7.0 - resolution: "@backstage-community/plugin-lighthouse-common@npm:0.7.0" +"@backstage-community/plugin-lighthouse-common@npm:^0.9.0": + version: 0.9.0 + resolution: "@backstage-community/plugin-lighthouse-common@npm:0.9.0" dependencies: - "@backstage/config": ^1.3.2 - checksum: 564e03968c30660c75d7b7e75c18e462f79b4ae7e231f1070860922ad40d3d4359199a00e0f6bafa62d240e69ef5cabaa1cc785d5ecf0eefc78b443c18d79fb6 + "@backstage/config": ^1.3.3 + checksum: 44ed770e698762d1e26563c488a5ebbff4115362918928beec243a1af96c586b0e4aebcc92aa6e31ec18f920c1fe4ad2fe565ea9d0de7903dbd049a7b9f52007 languageName: node linkType: hard -"@backstage-community/plugin-lighthouse@npm:0.10.0": - version: 0.10.0 - resolution: "@backstage-community/plugin-lighthouse@npm:0.10.0" +"@backstage-community/plugin-lighthouse@npm:0.12.0": + version: 0.12.0 + resolution: "@backstage-community/plugin-lighthouse@npm:0.12.0" dependencies: - "@backstage-community/plugin-lighthouse-common": ^0.7.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 + "@backstage-community/plugin-lighthouse-common": ^0.9.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.4 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.19.1 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -3582,75 +3521,75 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 9c758d9b82a11ce5ecd0ba73c9324049bb15049ab21e73b53182654576318cace767b73ea344649003d1c3d017245666554d04fbfc4965fefd108297cea16728 + checksum: 3e8f9ac644e48093df865d7ba5decc19bca27023481016503e998d6ccb4652f697c6ed80868da8a9d01f9cf9408c99445e3e50762123376156a16d5f1cffdc41 languageName: node linkType: hard -"@backstage-community/plugin-nexus-repository-manager@npm:1.14.1": - version: 1.14.1 - resolution: "@backstage-community/plugin-nexus-repository-manager@npm:1.14.1" +"@backstage-community/plugin-nexus-repository-manager@npm:1.16.0": + version: 1.16.0 + resolution: "@backstage-community/plugin-nexus-repository-manager@npm:1.16.0" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/theme": ^0.6.6 - "@janus-idp/shared-react": ^2.16.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.11.3 "@material-ui/lab": ^4.0.0-alpha.45 filesize: ^10.1.6 + luxon: ^3.6.1 react-use: ^17.4.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: 1e1feb648674bf30debf205738e76fa2d2faa9271edd1d654b737235aca9d41225c71dbfac1e5eecd5ab650d7719e42cf8636abe761f1cf58e7fb9a2d9b4b23c + checksum: 84d5df28667c6c7f39a020a2c8c968149b544a2eb15302ecd3edeea0c3ec08acec86cb8c895ee296c3688d3a578f9e1b5bfd6756ae8defa127c175238df3ec34 languageName: node linkType: hard -"@backstage-community/plugin-ocm-backend@npm:5.7.0": - version: 5.7.0 - resolution: "@backstage-community/plugin-ocm-backend@npm:5.7.0" +"@backstage-community/plugin-ocm-backend@npm:5.9.1": + version: 5.9.1 + resolution: "@backstage-community/plugin-ocm-backend@npm:5.9.1" dependencies: - "@backstage-community/plugin-ocm-common": ^3.10.0 - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-openapi-utils": ^0.5.3 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 + "@backstage-community/plugin-ocm-common": ^3.12.0 + "@backstage/backend-defaults": ^0.12.0 + "@backstage/backend-openapi-utils": ^0.6.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.0 - "@kubernetes/client-node": 1.0.0-rc7 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.3 + "@kubernetes/client-node": 1.1.2 express: ^4.18.2 semver: ^7.5.4 - checksum: 3e9c9f23c2324c85f41331ee3f481065ee15a71e03d0edf51dfac0eadf18ab85303badc21220fff813c71d6743bda887f531ad62ce26a2c33270cce0d61bcc10 + checksum: f944e4d83a418bbe89f14772d7d634659e78cd141b017b418026e61329415b227c20e50dc80681c795d0561debd3288fae6cdded3ae8af988be89f5619829d81 languageName: node linkType: hard -"@backstage-community/plugin-ocm-common@npm:^3.10.0": - version: 3.10.0 - resolution: "@backstage-community/plugin-ocm-common@npm:3.10.0" +"@backstage-community/plugin-ocm-common@npm:^3.12.0": + version: 3.12.0 + resolution: "@backstage-community/plugin-ocm-common@npm:3.12.0" peerDependencies: - "@backstage/plugin-permission-common": ^0.9.0 - checksum: 42cc2cbc142db1725f62dc26ca711a4aed83808376f94927f97a579ada5844cb027229f53e8a95c6f85bd186a4f83ac6e5d3a3bc30c508d9ab09b9c227b78346 + "@backstage/plugin-permission-common": ^0.9.1 + checksum: 0d0cd31ef79fcda6f367c059098dc63ca64185dca2fbf1702f7bcfe15f8b10202ee584a0692f231e2dd94ba047a82baa0a246203b633f6933a0e0d089104ce96 languageName: node linkType: hard -"@backstage-community/plugin-ocm@npm:5.6.0": - version: 5.6.0 - resolution: "@backstage-community/plugin-ocm@npm:5.6.0" +"@backstage-community/plugin-ocm@npm:5.8.0": + version: 5.8.0 + resolution: "@backstage-community/plugin-ocm@npm:5.8.0" dependencies: - "@backstage-community/plugin-ocm-common": ^3.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 + "@backstage-community/plugin-ocm-common": ^3.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-home": ^0.8.8 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/plugin-search-react": ^1.9.0 - "@backstage/theme": ^0.6.6 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-home": ^0.8.11 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/plugin-search-react": ^1.9.3 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.11.3 "@mui/icons-material": ^5.16.4 @@ -3660,71 +3599,70 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 47874e8ef881b36d3dac6bb573b0819b9eafb9f3f9fc43f40b9236f144a1f9134276d03f40053a946ca8a18c6b83b774a8029c4b10e362400e017f4d04244bb7 + checksum: 8284f73ec067dffa922a9361bebccb8a0865254e914c0153817b4b7877451c4640a9d8bcf4c31535372c65ceb432c7990c758dbd5eacb255cd9285b6c4a5c847 languageName: node linkType: hard -"@backstage-community/plugin-quay-common@npm:^1.9.1": - version: 1.9.1 - resolution: "@backstage-community/plugin-quay-common@npm:1.9.1" +"@backstage-community/plugin-quay-common@npm:^1.11.0": + version: 1.11.0 + resolution: "@backstage-community/plugin-quay-common@npm:1.11.0" peerDependencies: - "@backstage/plugin-permission-common": ^0.9.0 + "@backstage/plugin-permission-common": ^0.9.1 react: ^17.0.0 || ^18.0.0 - checksum: d49676b4268dbb9086f505199a4f94b266cf9f57755172b6fc7b62fd7e5a74fdf8d4ff0ba62941ca90961c085ab9ede76cca8fc6a8d9728ed653a80040afa13e + checksum: a588adda6f46d4a26aae5eb079476814c9b8d138404e7dda678169ba67569793487de0de43b1829e53a4fde41b83e4459b15743298671559c23004f4b2c62d7c languageName: node linkType: hard -"@backstage-community/plugin-quay@npm:1.21.1": - version: 1.21.1 - resolution: "@backstage-community/plugin-quay@npm:1.21.1" +"@backstage-community/plugin-quay@npm:1.24.0": + version: 1.24.0 + resolution: "@backstage-community/plugin-quay@npm:1.24.0" dependencies: - "@backstage-community/plugin-quay-common": ^1.9.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/theme": ^0.6.6 - "@janus-idp/shared-react": ^2.16.0 + "@backstage-community/plugin-quay-common": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.11.3 "@material-ui/lab": 4.0.0-alpha.61 filesize: ^10.1.6 + luxon: ^3.6.1 react-use: ^17.4.0 peerDependencies: react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: 2b8ab7e09728324eaa80c028a7a5064cf3daca6f2b35e76ea34cde6baa9ffe2c4f1b58527edb6ab863ad721577c4f131d3e0a94d57bac90ee00e49b9e6e09f7d + checksum: 828867daf6498dff8dcf3e6472315577ffd7bd1d108a6170671aee90e8638e764024e99e76c4dc2484b32cdbf06afc9d61dd17d2b3cf2333175104a7a588dfd2 languageName: node linkType: hard -"@backstage-community/plugin-rbac-common@npm:^1.18.0": - version: 1.18.0 - resolution: "@backstage-community/plugin-rbac-common@npm:1.18.0" +"@backstage-community/plugin-rbac-common@npm:^1.19.0, @backstage-community/plugin-rbac-common@npm:^1.20.0": + version: 1.20.0 + resolution: "@backstage-community/plugin-rbac-common@npm:1.20.0" peerDependencies: "@backstage/errors": ^1.2.7 - "@backstage/plugin-permission-common": ^0.9.0 - checksum: 7115bc49a6f58a6080b140fccb0f627edf3df7948769ef9303a723db5de51641369d01144518eae6f43c6aea56cff4e1b8e9013998ba47b6856b29c10335938c + "@backstage/plugin-permission-common": ^0.9.1 + checksum: 8547d5a7a9ed24db008e4cd042330af4876549f226373b44ea09fee6fd5348e33de061fd97d45b5e979f22cbdff2b98c7cd048f1cb83496cfa8f86df96ddbb18 languageName: node linkType: hard -"@backstage-community/plugin-rbac@npm:1.42.0": - version: 1.42.0 - resolution: "@backstage-community/plugin-rbac@npm:1.42.0" +"@backstage-community/plugin-rbac@npm:1.45.1": + version: 1.45.1 + resolution: "@backstage-community/plugin-rbac@npm:1.45.1" dependencies: - "@backstage-community/plugin-rbac-common": ^1.18.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog": ^1.30.0 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/theme": ^0.6.6 - "@janus-idp/shared-react": ^2.16.0 - "@mui/icons-material": 5.16.14 + "@backstage-community/plugin-rbac-common": ^1.20.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog": ^1.31.2 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 + "@mui/icons-material": 5.18.0 "@mui/material": ^5.14.18 "@mui/styles": ^6.1.7 "@rjsf/core": ^5.21.2 @@ -3738,33 +3676,32 @@ __metadata: peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: 95891e65774a745b6ac1a8fb749961b74ce8ef4083a69c0dc920014708085de64103955456d23c6624893c90b4a946f44724982fa85d5c529986691b535f21ca + checksum: a24f62cb2751e78466f19948a25fbcddacf623f64b2602961e70ced024541da817324970fc0d60dccaeb98c8d78be9ce5f9d1e8bc291eb88b483856c7b6c81ba languageName: node linkType: hard -"@backstage-community/plugin-redhat-argocd-common@npm:^1.6.1": - version: 1.6.1 - resolution: "@backstage-community/plugin-redhat-argocd-common@npm:1.6.1" +"@backstage-community/plugin-redhat-argocd-common@npm:^1.8.0": + version: 1.8.0 + resolution: "@backstage-community/plugin-redhat-argocd-common@npm:1.8.0" dependencies: - "@backstage/plugin-permission-common": ^0.9.0 + "@backstage/plugin-permission-common": ^0.9.1 "@kubernetes/client-node": ^0.22.1 - checksum: 012c05739adcc205f039735953ca7893c9a16ba6aa9767a12d86ecf9afa6a872ceb1d4fc19cae2b167ee66d214f9144ad58518702b2455087d5c43517c1936cc + checksum: a9cad9646a179f59f667e89d7ea28b73d5c0ebd2b4557a95414b09751e960dca87ea17865de52322c8d0b6ed9131135524f512dfb8be565ee18579ba2f38b392 languageName: node linkType: hard -"@backstage-community/plugin-redhat-argocd@npm:1.21.2": - version: 1.21.2 - resolution: "@backstage-community/plugin-redhat-argocd@npm:1.21.2" - dependencies: - "@backstage-community/plugin-redhat-argocd-common": ^1.6.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-kubernetes-react": ^0.5.7 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/theme": ^0.6.6 - "@janus-idp/shared-react": ^2.16.0 +"@backstage-community/plugin-redhat-argocd@npm:2.0.0": + version: 2.0.0 + resolution: "@backstage-community/plugin-redhat-argocd@npm:2.0.0" + dependencies: + "@backstage-community/plugin-redhat-argocd-common": ^1.8.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-kubernetes-react": ^0.5.10 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 "@kubernetes/client-node": ^0.22.1 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.9.1 @@ -3772,7 +3709,6 @@ __metadata: "@material-ui/styles": ^4.11.5 "@mui/icons-material": ^6.0.0 "@mui/material": ^5.15.16 - "@patternfly/patternfly": ^6.0.0 "@patternfly/react-core": ^6.0.0 "@patternfly/react-icons": ^6.0.0 moment: ^2.30.1 @@ -3781,116 +3717,113 @@ __metadata: peerDependencies: react: ^17.0.0 || ^18.0.0 react-router-dom: ^6.3.0 - checksum: f7aa957ac813d8f6782e46784a34e3d94039c2e7b2bc6c9b94869a034aeaddfb5943f0e0f7f5742111cea21815365697ce250232d49e02e93daf207ad9a615c8 + checksum: 2a4db313b511dbabad6a47a939cce14a81246d829f1e7a50b33b892ad58ca33718321db15caba43214a7c3d01aa5f8471da1c12a196688fe7d317001156d31c9 languageName: node linkType: hard -"@backstage-community/plugin-scaffolder-backend-module-kubernetes@npm:2.8.1": - version: 2.8.1 - resolution: "@backstage-community/plugin-scaffolder-backend-module-kubernetes@npm:2.8.1" +"@backstage-community/plugin-scaffolder-backend-module-kubernetes@npm:2.10.1": + version: 2.10.1 + resolution: "@backstage-community/plugin-scaffolder-backend-module-kubernetes@npm:2.10.1" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/plugin-scaffolder-node": ^0.8.2 - "@kubernetes/client-node": 1.0.0-rc7 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/plugin-scaffolder-node": ^0.11.0 + "@kubernetes/client-node": 1.1.2 yaml: ^2.0.0 - zod: ^3.22.4 - checksum: 36c99a1152aea90bf25bb613b6db8fef27b7958433d71ce85e9be858b08b77b2fc26437222b7a29012ab6b78f077bdd65de9e1871375f5295834dfd538db2047 + checksum: 5059473fca48e8420dc7cc5fb947160c7fbd78886c3d9e55ad63fdbf00a993bc0ad44c4e36aac7715537edef91d1862157ab9323c6fea33896a0e9ac056c3e92 languageName: node linkType: hard -"@backstage-community/plugin-scaffolder-backend-module-quay@npm:2.9.1": - version: 2.9.1 - resolution: "@backstage-community/plugin-scaffolder-backend-module-quay@npm:2.9.1" +"@backstage-community/plugin-scaffolder-backend-module-quay@npm:2.11.0": + version: 2.11.0 + resolution: "@backstage-community/plugin-scaffolder-backend-module-quay@npm:2.11.0" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/plugin-scaffolder-node": ^0.8.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/plugin-scaffolder-node": ^0.11.0 yaml: ^2.6.0 - checksum: 3f4b0e300a98e7a32491e3094e512bf6da3875c92ef797962eb1947297e53d06da86cd382a83cd28ec0fbe6b65bf09f7cc39a6430d782e46b583cbf9575266a2 + checksum: bd8501eb209871729d4e517635fb6ff8979ebb3b38aab58e28a0a5979ed2f9cfb286f90541b5d96916032447c1e588133758bcd7987f655d1b6614bd0f2570d7 languageName: node linkType: hard -"@backstage-community/plugin-scaffolder-backend-module-regex@npm:2.7.0": - version: 2.7.0 - resolution: "@backstage-community/plugin-scaffolder-backend-module-regex@npm:2.7.0" +"@backstage-community/plugin-scaffolder-backend-module-regex@npm:2.8.0": + version: 2.8.0 + resolution: "@backstage-community/plugin-scaffolder-backend-module-regex@npm:2.8.0" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/plugin-scaffolder-node": ^0.8.2 + "@backstage/backend-plugin-api": ^1.4.1 + "@backstage/plugin-scaffolder-node": ^0.10.0 yaml: ^2.3.3 - zod: ^3.22.4 - checksum: e53222d31bcf2e225de29619345a6676edbdbf9c72bd98b0b46bd709d685f1db49f985dbd21e86f569f0861dc38ba09cdf4cfd391d58ff73cff4b3a2f6e0c819 + checksum: 9e4ebb0bd4b4a154b385e52c5dd8d1959c06b7a0a9354ffb9bfb4acdd41a8a0a6a6a4358fa9e40556fcd2677feb1b5bd3fd290fd3041f41aede9897d3698d8e5 languageName: node linkType: hard -"@backstage-community/plugin-scaffolder-backend-module-servicenow@npm:2.7.0": - version: 2.7.0 - resolution: "@backstage-community/plugin-scaffolder-backend-module-servicenow@npm:2.7.0" +"@backstage-community/plugin-scaffolder-backend-module-servicenow@npm:2.8.1": + version: 2.8.1 + resolution: "@backstage-community/plugin-scaffolder-backend-module-servicenow@npm:2.8.1" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/plugin-scaffolder-node": ^0.8.2 + "@backstage/backend-plugin-api": ^1.4.1 + "@backstage/plugin-scaffolder-node": ^0.10.0 abort-controller: ^3.0.0 axios: ^1.7.4 form-data: ^4.0.0 yaml: ^2.3.3 - zod: ^3.22.4 - checksum: bafcebcb2f99f5e517a8d3285ab0526865917526076a08aad551ead2d932e61f563296776a11128ea01cde97ea9782e4a7380dc9ee67d41b5e1753e57e0fb221 + checksum: 93b4abc5c1e80a36cbfd856756e8fbfa97ba309db0db433f259af4aa975c2ef0fcbbad31a238319ad8602dd902555ff03946020b0f939ba07a1df77262df41e9 languageName: node linkType: hard -"@backstage-community/plugin-scaffolder-backend-module-sonarqube@npm:2.7.1": - version: 2.7.1 - resolution: "@backstage-community/plugin-scaffolder-backend-module-sonarqube@npm:2.7.1" +"@backstage-community/plugin-scaffolder-backend-module-sonarqube@npm:2.8.0": + version: 2.8.0 + resolution: "@backstage-community/plugin-scaffolder-backend-module-sonarqube@npm:2.8.0" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/plugin-scaffolder-node": ^0.8.2 + "@backstage/backend-plugin-api": ^1.4.1 + "@backstage/plugin-scaffolder-node": ^0.10.0 yaml: ^2.3.3 - checksum: ac8cf51aada9fce27e71f11ae6621f225f0afaa1e6e6a872b67b986f345d6ed06c04ba3ff6595e046d67ba71f66c21dfa422b04a7852b116cb1e974529c83e7a + checksum: 55d1191fe2c472cefacc44ab2e4be07c1bcb047159f57a06ba241ca7e4d1454e31b3dc214acc38884ccc4be99ca48a2d6b3a686687558aaae13e42373afe4a59 languageName: node linkType: hard -"@backstage-community/plugin-sonarqube-backend@npm:0.9.2": - version: 0.9.2 - resolution: "@backstage-community/plugin-sonarqube-backend@npm:0.9.2" +"@backstage-community/plugin-sonarqube-backend@npm:0.12.0": + version: 0.12.0 + resolution: "@backstage-community/plugin-sonarqube-backend@npm:0.12.0" dependencies: - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 + "@backstage/backend-defaults": ^0.12.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 "@types/express": "*" express: ^4.18.1 express-promise-router: ^4.1.0 node-fetch: ^2.6.7 yn: ^5.0.0 - checksum: c882ebfb6d67f8d3a438e3a3f1fd4bc97389cd5e4de1d53a4e337f5a8ea8097a284c9e766142044f19890ed07fd720ae0aa99d7b747a09b9686a749ac5e6ee6f + checksum: 3f070fcf6b46f7e0c6980e1b929f989955d1c1dc77867fbc3b321032461f6ca12ed4350314c1a54f44110d3eef198d5614e4149c5cf5ba25faaca0839e3149d0 languageName: node linkType: hard -"@backstage-community/plugin-sonarqube-react@npm:^0.7.0": - version: 0.7.0 - resolution: "@backstage-community/plugin-sonarqube-react@npm:0.7.0" +"@backstage-community/plugin-sonarqube-react@npm:^0.10.0": + version: 0.10.0 + resolution: "@backstage-community/plugin-sonarqube-react@npm:0.10.0" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-plugin-api": ^1.10.7 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-plugin-api": ^1.10.9 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 3b1cf7212ee59766b826417a9680984306b7b982f61eef1da8af3602d3f5b6fad2517ec310a2648aab97d8bc5aa6ad69051f607e959ff3655f4362c71d0c8aa6 + checksum: 373ea9ad3cf6e4f086bd92e29379d1af5f5ebad671dc4cf729542352825496665459df19370e3800cb33bd25f28bf15250e958afe35084c87ed186e615ffc1ba languageName: node linkType: hard -"@backstage-community/plugin-sonarqube@npm:0.13.0": - version: 0.13.0 - resolution: "@backstage-community/plugin-sonarqube@npm:0.13.0" +"@backstage-community/plugin-sonarqube@npm:0.18.0": + version: 0.18.0 + resolution: "@backstage-community/plugin-sonarqube@npm:0.18.0" dependencies: - "@backstage-community/plugin-sonarqube-react": ^0.7.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-app-api": ^0.11.2 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/plugin-catalog-react": ^1.18.0 + "@backstage-community/plugin-sonarqube-react": ^0.10.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.5.1 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-app-api": ^0.12.0 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/plugin-catalog-react": ^1.20.1 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/styles": ^4.10.0 @@ -3903,44 +3836,44 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 1524c19298cb695d52ee3c9769047f45ad0d872fdba73588991b1fec0afbaec891d4e049ccdd729403722294029aed1769cc29fda48f3839e003d372d04712ce + checksum: 3d554a4245d76e47a40a2c18dd80747da8fd80d3695574e18936b7b0634c2055a91ff537db5d0bb312e4e8edb0133cb58b6984a4fbe99d1728480c8810a23112 languageName: node linkType: hard -"@backstage-community/plugin-tech-radar-backend@npm:1.6.0": - version: 1.6.0 - resolution: "@backstage-community/plugin-tech-radar-backend@npm:1.6.0" +"@backstage-community/plugin-tech-radar-backend@npm:1.9.1": + version: 1.9.1 + resolution: "@backstage-community/plugin-tech-radar-backend@npm:1.9.1" dependencies: - "@backstage-community/plugin-tech-radar-common": ^1.6.0 - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 + "@backstage-community/plugin-tech-radar-common": ^1.9.1 + "@backstage/backend-defaults": ^0.12.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 express: ^4.17.1 express-promise-router: ^4.1.0 node-fetch: ^2.6.7 zod: ^3.20.0 - checksum: 83675eff6b7f8f2ea78b7083b5aab8cbe22f83cceda0c4083f6cc403d5ff83c668e7b9c484ed47633b3292cd93a6f11d36497aa79fb67dc9280a37164ce46e34 + checksum: b2649eebffa301091b6da53fd9d585c6be5604a9ecd8528fce56fb1926b79d8908d192fddfc445641cac4b4a414d6d12a144811c5fbce9e856959839cb2262df languageName: node linkType: hard -"@backstage-community/plugin-tech-radar-common@npm:1.6.0, @backstage-community/plugin-tech-radar-common@npm:^1.6.0": - version: 1.6.0 - resolution: "@backstage-community/plugin-tech-radar-common@npm:1.6.0" +"@backstage-community/plugin-tech-radar-common@npm:1.10.0, @backstage-community/plugin-tech-radar-common@npm:^1.10.0, @backstage-community/plugin-tech-radar-common@npm:^1.9.1": + version: 1.10.0 + resolution: "@backstage-community/plugin-tech-radar-common@npm:1.10.0" dependencies: zod: ^3.20.0 - checksum: 2ccc129b8ebeaaaafce053168bce3afff1109ac7fb5a363b5800bd0cfe0225b9d87d46fa6d8e62798bba43741fd3dbd421de9ac8b892491e3effdacf63a224e0 + checksum: c2bc1dc9dc432014cf4efb486b623843add126bf4dfe716a8bafd29a7ded09ab81c154baa36d6ab1c223ab55848911096d5b5a19d45727027b5f3dd05f43bac3 languageName: node linkType: hard -"@backstage-community/plugin-tech-radar@npm:1.7.0": - version: 1.7.0 - resolution: "@backstage-community/plugin-tech-radar@npm:1.7.0" +"@backstage-community/plugin-tech-radar@npm:1.11.0": + version: 1.11.0 + resolution: "@backstage-community/plugin-tech-radar@npm:1.11.0" dependencies: - "@backstage-community/plugin-tech-radar-common": ^1.6.0 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-plugin-api": ^0.10.2 + "@backstage-community/plugin-tech-radar-common": ^1.10.0 + "@backstage/core-compat-api": ^0.5.2 + "@backstage/core-components": ^0.18.1 + "@backstage/core-plugin-api": ^1.11.0 + "@backstage/frontend-plugin-api": ^0.12.0 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -3951,42 +3884,40 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 84bae7b9da35a5b628739501a89060d485ab3fbf12ff6563e08d0976d92c0e10362b061775552f104d2bdbc3fe95e81d2de4c9da65c016351fefb158739e77f3 + checksum: 8d3fcecdf7112cc84effaf4cdafaa7d449d08ae7c487956af4ca99ae3b78d8fc91537b421a523e4e766fa632cf6dbcae6269ac041fe9ddde94d3a42f7502f1c6 languageName: node linkType: hard -"@backstage-community/plugin-tekton-common@npm:^1.10.1": - version: 1.10.1 - resolution: "@backstage-community/plugin-tekton-common@npm:1.10.1" +"@backstage-community/plugin-tekton-common@npm:^1.12.0": + version: 1.13.0 + resolution: "@backstage-community/plugin-tekton-common@npm:1.13.0" peerDependencies: - "@backstage/plugin-permission-common": ^0.9.0 - checksum: e331be4d9a97cef18db8b1f02274af136e9b8e8ba68c969006589221a517c931eb536d94cd29a5c030a4a8e80dfd9b89ad9515f9f967bca65aeb921387cd8dad + "@backstage/plugin-permission-common": ^0.9.1 + checksum: 29f539cfa4cde442615ae56e43d647eb03e06d999d22a2125f53cb6ea72b977ecb37193a53641569e4d6a74f75c57a8c146129fe066858e76d010a7ba6c7b43e languageName: node linkType: hard -"@backstage-community/plugin-tekton@npm:3.26.2": - version: 3.26.2 - resolution: "@backstage-community/plugin-tekton@npm:3.26.2" +"@backstage-community/plugin-tekton@npm:3.29.0": + version: 3.29.0 + resolution: "@backstage-community/plugin-tekton@npm:3.29.0" dependencies: "@aonic-ui/pipelines": ^3.1.0 - "@backstage-community/plugin-tekton-common": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-kubernetes": ^0.12.7 - "@backstage/plugin-kubernetes-common": ^0.9.5 - "@backstage/plugin-kubernetes-react": ^0.5.7 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/theme": ^0.6.6 + "@backstage-community/plugin-tekton-common": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-kubernetes-common": ^0.9.6 + "@backstage/plugin-kubernetes-react": ^0.5.10 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 "@janus-idp/shared-react": ^2.16.0 "@kubernetes/client-node": 1.0.0-rc7 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.11.3 "@material-ui/lab": ^4.0.0-alpha.45 - "@mui/icons-material": 5.16.14 + "@mui/icons-material": 5.18.0 "@patternfly/patternfly": ^6.0.0 - "@patternfly/react-charts": ^7.1.1 "@patternfly/react-core": ^6.0.0 "@patternfly/react-tokens": ^6.0.0 "@patternfly/react-topology": ^6.0.0 @@ -3994,39 +3925,37 @@ __metadata: classnames: ^2.3.2 dagre: ^0.8.5 lodash: ^4.17.21 - react-measure: ^2.5.2 react-use: ^17.4.0 peerDependencies: react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: 42b8583fe26ca2bbfaa089d9e5f49d7ba77157cb9ef4b4800e130f3a1ad8c661738a5190253e784e25cd8b87e1eda193b0b17d1df90412c442a1c5653bbfa6c4 + checksum: 9f4189a5244ea1cc42de1377e616eeea4961dbcbcf4264cdec1c96897e005cee14fcbea9275219d8b0e1fc0df59b2d1a8f3ba0e7eeba0ed4bf232e3210aad74a languageName: node linkType: hard -"@backstage-community/plugin-topology@npm:2.2.2": - version: 2.2.2 - resolution: "@backstage-community/plugin-topology@npm:2.2.2" - dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-kubernetes-common": ^0.9.5 - "@backstage/plugin-kubernetes-react": ^0.5.7 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/theme": ^0.6.6 +"@backstage-community/plugin-topology@npm:2.7.0": + version: 2.7.0 + resolution: "@backstage-community/plugin-topology@npm:2.7.0" + dependencies: + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.18.1 + "@backstage/core-plugin-api": ^1.11.0 + "@backstage/plugin-catalog-react": ^1.21.1 + "@backstage/plugin-kubernetes-common": ^0.9.6 + "@backstage/plugin-kubernetes-react": ^0.5.11 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 "@janus-idp/shared-react": ^2.18.0 "@kubernetes/client-node": 1.1.2 - "@mui/icons-material": 5.16.14 - "@mui/lab": 5.0.0-alpha.175 + "@mui/icons-material": 5.18.0 + "@mui/lab": 5.0.0-alpha.177 "@mui/material": ^5.15.17 - "@mui/styles": 5.16.14 + "@mui/styles": 5.18.0 "@patternfly/patternfly": ^6.1.0 "@patternfly/react-charts": ^8.1.0 "@patternfly/react-core": ^6.1.0 - "@patternfly/react-styles": ^6.1.0 "@patternfly/react-tokens": ^6.1.0 "@patternfly/react-topology": ^6.1.0 classnames: 2.x @@ -4040,7 +3969,7 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: 2b2569ad1f016b7bf15367d05bcd05e7681da62bda0065405aeb315d69054cb66af5ebac29f84a999dc7dc8c23e83903060839fc7bc0b62ae4bbeb41eb9393aa + checksum: a4f3bb0f263bf288d04c1749f8cee5ef2eacdf0400c69c1117136261a5032a7c5a5bcadd4b84dfd5010c2baf90774a786f3f1aaae56e5f35c2cb69419bf69cb2 languageName: node linkType: hard @@ -4133,25 +4062,14 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-app-api@npm:^1.2.1": - version: 1.2.1 - resolution: "@backstage/backend-app-api@npm:1.2.1" - dependencies: - "@backstage/backend-plugin-api": ^1.2.1 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - checksum: 4f4baf705e0d50ce4390bf1448c49f241948e43f62ec42518e0b919688848f6089342a485c48e2d23ce37c52606a247921c7fb0674a659ab8bb8441dc2600f65 - languageName: node - linkType: hard - -"@backstage/backend-app-api@npm:^1.2.3, @backstage/backend-app-api@npm:^1.2.4": - version: 1.2.4 - resolution: "@backstage/backend-app-api@npm:1.2.4" +"@backstage/backend-app-api@npm:^1.2.1, @backstage/backend-app-api@npm:^1.2.5, @backstage/backend-app-api@npm:^1.2.7": + version: 1.2.7 + resolution: "@backstage/backend-app-api@npm:1.2.7" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - checksum: 4df278872bbdac686fea186f4b9b3ab2257c6cecef881ad2df7e2ce3a0ea4c2c7323d1c0b109f2cea6f01fdf01d6fc64fd0edcaa6a3f2b62ba155aa6c7e70748 + checksum: c43478358c0a7c53a04c8a2a831df1e36ec571bb154bb53f99387ff40f5f45f2fea9a8bafe7c0866fc7cf3ec88f49b487cddc1c440d96acc5c1deafc410c7620 languageName: node linkType: hard @@ -4455,9 +4373,9 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-defaults@npm:^0.10.0": - version: 0.10.0 - resolution: "@backstage/backend-defaults@npm:0.10.0" +"@backstage/backend-defaults@npm:^0.11.1": + version: 0.11.1 + resolution: "@backstage/backend-defaults@npm:0.11.1" dependencies: "@aws-sdk/abort-controller": ^3.347.0 "@aws-sdk/client-codecommit": ^3.350.0 @@ -4465,18 +4383,18 @@ __metadata: "@aws-sdk/credential-providers": ^3.350.0 "@aws-sdk/types": ^3.347.0 "@azure/storage-blob": ^12.5.0 - "@backstage/backend-app-api": ^1.2.3 + "@backstage/backend-app-api": ^1.2.5 "@backstage/backend-dev-utils": ^0.1.5 - "@backstage/backend-plugin-api": ^1.3.1 + "@backstage/backend-plugin-api": ^1.4.1 "@backstage/cli-node": ^0.2.13 - "@backstage/config": ^1.3.2 - "@backstage/config-loader": ^1.10.1 + "@backstage/config": ^1.3.3 + "@backstage/config-loader": ^1.10.2 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/integration-aws-node": ^0.1.16 - "@backstage/plugin-auth-node": ^0.6.3 - "@backstage/plugin-events-node": ^0.4.11 - "@backstage/plugin-permission-node": ^0.10.0 + "@backstage/integration": ^1.17.1 + "@backstage/integration-aws-node": ^0.1.17 + "@backstage/plugin-auth-node": ^0.6.5 + "@backstage/plugin-events-node": ^0.4.13 + "@backstage/plugin-permission-node": ^0.10.2 "@backstage/types": ^1.2.1 "@google-cloud/storage": ^7.0.0 "@keyv/memcache": ^2.0.1 @@ -4497,6 +4415,7 @@ __metadata: cron: ^3.0.0 express: ^4.17.1 express-promise-router: ^4.1.0 + express-rate-limit: ^7.5.0 fs-extra: ^11.2.0 git-url-parse: ^15.0.0 helmet: ^6.0.0 @@ -4516,6 +4435,7 @@ __metadata: pg: ^8.11.3 pg-connection-string: ^2.3.0 pg-format: ^1.0.4 + rate-limit-redis: ^4.2.0 raw-body: ^2.4.1 selfsigned: ^2.0.0 tar: ^6.1.12 @@ -4526,18 +4446,19 @@ __metadata: yauzl: ^3.0.0 yn: ^4.0.0 zod: ^3.22.4 + zod-to-json-schema: ^3.20.4 peerDependencies: "@google-cloud/cloud-sql-connector": ^1.4.0 peerDependenciesMeta: "@google-cloud/cloud-sql-connector": optional: true - checksum: 87ae31e4304d3f5954d0d701d1d4f28bedc339fbd7417df26089c4cc7192ae03898b028a3f6628052deba879b6b1515a0fa4101d1f2a8a480de8aed19854f47a + checksum: a14743f50cb8f627af23aee5760f3b07bbfff5883407bbbe50c85c06df6ac678bc3559496b1d94f5c70ddbebe33673caf5fe56c8bdbc254019561d06962bb892 languageName: node linkType: hard -"@backstage/backend-defaults@npm:^0.11.0": - version: 0.11.0 - resolution: "@backstage/backend-defaults@npm:0.11.0" +"@backstage/backend-defaults@npm:^0.12.0, @backstage/backend-defaults@npm:^0.12.1": + version: 0.12.1 + resolution: "@backstage/backend-defaults@npm:0.12.1" dependencies: "@aws-sdk/abort-controller": ^3.347.0 "@aws-sdk/client-codecommit": ^3.350.0 @@ -4545,19 +4466,19 @@ __metadata: "@aws-sdk/credential-providers": ^3.350.0 "@aws-sdk/types": ^3.347.0 "@azure/storage-blob": ^12.5.0 - "@backstage/backend-app-api": ^1.2.4 + "@backstage/backend-app-api": ^1.2.7 "@backstage/backend-dev-utils": ^0.1.5 - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/cli-node": ^0.2.13 - "@backstage/config": ^1.3.2 - "@backstage/config-loader": ^1.10.1 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/cli-node": ^0.2.14 + "@backstage/config": ^1.3.3 + "@backstage/config-loader": ^1.10.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/integration-aws-node": ^0.1.16 - "@backstage/plugin-auth-node": ^0.6.4 - "@backstage/plugin-events-node": ^0.4.12 - "@backstage/plugin-permission-node": ^0.10.1 - "@backstage/types": ^1.2.1 + "@backstage/integration": ^1.18.0 + "@backstage/integration-aws-node": ^0.1.17 + "@backstage/plugin-auth-node": ^0.6.7 + "@backstage/plugin-events-node": ^0.4.15 + "@backstage/plugin-permission-node": ^0.10.4 + "@backstage/types": ^1.2.2 "@google-cloud/storage": ^7.0.0 "@keyv/memcache": ^2.0.1 "@keyv/redis": ^4.0.1 @@ -4569,7 +4490,7 @@ __metadata: "@types/express": ^4.17.6 archiver: ^7.0.0 base64-stream: ^1.0.0 - better-sqlite3: ^11.0.0 + better-sqlite3: ^12.0.0 compression: ^1.7.4 concat-stream: ^2.0.0 cookie: ^0.7.0 @@ -4581,6 +4502,7 @@ __metadata: fs-extra: ^11.2.0 git-url-parse: ^15.0.0 helmet: ^6.0.0 + infinispan: ^0.12.0 is-glob: ^4.0.3 jose: ^5.0.0 keyv: ^5.2.1 @@ -4614,7 +4536,7 @@ __metadata: peerDependenciesMeta: "@google-cloud/cloud-sql-connector": optional: true - checksum: 9862ad103476b3d347ea96910f8ef6bca3f67e96f87db3f052dbf93f051d067e467d24747be998984ee2eced963ccd36031fa682a1918f31b37a27c77a6f5dbe + checksum: ee043f487eb43eb0aa1e0e709bd9db911302832f117bd7352c2239bf4153e9556537d42b211e8e91d765bb3bbb7eda4700673308d894bf52a0aa862f7afc9e18 languageName: node linkType: hard @@ -4781,19 +4703,54 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-openapi-utils@npm:^0.5.3, @backstage/backend-openapi-utils@npm:^0.5.4": - version: 0.5.4 - resolution: "@backstage/backend-openapi-utils@npm:0.5.4" +"@backstage/backend-dynamic-feature-service@npm:^0.7.3": + version: 0.7.4 + resolution: "@backstage/backend-dynamic-feature-service@npm:0.7.4" + dependencies: + "@backstage/backend-defaults": ^0.12.1 + "@backstage/backend-openapi-utils": ^0.6.1 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/cli-common": ^0.1.15 + "@backstage/cli-node": ^0.2.14 + "@backstage/config": ^1.3.3 + "@backstage/config-loader": ^1.10.3 + "@backstage/errors": ^1.2.7 + "@backstage/plugin-app-node": ^0.1.37 + "@backstage/plugin-auth-node": ^0.6.7 + "@backstage/plugin-catalog-backend": ^3.1.0 + "@backstage/plugin-events-backend": ^0.5.6 + "@backstage/plugin-events-node": ^0.4.15 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.4 + "@backstage/plugin-scaffolder-node": ^0.11.1 + "@backstage/plugin-search-backend-node": ^1.3.15 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/types": ^1.2.2 + "@manypkg/get-packages": ^1.1.3 + "@module-federation/sdk": ^0.9.0 + chokidar: ^3.5.3 + express: ^4.17.1 + express-promise-router: ^4.1.0 + fs-extra: ^11.2.0 + lodash: ^4.17.21 + winston: ^3.2.1 + checksum: 00b0c20ee0104afb3b67ac432937f546a7a1b1f6e9aed0111f9bac4c798b3d759ed89308b0d4212ace80f65249f3974a5dc7ea6838daa30d36036ddb1d641e92 + languageName: node + linkType: hard + +"@backstage/backend-openapi-utils@npm:^0.6.0, @backstage/backend-openapi-utils@npm:^0.6.1": + version: 0.6.1 + resolution: "@backstage/backend-openapi-utils@npm:0.6.1" dependencies: "@apidevtools/swagger-parser": ^10.1.0 - "@backstage/backend-plugin-api": ^1.4.0 + "@backstage/backend-plugin-api": ^1.4.3 "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 + "@backstage/types": ^1.2.2 "@types/express": ^4.17.6 "@types/express-serve-static-core": ^4.17.5 ajv: ^8.16.0 express: ^4.17.1 - express-openapi-validator: ^5.0.4 + express-openapi-validator: ^5.5.8 express-promise-router: ^4.1.0 get-port: ^5.1.1 json-schema-to-ts: ^3.0.0 @@ -4801,45 +4758,29 @@ __metadata: mockttp: ^3.13.0 openapi-merge: ^1.3.2 openapi3-ts: ^3.1.2 - checksum: d9104279f67e100409b736c5df016dd6eb99edbfd394436f62790eeb9f18463dc186ad14cadfc63da3d6994c777b9d8b33c04663f41d4a69e83f8a6baa6e87d2 + checksum: c3d8dc96eaae8a3ea43d9e9f22034ab61e97c5572c70f9740688100c97e5d9c6dab20a9f920296bad06be45b954cfa77b13ad3f8ee36bc19ecd36b686736d38f languageName: node linkType: hard -"@backstage/backend-plugin-api@npm:1.3.0": - version: 1.3.0 - resolution: "@backstage/backend-plugin-api@npm:1.3.0" - dependencies: - "@backstage/cli-common": ^0.1.15 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/plugin-auth-node": ^0.6.2 - "@backstage/plugin-permission-common": ^0.8.4 - "@backstage/plugin-permission-node": ^0.9.1 - "@backstage/types": ^1.2.1 - "@types/express": ^4.17.6 - "@types/luxon": ^3.0.0 - knex: ^3.0.0 - luxon: ^3.0.0 - checksum: cd702c9f54db8758bda04430a7e46cbf7dda0ce2bf77653f9a1eeb7a750d90324fef2d63d19e662c80e1c75da419bbd52a2235683132845678e446ca41885654 - languageName: node - linkType: hard - -"@backstage/backend-plugin-api@npm:1.3.1": - version: 1.3.1 - resolution: "@backstage/backend-plugin-api@npm:1.3.1" +"@backstage/backend-plugin-api@npm:1.4.2": + version: 1.4.2 + resolution: "@backstage/backend-plugin-api@npm:1.4.2" dependencies: "@backstage/cli-common": ^0.1.15 - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-auth-node": ^0.6.3 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.0 + "@backstage/plugin-auth-node": ^0.6.6 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.3 "@backstage/types": ^1.2.1 "@types/express": ^4.17.6 + "@types/json-schema": ^7.0.6 "@types/luxon": ^3.0.0 + json-schema: ^0.4.0 knex: ^3.0.0 luxon: ^3.0.0 - checksum: ba5d214cc5dcc2feeb63433d3ffc3dd78ca4d7eaaa83bbd72e127e11c729e009ee89dbba234355ebc9e73c37ea517966cab279d58994b08e34eafc010e2d202a + zod: ^3.22.4 + checksum: 4aa4ff08a1166f21ff3abc58036ac240b4ca1ebb61132d724119e2f98a76d53a296bb786d3abfbc70511817de7cb6eb08f5060f13b8b0254b6464ce337812f5c languageName: node linkType: hard @@ -4900,36 +4841,17 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-plugin-api@npm:^1.0.0, @backstage/backend-plugin-api@npm:^1.0.2, @backstage/backend-plugin-api@npm:^1.1.1, @backstage/backend-plugin-api@npm:^1.2.0, @backstage/backend-plugin-api@npm:^1.2.1": - version: 1.2.1 - resolution: "@backstage/backend-plugin-api@npm:1.2.1" - dependencies: - "@backstage/cli-common": ^0.1.15 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/plugin-auth-node": ^0.6.1 - "@backstage/plugin-permission-common": ^0.8.4 - "@backstage/plugin-permission-node": ^0.9.0 - "@backstage/types": ^1.2.1 - "@types/express": ^4.17.6 - "@types/luxon": ^3.0.0 - knex: ^3.0.0 - luxon: ^3.0.0 - checksum: 6f8668404fc0761f34100eb8ac7e992eae77c8af9660b21306f48b71b2b66fbc65505ec284d53634dc460300465e5761a23442b903a557c86738ad9f08b53815 - languageName: node - linkType: hard - -"@backstage/backend-plugin-api@npm:^1.3.0, @backstage/backend-plugin-api@npm:^1.3.1, @backstage/backend-plugin-api@npm:^1.4.0": - version: 1.4.0 - resolution: "@backstage/backend-plugin-api@npm:1.4.0" +"@backstage/backend-plugin-api@npm:^1.0.0, @backstage/backend-plugin-api@npm:^1.2.0, @backstage/backend-plugin-api@npm:^1.2.1, @backstage/backend-plugin-api@npm:^1.3.0, @backstage/backend-plugin-api@npm:^1.4.0, @backstage/backend-plugin-api@npm:^1.4.1, @backstage/backend-plugin-api@npm:^1.4.2, @backstage/backend-plugin-api@npm:^1.4.3": + version: 1.4.3 + resolution: "@backstage/backend-plugin-api@npm:1.4.3" dependencies: "@backstage/cli-common": ^0.1.15 - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-auth-node": ^0.6.4 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.1 - "@backstage/types": ^1.2.1 + "@backstage/plugin-auth-node": ^0.6.7 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.4 + "@backstage/types": ^1.2.2 "@types/express": ^4.17.6 "@types/json-schema": ^7.0.6 "@types/luxon": ^3.0.0 @@ -4937,7 +4859,7 @@ __metadata: knex: ^3.0.0 luxon: ^3.0.0 zod: ^3.22.4 - checksum: 2a87546a1cdc71a6369986a4dd611c5e2c345b7f2cf69da19d5cfeffc912b0f0eb3c4b1fc28b6db4141d25fddc5be50977e4a87b3a05b3cdb82a8d542df73718 + checksum: 29eb069677972d462e41ecb57bc6c930eff26af4a791069fb42568166a52d143abacdc248701708fca889043e7b4ebdf1dee6ba28d99d785706e6e5820fb74e3 languageName: node linkType: hard @@ -4962,51 +4884,27 @@ __metadata: languageName: node linkType: hard -"@backstage/catalog-client@npm:^1.10.0, @backstage/catalog-client@npm:^1.10.1": - version: 1.10.1 - resolution: "@backstage/catalog-client@npm:1.10.1" - dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/errors": ^1.2.7 - cross-fetch: ^4.0.0 - uri-template: ^2.0.0 - checksum: ea5cff781d524299766ac19499087f64a9b1c63a9ea02d2e5a982d332061d074c768f11dbc5e4949a415213e13fe9924ebda9013f3fefb31620c87ac60327b2a - languageName: node - linkType: hard - -"@backstage/catalog-client@npm:^1.6.5, @backstage/catalog-client@npm:^1.9.1": - version: 1.9.1 - resolution: "@backstage/catalog-client@npm:1.9.1" +"@backstage/catalog-client@npm:^1.10.2, @backstage/catalog-client@npm:^1.11.0, @backstage/catalog-client@npm:^1.12.0, @backstage/catalog-client@npm:^1.6.5, @backstage/catalog-client@npm:^1.9.1": + version: 1.12.0 + resolution: "@backstage/catalog-client@npm:1.12.0" dependencies: - "@backstage/catalog-model": ^1.7.3 + "@backstage/catalog-model": ^1.7.5 "@backstage/errors": ^1.2.7 cross-fetch: ^4.0.0 uri-template: ^2.0.0 - checksum: 15833bbf98f3ad548ca55218cb5c75f7404e34e1177b776b557e932cc5590fb935129ad74cefda3cf848a0f6a8d151790431957f83e7bb243aeeef487f423320 - languageName: node - linkType: hard - -"@backstage/catalog-model@npm:^1.5.0, @backstage/catalog-model@npm:^1.7.0, @backstage/catalog-model@npm:^1.7.1, @backstage/catalog-model@npm:^1.7.3": - version: 1.7.3 - resolution: "@backstage/catalog-model@npm:1.7.3" - dependencies: - "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 - ajv: ^8.10.0 - lodash: ^4.17.21 - checksum: 1f6202986b13c112cc35481daea2da929656e775b8158c5a796be64e5ff4d1457012935e41574633bc47f437cf228d82f547232b35761359c8273190e8a14889 + checksum: ec5a48a07ff1b0b24ccb0cfb7552580ac0963b1a50dedf69c887aee4d62d99a02768b1b128b090b7d18cadd690426384e36f7db5240b5e076c2b9df41dea26c0 languageName: node linkType: hard -"@backstage/catalog-model@npm:^1.7.4": - version: 1.7.4 - resolution: "@backstage/catalog-model@npm:1.7.4" +"@backstage/catalog-model@npm:^1.5.0, @backstage/catalog-model@npm:^1.7.0, @backstage/catalog-model@npm:^1.7.3, @backstage/catalog-model@npm:^1.7.4, @backstage/catalog-model@npm:^1.7.5": + version: 1.7.5 + resolution: "@backstage/catalog-model@npm:1.7.5" dependencies: "@backstage/errors": ^1.2.7 "@backstage/types": ^1.2.1 ajv: ^8.10.0 lodash: ^4.17.21 - checksum: 23091382334fe8cf38cb671089bb81392211851a0e193d6742de46238b8fb373d25932b363274a705dcc3bdbd48ed19bba2d4641a861340aa53d62e60a250e2f + checksum: 3f8d646268f31020f61a28139906f706b58b6dcf4ea51c4f8475c3a4a4437855406e12dd8cdb0792a7807d491d3a93971f2eb382919667806063a21844396df2 languageName: node linkType: hard @@ -5017,9 +4915,9 @@ __metadata: languageName: node linkType: hard -"@backstage/cli-node@npm:^0.2.12, @backstage/cli-node@npm:^0.2.13, @backstage/cli-node@npm:^0.2.6, @backstage/cli-node@npm:^0.2.7": - version: 0.2.13 - resolution: "@backstage/cli-node@npm:0.2.13" +"@backstage/cli-node@npm:^0.2.12, @backstage/cli-node@npm:^0.2.13, @backstage/cli-node@npm:^0.2.14, @backstage/cli-node@npm:^0.2.6, @backstage/cli-node@npm:^0.2.7": + version: 0.2.14 + resolution: "@backstage/cli-node@npm:0.2.14" dependencies: "@backstage/cli-common": ^0.1.15 "@backstage/errors": ^1.2.7 @@ -5029,32 +4927,32 @@ __metadata: fs-extra: ^11.2.0 semver: ^7.5.3 zod: ^3.22.4 - checksum: d1ce09a728b181db1eae0931ffee81795cd177d32f319edcab1eee8e624820a5bf23c28a9fc70e9883522fc7ded52be232718cc18e418d9febe34ef998737c72 + checksum: a5523f8cfe37a851bb29040d4421d76b21dc17a665584edb99fa483a5f19adfd18765cf5dd2bfce3363356749b67710daff933012f040fe2dd33e0045fc6d44b languageName: node linkType: hard -"@backstage/cli@npm:0.30.0": - version: 0.30.0 - resolution: "@backstage/cli@npm:0.30.0" +"@backstage/cli@npm:^0.26.11": + version: 0.26.11 + resolution: "@backstage/cli@npm:0.26.11" dependencies: - "@backstage/catalog-model": ^1.7.3 - "@backstage/cli-common": ^0.1.15 - "@backstage/cli-node": ^0.2.13 - "@backstage/config": ^1.3.2 - "@backstage/config-loader": ^1.9.6 - "@backstage/errors": ^1.2.7 - "@backstage/eslint-plugin": ^0.1.10 - "@backstage/integration": ^1.16.1 - "@backstage/release-manifests": ^0.0.12 - "@backstage/types": ^1.2.1 + "@backstage/catalog-model": ^1.5.0 + "@backstage/cli-common": ^0.1.14 + "@backstage/cli-node": ^0.2.7 + "@backstage/config": ^1.2.0 + "@backstage/config-loader": ^1.8.1 + "@backstage/errors": ^1.2.4 + "@backstage/eslint-plugin": ^0.1.8 + "@backstage/integration": ^1.13.0 + "@backstage/release-manifests": ^0.0.11 + "@backstage/types": ^1.1.1 "@manypkg/get-packages": ^1.1.3 - "@module-federation/enhanced": ^0.8.0 + "@module-federation/enhanced": ^0.1.19 "@octokit/graphql": ^5.0.0 "@octokit/graphql-schema": ^13.7.0 "@octokit/oauth-app": ^4.2.0 "@octokit/request": ^6.0.0 "@pmmmwh/react-refresh-webpack-plugin": ^0.5.7 - "@rollup/plugin-commonjs": ^26.0.0 + "@rollup/plugin-commonjs": ^25.0.0 "@rollup/plugin-json": ^6.0.0 "@rollup/plugin-node-resolve": ^15.0.0 "@rollup/plugin-yaml": ^4.0.0 @@ -5072,8 +4970,8 @@ __metadata: "@swc/jest": ^0.2.22 "@types/jest": ^29.5.11 "@types/webpack-env": ^1.15.2 - "@typescript-eslint/eslint-plugin": ^8.17.0 - "@typescript-eslint/parser": ^8.16.0 + "@typescript-eslint/eslint-plugin": ^6.12.0 + "@typescript-eslint/parser": ^6.7.2 "@yarnpkg/lockfile": ^1.1.0 "@yarnpkg/parsers": ^3.0.0 bfj: ^8.0.0 @@ -5085,31 +4983,30 @@ __metadata: cross-spawn: ^7.0.3 css-loader: ^6.5.1 ctrlc-windows: ^2.1.0 - esbuild: ^0.24.0 + diff: ^5.0.0 + esbuild: ^0.21.0 esbuild-loader: ^4.0.0 eslint: ^8.6.0 eslint-config-prettier: ^9.0.0 eslint-formatter-friendly: ^7.0.0 - eslint-plugin-deprecation: ^3.0.0 - eslint-plugin-import: ^2.31.0 - eslint-plugin-jest: ^28.9.0 - eslint-plugin-jsx-a11y: ^6.10.2 - eslint-plugin-react: ^7.37.2 - eslint-plugin-react-hooks: ^5.0.0 - eslint-plugin-unused-imports: ^4.1.4 - eslint-webpack-plugin: ^4.2.0 + eslint-plugin-deprecation: ^2.0.0 + eslint-plugin-import: ^2.25.4 + eslint-plugin-jest: ^27.0.0 + eslint-plugin-jsx-a11y: ^6.5.1 + eslint-plugin-react: ^7.28.0 + eslint-plugin-react-hooks: ^4.3.0 + eslint-plugin-unused-imports: ^3.0.0 + eslint-webpack-plugin: ^4.0.0 express: ^4.17.1 fork-ts-checker-webpack-plugin: ^9.0.0 fs-extra: ^11.2.0 - git-url-parse: ^15.0.0 + git-url-parse: ^14.0.0 glob: ^7.1.7 global-agent: ^3.0.0 - globby: ^11.1.0 handlebars: ^4.7.3 - html-webpack-plugin: ^5.6.3 + html-webpack-plugin: ^5.3.1 inquirer: ^8.2.0 jest: ^29.7.0 - jest-cli: ^29.7.0 jest-css-modules: ^2.1.0 jest-environment-jsdom: ^29.0.2 jest-runtime: ^29.0.2 @@ -5117,98 +5014,96 @@ __metadata: lodash: ^4.17.21 mini-css-extract-plugin: ^2.4.2 minimatch: ^9.0.0 - node-stdlib-browser: ^1.3.1 + node-fetch: ^2.6.7 + node-libs-browser: ^2.2.1 npm-packlist: ^5.0.0 ora: ^5.3.0 + p-limit: ^3.1.0 p-queue: ^6.6.2 pirates: ^4.0.6 postcss: ^8.1.0 process: ^0.11.10 - raw-loader: ^4.0.2 react-dev-utils: ^12.0.0-next.60 react-refresh: ^0.14.0 recursive-readdir: ^2.2.2 replace-in-file: ^7.1.0 - rollup: ^4.27.3 + rollup: ^4.0.0 rollup-plugin-dts: ^6.1.0 rollup-plugin-esbuild: ^6.1.1 rollup-plugin-postcss: ^4.0.0 rollup-pluginutils: ^2.8.2 + run-script-webpack-plugin: ^0.2.0 semver: ^7.5.3 style-loader: ^3.3.1 sucrase: ^3.20.2 swc-loader: ^0.2.3 tar: ^6.1.12 terser-webpack-plugin: ^5.1.3 - ts-morph: ^24.0.0 - undici: ^7.2.3 util: ^0.12.3 - webpack: ^5.94.0 + webpack: ^5.70.0 webpack-dev-server: ^5.0.0 + webpack-node-externals: ^3.0.0 yaml: ^2.0.0 - yargs: ^16.2.0 yml-loader: ^2.1.0 yn: ^4.0.0 zod: ^3.22.4 - zod-validation-error: ^3.4.0 peerDependencies: - "@rspack/core": ^1.0.10 - "@rspack/dev-server": ^1.0.9 - "@rspack/plugin-react-refresh": ^1.0.0 + "@vitejs/plugin-react": ^4.0.4 + vite: ^4.4.9 + vite-plugin-html: ^3.2.0 + vite-plugin-node-polyfills: ^0.22.0 peerDependenciesMeta: - "@rspack/core": + "@vitejs/plugin-react": + optional: true + vite: optional: true - "@rspack/dev-server": + vite-plugin-html: optional: true - "@rspack/plugin-react-refresh": + vite-plugin-node-polyfills: optional: true bin: backstage-cli: bin/backstage-cli - checksum: b643a0ea2cb335a7653b9a47f03db0a5f5bc1481de7951dc7944242e55ff3d4b888dfab26eecb1e2e1d9eda0a68671a75b7ab9b9d9dc08aaeaa8715c8557b74b + checksum: 328525101cfa824722e7bdace20dbdb8f7ef55a1eb3b7084f03394177db5f13fe3e49a4746d07ae5d7fbb9ee45f01f239bb19cf4f59f28bf5c8093c395caea0f languageName: node linkType: hard -"@backstage/cli@npm:^0.26.11": - version: 0.26.11 - resolution: "@backstage/cli@npm:0.26.11" +"@backstage/cli@npm:^0.34.1": + version: 0.34.1 + resolution: "@backstage/cli@npm:0.34.1" dependencies: - "@backstage/catalog-model": ^1.5.0 - "@backstage/cli-common": ^0.1.14 - "@backstage/cli-node": ^0.2.7 - "@backstage/config": ^1.2.0 - "@backstage/config-loader": ^1.8.1 - "@backstage/errors": ^1.2.4 - "@backstage/eslint-plugin": ^0.1.8 - "@backstage/integration": ^1.13.0 - "@backstage/release-manifests": ^0.0.11 - "@backstage/types": ^1.1.1 + "@backstage/catalog-model": ^1.7.5 + "@backstage/cli-common": ^0.1.15 + "@backstage/cli-node": ^0.2.14 + "@backstage/config": ^1.3.3 + "@backstage/config-loader": ^1.10.2 + "@backstage/errors": ^1.2.7 + "@backstage/eslint-plugin": ^0.1.11 + "@backstage/integration": ^1.17.1 + "@backstage/release-manifests": ^0.0.13 + "@backstage/types": ^1.2.1 "@manypkg/get-packages": ^1.1.3 - "@module-federation/enhanced": ^0.1.19 + "@module-federation/enhanced": ^0.9.0 "@octokit/graphql": ^5.0.0 "@octokit/graphql-schema": ^13.7.0 "@octokit/oauth-app": ^4.2.0 - "@octokit/request": ^6.0.0 - "@pmmmwh/react-refresh-webpack-plugin": ^0.5.7 - "@rollup/plugin-commonjs": ^25.0.0 + "@octokit/request": ^8.0.0 + "@rollup/plugin-commonjs": ^26.0.0 "@rollup/plugin-json": ^6.0.0 "@rollup/plugin-node-resolve": ^15.0.0 "@rollup/plugin-yaml": ^4.0.0 + "@rspack/core": ^1.4.11 + "@rspack/dev-server": ^1.1.4 + "@rspack/plugin-react-refresh": ^1.4.3 "@spotify/eslint-config-base": ^15.0.0 "@spotify/eslint-config-react": ^15.0.0 "@spotify/eslint-config-typescript": ^15.0.0 - "@sucrase/webpack-loader": ^2.0.0 - "@svgr/core": 6.5.x - "@svgr/plugin-jsx": 6.5.x - "@svgr/plugin-svgo": 6.5.x - "@svgr/rollup": 6.5.x - "@svgr/webpack": 6.5.x "@swc/core": ^1.3.46 "@swc/helpers": ^0.5.0 "@swc/jest": ^0.2.22 "@types/jest": ^29.5.11 "@types/webpack-env": ^1.15.2 - "@typescript-eslint/eslint-plugin": ^6.12.0 - "@typescript-eslint/parser": ^6.7.2 + "@typescript-eslint/eslint-plugin": ^8.17.0 + "@typescript-eslint/parser": ^8.16.0 "@yarnpkg/lockfile": ^1.1.0 "@yarnpkg/parsers": ^3.0.0 bfj: ^8.0.0 @@ -5220,121 +5115,110 @@ __metadata: cross-spawn: ^7.0.3 css-loader: ^6.5.1 ctrlc-windows: ^2.1.0 - diff: ^5.0.0 - esbuild: ^0.21.0 - esbuild-loader: ^4.0.0 + esbuild: ^0.25.0 eslint: ^8.6.0 eslint-config-prettier: ^9.0.0 eslint-formatter-friendly: ^7.0.0 - eslint-plugin-deprecation: ^2.0.0 - eslint-plugin-import: ^2.25.4 - eslint-plugin-jest: ^27.0.0 - eslint-plugin-jsx-a11y: ^6.5.1 - eslint-plugin-react: ^7.28.0 - eslint-plugin-react-hooks: ^4.3.0 - eslint-plugin-unused-imports: ^3.0.0 - eslint-webpack-plugin: ^4.0.0 + eslint-plugin-deprecation: ^3.0.0 + eslint-plugin-import: ^2.31.0 + eslint-plugin-jest: ^28.9.0 + eslint-plugin-jsx-a11y: ^6.10.2 + eslint-plugin-react: ^7.37.2 + eslint-plugin-react-hooks: ^5.0.0 + eslint-plugin-unused-imports: ^4.1.4 + eslint-rspack-plugin: ^4.2.1 express: ^4.17.1 - fork-ts-checker-webpack-plugin: ^9.0.0 fs-extra: ^11.2.0 - git-url-parse: ^14.0.0 + git-url-parse: ^15.0.0 glob: ^7.1.7 global-agent: ^3.0.0 + globby: ^11.1.0 handlebars: ^4.7.3 - html-webpack-plugin: ^5.3.1 + html-webpack-plugin: ^5.6.3 inquirer: ^8.2.0 jest: ^29.7.0 + jest-cli: ^29.7.0 jest-css-modules: ^2.1.0 jest-environment-jsdom: ^29.0.2 jest-runtime: ^29.0.2 json-schema: ^0.4.0 lodash: ^4.17.21 - mini-css-extract-plugin: ^2.4.2 minimatch: ^9.0.0 - node-fetch: ^2.6.7 - node-libs-browser: ^2.2.1 + node-stdlib-browser: ^1.3.1 npm-packlist: ^5.0.0 ora: ^5.3.0 - p-limit: ^3.1.0 p-queue: ^6.6.2 pirates: ^4.0.6 postcss: ^8.1.0 process: ^0.11.10 + raw-loader: ^4.0.2 react-dev-utils: ^12.0.0-next.60 - react-refresh: ^0.14.0 + react-refresh: ^0.17.0 recursive-readdir: ^2.2.2 replace-in-file: ^7.1.0 - rollup: ^4.0.0 + rollup: ^4.27.3 rollup-plugin-dts: ^6.1.0 rollup-plugin-esbuild: ^6.1.1 rollup-plugin-postcss: ^4.0.0 rollup-pluginutils: ^2.8.2 - run-script-webpack-plugin: ^0.2.0 semver: ^7.5.3 style-loader: ^3.3.1 sucrase: ^3.20.2 swc-loader: ^0.2.3 tar: ^6.1.12 - terser-webpack-plugin: ^5.1.3 + ts-checker-rspack-plugin: ^1.1.5 + ts-morph: ^24.0.0 + undici: ^7.2.3 util: ^0.12.3 - webpack: ^5.70.0 - webpack-dev-server: ^5.0.0 - webpack-node-externals: ^3.0.0 yaml: ^2.0.0 + yargs: ^16.2.0 yml-loader: ^2.1.0 yn: ^4.0.0 zod: ^3.22.4 + zod-validation-error: ^3.4.0 peerDependencies: - "@vitejs/plugin-react": ^4.0.4 - vite: ^4.4.9 - vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.22.0 + "@module-federation/enhanced": ^0.9.0 + "@pmmmwh/react-refresh-webpack-plugin": ^0.5.7 + esbuild-loader: ^4.0.0 + eslint-webpack-plugin: ^4.2.0 + fork-ts-checker-webpack-plugin: ^9.0.0 + mini-css-extract-plugin: ^2.4.2 + terser-webpack-plugin: ^5.1.3 + webpack: ~5.96.0 + webpack-dev-server: ^5.0.0 peerDependenciesMeta: - "@vitejs/plugin-react": + "@module-federation/enhanced": optional: true - vite: + "@pmmmwh/react-refresh-webpack-plugin": optional: true - vite-plugin-html: + esbuild-loader: optional: true - vite-plugin-node-polyfills: + eslint-webpack-plugin: + optional: true + fork-ts-checker-webpack-plugin: + optional: true + mini-css-extract-plugin: + optional: true + terser-webpack-plugin: + optional: true + webpack: + optional: true + webpack-dev-server: optional: true bin: backstage-cli: bin/backstage-cli - checksum: 328525101cfa824722e7bdace20dbdb8f7ef55a1eb3b7084f03394177db5f13fe3e49a4746d07ae5d7fbb9ee45f01f239bb19cf4f59f28bf5c8093c395caea0f - languageName: node - linkType: hard - -"@backstage/config-loader@npm:^1.10.0, @backstage/config-loader@npm:^1.8.0, @backstage/config-loader@npm:^1.8.1, @backstage/config-loader@npm:^1.9.0, @backstage/config-loader@npm:^1.9.1, @backstage/config-loader@npm:^1.9.5, @backstage/config-loader@npm:^1.9.6": - version: 1.10.0 - resolution: "@backstage/config-loader@npm:1.10.0" - dependencies: - "@backstage/cli-common": ^0.1.15 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 - "@types/json-schema": ^7.0.6 - ajv: ^8.10.0 - chokidar: ^3.5.2 - fs-extra: ^11.2.0 - json-schema: ^0.4.0 - json-schema-merge-allof: ^0.8.1 - json-schema-traverse: ^1.0.0 - lodash: ^4.17.21 - minimist: ^1.2.5 - typescript-json-schema: ^0.65.0 - yaml: ^2.0.0 - checksum: a73155228a81c6096b87bddbd8dd54d01852e2b22c3e16fdf6ec6dcc86fa70dfc686191d91a70875755b6ec3732427b74b551b8458553d90469e3637fadaa384 + checksum: 1070467303be5d5e9209de4228f8046c094d990c597fbcdb3a27e8c49027b174452689e6fe0c4e719aebd4d33a9608202fc741cb9ac7dec32b8b76f30ed820a0 languageName: node linkType: hard -"@backstage/config-loader@npm:^1.10.1": - version: 1.10.1 - resolution: "@backstage/config-loader@npm:1.10.1" +"@backstage/config-loader@npm:^1.10.0, @backstage/config-loader@npm:^1.10.2, @backstage/config-loader@npm:^1.10.3, @backstage/config-loader@npm:^1.8.0, @backstage/config-loader@npm:^1.8.1, @backstage/config-loader@npm:^1.9.0, @backstage/config-loader@npm:^1.9.1, @backstage/config-loader@npm:^1.9.5": + version: 1.10.4 + resolution: "@backstage/config-loader@npm:1.10.4" dependencies: "@backstage/cli-common": ^0.1.15 - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.4 "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 + "@backstage/types": ^1.2.2 "@types/json-schema": ^7.0.6 ajv: ^8.10.0 chokidar: ^3.5.2 @@ -5346,56 +5230,28 @@ __metadata: minimist: ^1.2.5 typescript-json-schema: ^0.65.0 yaml: ^2.0.0 - checksum: 89e49c51ee401d9fe2a843cf756bfc41f178494d7f9499ca2abef9dcff99a0770bd74099b4720e54567d9c7e506fe5de89b079876079fd127b2f066826e694b7 + checksum: fe42f79b0eafa6825c241f882d3916c70b11c0f1063bbee1c76c3b0cc9a611e601a3e86277fad4456339eea144f936e83610811f65855fde094416ff65083468 languageName: node linkType: hard -"@backstage/config@npm:^1.2.0, @backstage/config@npm:^1.3.0, @backstage/config@npm:^1.3.2": - version: 1.3.2 - resolution: "@backstage/config@npm:1.3.2" +"@backstage/config@npm:^1.2.0, @backstage/config@npm:^1.3.2, @backstage/config@npm:^1.3.3, @backstage/config@npm:^1.3.4, @backstage/config@npm:^1.3.5": + version: 1.3.5 + resolution: "@backstage/config@npm:1.3.5" dependencies: "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 + "@backstage/types": ^1.2.2 ms: ^2.1.3 - checksum: a8688592f2b0469c8018f951d09a1ffd024e39eeced40e67a6f4a9fb355b530699ba7e06c04aeaf7d9f69080ce4bf62fd6ba0d563889583e09b978d36d4cff53 - languageName: node - linkType: hard - -"@backstage/core-app-api@npm:^1.16.0": - version: 1.16.1 - resolution: "@backstage/core-app-api@npm:1.16.1" - dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-plugin-api": ^1.10.6 - "@backstage/types": ^1.2.1 - "@backstage/version-bridge": ^1.0.11 - "@types/prop-types": ^15.7.3 - history: ^5.0.0 - i18next: ^22.4.15 - lodash: ^4.17.21 - prop-types: ^15.7.2 - react-use: ^17.2.4 - zen-observable: ^0.10.0 - zod: ^3.22.4 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: f10fe66f4f5e6522691979de7cbefe4ef15cb3934f6777be578c26a180324e336ef6ab7a054ebb839efe9c6535ff3a9ab5d658e023d2441b4d34c378faa1e015 + checksum: db4af0cf1f9e8c269da9fd9798a537e5527f9ff10aba08451fb863fe6fce5e9f5510db23830871a76231b5ac63f8814c694de32d66209c59d7f5e569ca045819 languageName: node linkType: hard -"@backstage/core-app-api@npm:^1.17.1": - version: 1.17.1 - resolution: "@backstage/core-app-api@npm:1.17.1" +"@backstage/core-app-api@npm:^1.18.0, @backstage/core-app-api@npm:^1.19.0, @backstage/core-app-api@npm:^1.19.1": + version: 1.19.1 + resolution: "@backstage/core-app-api@npm:1.19.1" dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/types": ^1.2.1 + "@backstage/config": ^1.3.5 + "@backstage/core-plugin-api": ^1.11.1 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 "@types/prop-types": ^15.7.3 history: ^5.0.0 @@ -5413,37 +5269,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 986d585240b8d276eeb2576205775d24ba1ed045ffbcb39cac99d16427644ad43c1969159a82f07638daa187421c0da9f2374fc11e83f201be317c4cb97b55cc - languageName: node - linkType: hard - -"@backstage/core-compat-api@npm:^0.3.3": - version: 0.3.6 - resolution: "@backstage/core-compat-api@npm:0.3.6" - dependencies: - "@backstage/core-plugin-api": ^1.10.4 - "@backstage/frontend-plugin-api": ^0.9.5 - "@backstage/version-bridge": ^1.0.11 - lodash: ^4.17.21 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: d5d91c8162a6e83132bcaabdb8abd727b8180438c2474de95a543b7e8732c365a22a81c4bf953e60ecb71df5eac227f7a060c9f4101aa6a5b2c1ad7be40a86f3 + checksum: 71194340ff8478d9b771f01952799beec78fdf59560d8a198fdf884d3da4c9f3863e81be58eb8e139a5b1b34f7eb98ed7e2250c8bd721ff649ce8da3f1961497 languageName: node linkType: hard -"@backstage/core-compat-api@npm:^0.4.0": - version: 0.4.0 - resolution: "@backstage/core-compat-api@npm:0.4.0" +"@backstage/core-compat-api@npm:^0.4.3, @backstage/core-compat-api@npm:^0.4.4": + version: 0.4.4 + resolution: "@backstage/core-compat-api@npm:0.4.4" dependencies: - "@backstage/core-plugin-api": ^1.10.5 - "@backstage/frontend-plugin-api": ^0.10.0 - "@backstage/plugin-catalog-react": ^1.16.0 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-plugin-api": ^0.10.4 + "@backstage/plugin-catalog-react": ^1.19.1 "@backstage/version-bridge": ^1.0.11 lodash: ^4.17.21 peerDependencies: @@ -5454,17 +5290,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 783ee24e7c9b7a495201049fc239de18328c6f02d192e8922d3adeb8c8e9a7bb13431f6b341a1464a885f88af4da7fbdff02f93061274597375fcfd32e54cb42 + checksum: cea1718036b29cedaf524e1e06d1c0120d0503c6af95f211b2db3c03e458926e4fa087f31c3261dfac9813d6acca13e83ae0f1da869af15ec1d24d171e949a8f languageName: node linkType: hard -"@backstage/core-compat-api@npm:^0.4.2, @backstage/core-compat-api@npm:^0.4.3": - version: 0.4.3 - resolution: "@backstage/core-compat-api@npm:0.4.3" +"@backstage/core-compat-api@npm:^0.5.0, @backstage/core-compat-api@npm:^0.5.1, @backstage/core-compat-api@npm:^0.5.2, @backstage/core-compat-api@npm:^0.5.3": + version: 0.5.3 + resolution: "@backstage/core-compat-api@npm:0.5.3" dependencies: - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-catalog-react": ^1.19.0 + "@backstage/core-plugin-api": ^1.11.1 + "@backstage/frontend-plugin-api": ^0.12.1 + "@backstage/plugin-catalog-react": ^1.21.2 "@backstage/version-bridge": ^1.0.11 lodash: ^4.17.21 peerDependencies: @@ -5475,60 +5311,11 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 123d4d5bd02443bf6ee1b7b0d08be69850214447aaf4e7a100817e932e961331eea496f35b3cf0f1d8edef98fad75c511307f329ca0a3df4002cb60b8e84bec9 - languageName: node - linkType: hard - -"@backstage/core-components@npm:^0.14.9": - version: 0.14.10 - resolution: "@backstage/core-components@npm:0.14.10" - dependencies: - "@backstage/config": ^1.2.0 - "@backstage/core-plugin-api": ^1.9.3 - "@backstage/errors": ^1.2.4 - "@backstage/theme": ^0.5.6 - "@backstage/version-bridge": ^1.0.8 - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^24.0.0 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 - "@types/react-sparklines": ^1.7.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 - lodash: ^4.17.21 - pluralize: ^8.0.0 - qs: ^6.9.4 - rc-progress: 3.5.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-idle-timer: 5.7.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.11 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ^3.22.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 303682d411b846a4892b27c1064d499dbd4eccb5a3cdc5acbb1d3247e1141f4704efc7bd286744c19818487e52a61891943156817f59e3bd6555926f7331f575 + checksum: 3c10024121cbe6f5c184f4ad59be6b9b7fe6456a66e80e9a19b9a482a221805b8c8ebced4b31d29efde8f0c866a01f4a01ef21c6e633b45ae2032b5ac29b3a9d languageName: node linkType: hard -"@backstage/core-components@npm:^0.16.1, @backstage/core-components@npm:^0.16.3, @backstage/core-components@npm:^0.16.4": +"@backstage/core-components@npm:^0.16.3": version: 0.16.4 resolution: "@backstage/core-components@npm:0.16.4" dependencies: @@ -5582,14 +5369,14 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.17.0": - version: 0.17.0 - resolution: "@backstage/core-components@npm:0.17.0" +"@backstage/core-components@npm:^0.17.3, @backstage/core-components@npm:^0.17.4, @backstage/core-components@npm:^0.17.5": + version: 0.17.5 + resolution: "@backstage/core-components@npm:0.17.5" dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-plugin-api": ^1.10.5 + "@backstage/config": ^1.3.3 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/theme": ^0.6.4 + "@backstage/theme": ^0.6.8 "@backstage/version-bridge": ^1.0.11 "@dagrejs/dagre": ^1.1.4 "@date-io/core": ^1.3.13 @@ -5606,8 +5393,8 @@ __metadata: d3-shape: ^3.0.0 d3-zoom: ^3.0.0 js-yaml: ^4.1.0 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 + linkify-react: 4.3.2 + linkifyjs: 4.3.2 lodash: ^4.17.21 pluralize: ^8.0.0 qs: ^6.9.4 @@ -5632,18 +5419,18 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 2b4a285cc812757b513b565cac7972804da6402b910dae52cc1228f9dc520a2eb4e4089ae96ffb82a5beec2155aecda3c95f5296e242a454f6cc221e66718d72 + checksum: cc04f3447f4793779d65068a7ff7b5cfd83af107eab8a68df819de3cd9ec29f18495aa9125f58b1053072620e567e8cb2c01fc465b7a7ea48f11bc3d030f388b languageName: node linkType: hard -"@backstage/core-components@npm:^0.17.1, @backstage/core-components@npm:^0.17.2, @backstage/core-components@npm:^0.17.3": - version: 0.17.3 - resolution: "@backstage/core-components@npm:0.17.3" +"@backstage/core-components@npm:^0.18.0, @backstage/core-components@npm:^0.18.1, @backstage/core-components@npm:^0.18.2": + version: 0.18.2 + resolution: "@backstage/core-components@npm:0.18.2" dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/config": ^1.3.5 + "@backstage/core-plugin-api": ^1.11.1 "@backstage/errors": ^1.2.7 - "@backstage/theme": ^0.6.6 + "@backstage/theme": ^0.7.0 "@backstage/version-bridge": ^1.0.11 "@dagrejs/dagre": ^1.1.4 "@date-io/core": ^1.3.13 @@ -5660,12 +5447,13 @@ __metadata: d3-shape: ^3.0.0 d3-zoom: ^3.0.0 js-yaml: ^4.1.0 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 + linkify-react: 4.3.2 + linkifyjs: 4.3.2 lodash: ^4.17.21 pluralize: ^8.0.0 qs: ^6.9.4 rc-progress: 3.5.1 + react-full-screen: ^1.1.1 react-helmet: 6.1.0 react-hook-form: ^7.12.2 react-idle-timer: 5.7.2 @@ -5686,36 +5474,15 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 7341d7f21223175919e7974e5ef83734d5286a9d480b024490abc90f986be977b735c3aaef4d48de1ee6dcaa969a7106ae0c21030aaccc024c60177a869d6b36 - languageName: node - linkType: hard - -"@backstage/core-plugin-api@npm:1.10.7": - version: 1.10.7 - resolution: "@backstage/core-plugin-api@npm:1.10.7" - dependencies: - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 - "@backstage/version-bridge": ^1.0.11 - history: ^5.0.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 4f421c8367e502c4697eb3170c2c836958c559c1d5e84458f9677328a4ab3879476e13e5cae6b46c9236f1d14e41b23a8ec16c56ba2b787f78bc013d189eac36 + checksum: efe4c5bd1412a72f0f98f433e0f5eda26012c1c4e331ea5c48442f5647456c93a3c7944f81a386981409b44f201a44323621b260844a2daa9f56f69971d3b387 languageName: node linkType: hard -"@backstage/core-plugin-api@npm:^1.10.1, @backstage/core-plugin-api@npm:^1.10.3, @backstage/core-plugin-api@npm:^1.10.4, @backstage/core-plugin-api@npm:^1.10.5, @backstage/core-plugin-api@npm:^1.10.6, @backstage/core-plugin-api@npm:^1.9.3": - version: 1.10.6 - resolution: "@backstage/core-plugin-api@npm:1.10.6" +"@backstage/core-plugin-api@npm:1.10.9": + version: 1.10.9 + resolution: "@backstage/core-plugin-api@npm:1.10.9" dependencies: - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 "@backstage/types": ^1.2.1 "@backstage/version-bridge": ^1.0.11 @@ -5728,17 +5495,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 0f5933b07d19f3ce796503c38f7d73b94adf40df3e88f6cc55c363e2d92939f5d83c6d97730db98a4b9c4d0cf903cbf93d5df68399e9a603c93a9825fed8102a + checksum: 724ebbb26be3fe9f49dd54ff5fe6928af67994347d805b5576cb1142156f449168afbf160ec4142510c47590db577ef60c7e18f1d5f6040ddaf901040f292a89 languageName: node linkType: hard -"@backstage/core-plugin-api@npm:^1.10.7, @backstage/core-plugin-api@npm:^1.10.8": - version: 1.10.8 - resolution: "@backstage/core-plugin-api@npm:1.10.8" +"@backstage/core-plugin-api@npm:^1.10.3, @backstage/core-plugin-api@npm:^1.10.4, @backstage/core-plugin-api@npm:^1.10.8, @backstage/core-plugin-api@npm:^1.10.9, @backstage/core-plugin-api@npm:^1.11.0, @backstage/core-plugin-api@npm:^1.11.1, @backstage/core-plugin-api@npm:^1.9.3": + version: 1.11.1 + resolution: "@backstage/core-plugin-api@npm:1.11.1" dependencies: - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.5 "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 history: ^5.0.0 peerDependencies: @@ -5749,11 +5516,11 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: c73a0fa667a80f7623881f96dd75aa3d5b7b358ac7c3570f5c5e24cb1695d9e84b1a2b7aeb4d1e5090b8418b4c0db6a883901b8daa827da5cc09613db79f896d + checksum: a3e2bbd2cc621124d39565728ec2a2b673da62d992b18b32b5d18d75de5a80be12ceb3e3c8f26953fac636969aa17793a0d245902954a8e5a5035597a5973b18 languageName: node linkType: hard -"@backstage/errors@npm:^1.2.3, @backstage/errors@npm:^1.2.4, @backstage/errors@npm:^1.2.5, @backstage/errors@npm:^1.2.7": +"@backstage/errors@npm:^1.2.3, @backstage/errors@npm:^1.2.4, @backstage/errors@npm:^1.2.7": version: 1.2.7 resolution: "@backstage/errors@npm:1.2.7" dependencies: @@ -5763,26 +5530,26 @@ __metadata: languageName: node linkType: hard -"@backstage/eslint-plugin@npm:^0.1.10, @backstage/eslint-plugin@npm:^0.1.8": - version: 0.1.10 - resolution: "@backstage/eslint-plugin@npm:0.1.10" +"@backstage/eslint-plugin@npm:^0.1.11, @backstage/eslint-plugin@npm:^0.1.8": + version: 0.1.11 + resolution: "@backstage/eslint-plugin@npm:0.1.11" dependencies: "@manypkg/get-packages": ^1.1.3 minimatch: ^9.0.0 - checksum: 1952a39e1ba5ef1c71cb48ba7908c4e545fc20eba962a2481d574f80b998f21d1ced7602b04415ba4b5ae1aa52c289c307b9d3f0950eeedecc895dcbb0c878a4 + checksum: e6d6ee8ad07d17c634fd4a7388711268dd75debcd23148d0a4ceba2575d0138f617c1d794bd98d46925aa9db556c9cd1cfe4f092fcd974d80d38dd4cc2274b7b languageName: node linkType: hard -"@backstage/frontend-app-api@npm:^0.11.0": - version: 0.11.0 - resolution: "@backstage/frontend-app-api@npm:0.11.0" +"@backstage/frontend-app-api@npm:^0.12.0": + version: 0.12.0 + resolution: "@backstage/frontend-app-api@npm:0.12.0" dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-app-api": ^1.16.0 - "@backstage/core-plugin-api": ^1.10.5 + "@backstage/config": ^1.3.3 + "@backstage/core-app-api": ^1.18.0 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/frontend-defaults": ^0.2.0 - "@backstage/frontend-plugin-api": ^0.10.0 + "@backstage/frontend-defaults": ^0.3.0 + "@backstage/frontend-plugin-api": ^0.11.0 "@backstage/types": ^1.2.1 "@backstage/version-bridge": ^1.0.11 lodash: ^4.17.21 @@ -5795,21 +5562,21 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 1324a5adcc3ff1b588e78d32a394498d9798a8dd0cace324d2944850cb4c105dbfbda9dfc1818e2d74b6f0c30861f756141029b01fa3c1cafbb967acbe9ab4f8 + checksum: 28a6289a155ae7b497d9f99a72b282808f0704f90f2bf95910e728b2d069d39c6beb5b7ead42ff9efdb89a6b5b5ee175ed525f97c9b6fa4e6e341069aff2c36a languageName: node linkType: hard -"@backstage/frontend-app-api@npm:^0.11.2, @backstage/frontend-app-api@npm:^0.11.3": - version: 0.11.3 - resolution: "@backstage/frontend-app-api@npm:0.11.3" +"@backstage/frontend-app-api@npm:^0.13.0, @backstage/frontend-app-api@npm:^0.13.1": + version: 0.13.1 + resolution: "@backstage/frontend-app-api@npm:0.13.1" dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-app-api": ^1.17.1 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/config": ^1.3.5 + "@backstage/core-app-api": ^1.19.1 + "@backstage/core-plugin-api": ^1.11.1 "@backstage/errors": ^1.2.7 - "@backstage/frontend-defaults": ^0.2.3 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/types": ^1.2.1 + "@backstage/frontend-defaults": ^0.3.2 + "@backstage/frontend-plugin-api": ^0.12.1 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 lodash: ^4.17.21 zod: ^3.22.4 @@ -5821,41 +5588,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 9c37c997671bf14bcd245e640e371eb3bf6f5c08cea6c5935397c24a8df9e767432f532fda7d8c8e71ae0aafd6d285df3351607185fee0004b335fe134f10814 - languageName: node - linkType: hard - -"@backstage/frontend-defaults@npm:^0.2.0": - version: 0.2.0 - resolution: "@backstage/frontend-defaults@npm:0.2.0" - dependencies: - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/frontend-app-api": ^0.11.0 - "@backstage/frontend-plugin-api": ^0.10.0 - "@backstage/plugin-app": ^0.1.7 - "@react-hookz/web": ^24.0.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 0d1291dfb94f87353c66da728f4dacceebac78a9c9bd6acb359ef3f46c941d96ef59bca55c4beede813d224ee82d69f2d8d17d5d2cd79cbaa03ed4aec7a03f00 + checksum: e6cd436105a5edf2459e097283f1a79755b837ecf8629209db35370c9cfc9deedef946aee809b901ae936ece745536064208e1350420cc91ce22ed205fcaab77 languageName: node linkType: hard -"@backstage/frontend-defaults@npm:^0.2.3": - version: 0.2.3 - resolution: "@backstage/frontend-defaults@npm:0.2.3" +"@backstage/frontend-defaults@npm:^0.3.0, @backstage/frontend-defaults@npm:^0.3.2": + version: 0.3.2 + resolution: "@backstage/frontend-defaults@npm:0.3.2" dependencies: - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.5 + "@backstage/core-components": ^0.18.2 "@backstage/errors": ^1.2.7 - "@backstage/frontend-app-api": ^0.11.3 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-app": ^0.1.10 + "@backstage/frontend-app-api": ^0.13.1 + "@backstage/frontend-plugin-api": ^0.12.1 + "@backstage/plugin-app": ^0.3.1 "@react-hookz/web": ^24.0.0 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -5865,16 +5611,16 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: b03f5d7f36284a629f2d628e8275f4256745954003a006ec80e31701029ce56cb022d60debc281a860ffb83b8544035cb828ecc5e79306dc09304c37a712d443 + checksum: 868e772ca3c35e720213809c97add5b0f4b4f49ebc31e3872280b95d5bb545f9d23a870200276f7ba657afd48f4aeee72094acd4494099d30a0945617d78630a languageName: node linkType: hard -"@backstage/frontend-plugin-api@npm:^0.10.0": - version: 0.10.0 - resolution: "@backstage/frontend-plugin-api@npm:0.10.0" +"@backstage/frontend-plugin-api@npm:^0.10.3, @backstage/frontend-plugin-api@npm:^0.10.4": + version: 0.10.4 + resolution: "@backstage/frontend-plugin-api@npm:0.10.4" dependencies: - "@backstage/core-components": ^0.17.0 - "@backstage/core-plugin-api": ^1.10.5 + "@backstage/core-components": ^0.17.4 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/types": ^1.2.1 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.4 @@ -5889,16 +5635,16 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: aa56771b94033d4825aaad0007d93f99061b60d114d0cf10c54aacc5087806cf709bdc2c5d30e32bb3a49cce050dcc5068fea4d14d099f4589c2400bd2ad45a1 + checksum: 5318659cceb47951d01c08f744c85ffea8d59d1e4d6a989d22529e25e632996302fa27744f192e438339f512dd4298cd39c83b9552b31d51721c17631cdd2236 languageName: node linkType: hard -"@backstage/frontend-plugin-api@npm:^0.10.2, @backstage/frontend-plugin-api@npm:^0.10.3": - version: 0.10.3 - resolution: "@backstage/frontend-plugin-api@npm:0.10.3" +"@backstage/frontend-plugin-api@npm:^0.11.0": + version: 0.11.0 + resolution: "@backstage/frontend-plugin-api@npm:0.11.0" dependencies: - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/types": ^1.2.1 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.4 @@ -5913,17 +5659,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 5bf7a5cf03ceaea5f63d4db188fe97174fda1a04592dd3e0b2571a77c6865ec8fd51f1a58adfcf0c8220189e0f0b2f77fc62d492d61374ebb7c2e2c72b47e6fa + checksum: ed71036448c8de36b68c530a4a7d18cc2af3704d1b392d50de9da2ee1ac66d9aefb756375f4acc34bed9a6596cd8152bdfd80ee854f6ddd5a0d358f0fb39f47a languageName: node linkType: hard -"@backstage/frontend-plugin-api@npm:^0.9.2, @backstage/frontend-plugin-api@npm:^0.9.5": - version: 0.9.5 - resolution: "@backstage/frontend-plugin-api@npm:0.9.5" +"@backstage/frontend-plugin-api@npm:^0.12.0, @backstage/frontend-plugin-api@npm:^0.12.1": + version: 0.12.1 + resolution: "@backstage/frontend-plugin-api@npm:0.12.1" dependencies: - "@backstage/core-components": ^0.16.4 - "@backstage/core-plugin-api": ^1.10.4 - "@backstage/types": ^1.2.1 + "@backstage/core-components": ^0.18.2 + "@backstage/core-plugin-api": ^1.11.1 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.4 lodash: ^4.17.21 @@ -5937,20 +5683,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 6d727528f3d1ccd9acd55fd708034b1613709b250cb7d2909f7a816ea5c1c106b72259494a870272961784e9ca66a7f5a109f9318b507b7757de7744c2798578 + checksum: 9b203477ed2075e357135244e0d6440ccb548132e15aa94bddd00c32bbb44063007974af36b6ed77970d5290f8c2730c8e6b47bd13a99bb12762932522ba47c8 languageName: node linkType: hard -"@backstage/frontend-test-utils@npm:^0.3.0": - version: 0.3.0 - resolution: "@backstage/frontend-test-utils@npm:0.3.0" - dependencies: - "@backstage/config": ^1.3.2 - "@backstage/frontend-app-api": ^0.11.0 - "@backstage/frontend-plugin-api": ^0.10.0 - "@backstage/plugin-app": ^0.1.7 - "@backstage/test-utils": ^1.7.6 - "@backstage/types": ^1.2.1 +"@backstage/frontend-test-utils@npm:^0.3.5": + version: 0.3.6 + resolution: "@backstage/frontend-test-utils@npm:0.3.6" + dependencies: + "@backstage/config": ^1.3.3 + "@backstage/frontend-app-api": ^0.13.0 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/plugin-app": ^0.3.0 + "@backstage/test-utils": ^1.7.11 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 zod: ^3.22.4 peerDependencies: @@ -5962,20 +5708,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 1483f851333f2733d1b675d020cf14300d457dacab56dfa4b52d405225d5efaf340e6ccb4e48b9321c4820098254c47a544b8dacd8f797c71fc3d2610eaf10ab + checksum: 608b77a23fc92e29629a03cf8117e63a18cc37e41e27385c2989115adca199e3bb719784a931d8cf7e6a67d806d7e54ee5333e25011301d1829405720251cfbe languageName: node linkType: hard -"@backstage/frontend-test-utils@npm:^0.3.2, @backstage/frontend-test-utils@npm:^0.3.3": - version: 0.3.3 - resolution: "@backstage/frontend-test-utils@npm:0.3.3" - dependencies: - "@backstage/config": ^1.3.2 - "@backstage/frontend-app-api": ^0.11.3 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-app": ^0.1.10 - "@backstage/test-utils": ^1.7.9 - "@backstage/types": ^1.2.1 +"@backstage/frontend-test-utils@npm:^0.4.0": + version: 0.4.0 + resolution: "@backstage/frontend-test-utils@npm:0.4.0" + dependencies: + "@backstage/config": ^1.3.5 + "@backstage/frontend-app-api": ^0.13.1 + "@backstage/frontend-plugin-api": ^0.12.1 + "@backstage/plugin-app": ^0.3.1 + "@backstage/test-utils": ^1.7.12 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 zod: ^3.22.4 peerDependencies: @@ -5987,68 +5733,32 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 363be516ac8e5fad43432cbe6a712778f0a3942909f009823cf0c58ab397f41ac9e6aaa9d7718dadec00bb145b1dc44f021fbb165c105c04dead93ee2b6679fb - languageName: node - linkType: hard - -"@backstage/integration-aws-node@npm:^0.1.12, @backstage/integration-aws-node@npm:^0.1.15": - version: 0.1.15 - resolution: "@backstage/integration-aws-node@npm:0.1.15" - dependencies: - "@aws-sdk/client-sts": ^3.350.0 - "@aws-sdk/credential-provider-node": ^3.350.0 - "@aws-sdk/credential-providers": ^3.350.0 - "@aws-sdk/types": ^3.347.0 - "@aws-sdk/util-arn-parser": ^3.310.0 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - checksum: ba86647ca4e463b6c8d5f6d56ca732b556ea8934e8df2b516e2f88b411ddffed098a67f55df744216c28c8f7182e19c1a2312a088b5f4726dfb3c9311d7821d6 + checksum: da64dcbffb088fd65f47d1ec59a705ef084e965d9891d2cf90e744529bff6c17e23873577c5136d8e7812199e1b33ab8790393ec1191045f7de7e79619af4cd3 languageName: node linkType: hard -"@backstage/integration-aws-node@npm:^0.1.16": - version: 0.1.16 - resolution: "@backstage/integration-aws-node@npm:0.1.16" +"@backstage/integration-aws-node@npm:^0.1.12, @backstage/integration-aws-node@npm:^0.1.15, @backstage/integration-aws-node@npm:^0.1.17": + version: 0.1.17 + resolution: "@backstage/integration-aws-node@npm:0.1.17" dependencies: "@aws-sdk/client-sts": ^3.350.0 "@aws-sdk/credential-provider-node": ^3.350.0 "@aws-sdk/credential-providers": ^3.350.0 "@aws-sdk/types": ^3.347.0 "@aws-sdk/util-arn-parser": ^3.310.0 - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - checksum: fd9460168c72dfacbdcd0497daa5600ab0c650485686190f60d5b5b60b6a33f8e997d660dcc22245c1ff1aee4f30912e1e35a20977e73b8f74f41d1aee23fb50 - languageName: node - linkType: hard - -"@backstage/integration-react@npm:^1.2.1, @backstage/integration-react@npm:^1.2.5": - version: 1.2.5 - resolution: "@backstage/integration-react@npm:1.2.5" - dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-plugin-api": ^1.10.5 - "@backstage/integration": ^1.16.2 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: a2f8635b305a614bc8be759923856ff801dd085e7791ca8ba2b1e7896d0b2df5cb1b9c0fe6d5413fe91db35b5ddea9d39261eabde42485df7e1abc1b6c6e59a0 + checksum: f3bab1e5eefcc8e69123721b3f204b7c283ea7770e7734f6b65ab8f36bd78894ae48d5ddd6d7d24255403b953e93645bc9e54a01f5219c37b449416a369b6df4 languageName: node linkType: hard -"@backstage/integration-react@npm:^1.2.7, @backstage/integration-react@npm:^1.2.8": - version: 1.2.8 - resolution: "@backstage/integration-react@npm:1.2.8" +"@backstage/integration-react@npm:^1.2.10, @backstage/integration-react@npm:^1.2.11, @backstage/integration-react@npm:^1.2.8, @backstage/integration-react@npm:^1.2.9": + version: 1.2.11 + resolution: "@backstage/integration-react@npm:1.2.11" dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/integration": ^1.17.0 + "@backstage/config": ^1.3.5 + "@backstage/core-plugin-api": ^1.11.1 + "@backstage/integration": ^1.18.1 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 peerDependencies: @@ -6059,35 +5769,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 9f1b9efe9c669b7c9394003699da9d9ed0ff30048645c444e4daa131f5a0a3de17dca9a8faf60b04fea78ed085df00faab5c8324fb046c924e813a3eb9037e99 - languageName: node - linkType: hard - -"@backstage/integration@npm:^1.11.0, @backstage/integration@npm:^1.13.0, @backstage/integration@npm:^1.14.0, @backstage/integration@npm:^1.15.0, @backstage/integration@npm:^1.16.1, @backstage/integration@npm:^1.16.2, @backstage/integration@npm:^1.8.0": - version: 1.16.2 - resolution: "@backstage/integration@npm:1.16.2" - dependencies: - "@azure/identity": ^4.0.0 - "@azure/storage-blob": ^12.5.0 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@octokit/auth-app": ^4.0.0 - "@octokit/rest": ^19.0.3 - cross-fetch: ^4.0.0 - git-url-parse: ^15.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - checksum: ae5b7f467431edc18797117754a4ef17e5f3db6d1fec258ea1d51d7827813083c11a9e0c67a0f32ed61ae9236f372479154cb38df95c7ba6ff9ceb5744588806 + checksum: 6b1027c28622479bd572c75f9b87b6358c4a321bf73747aecd4384096ff43550fb74965ec1f1e5eecff666bd53e25fc375cfe9363f3e4f78a82a821036cb9cf3 languageName: node linkType: hard -"@backstage/integration@npm:^1.16.3, @backstage/integration@npm:^1.17.0": - version: 1.17.0 - resolution: "@backstage/integration@npm:1.17.0" +"@backstage/integration@npm:^1.11.0, @backstage/integration@npm:^1.13.0, @backstage/integration@npm:^1.14.0, @backstage/integration@npm:^1.15.0, @backstage/integration@npm:^1.16.1, @backstage/integration@npm:^1.16.2, @backstage/integration@npm:^1.17.0, @backstage/integration@npm:^1.17.1, @backstage/integration@npm:^1.18.0, @backstage/integration@npm:^1.18.1, @backstage/integration@npm:^1.8.0": + version: 1.18.1 + resolution: "@backstage/integration@npm:1.18.1" dependencies: "@azure/identity": ^4.0.0 "@azure/storage-blob": ^12.5.0 - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.5 "@backstage/errors": ^1.2.7 "@octokit/auth-app": ^4.0.0 "@octokit/rest": ^19.0.3 @@ -6095,52 +5787,41 @@ __metadata: git-url-parse: ^15.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - checksum: a74abea5c5c3546ff6e3fc62db58285c5887b0da2c48fcc8abc2a59be4662f2d27c9672facb44e40131faa93ee65d0102975f7947d548feedbb5c38b7a182736 + checksum: 1d9c03bb51556638d6b7d22c867f9c0a6677b2ae3683d46752a1a559991ba11a57a5db65608c3b518b8757666e1f6b9fffcbb3ec461cb1215433fb6f86ce6d38 languageName: node linkType: hard -"@backstage/plugin-app@npm:^0.1.10": - version: 0.1.10 - resolution: "@backstage/plugin-app@npm:0.1.10" +"@backstage/plugin-app-node@npm:^0.1.37": + version: 0.1.37 + resolution: "@backstage/plugin-app-node@npm:0.1.37" dependencies: - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/integration-react": ^1.2.8 - "@backstage/plugin-permission-react": ^0.4.35 - "@backstage/theme": ^0.6.6 - "@backstage/types": ^1.2.1 - "@material-ui/core": ^4.9.13 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": ^4.0.0-alpha.61 - react-use: ^17.2.4 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: b5be19e2a8aff12ece0cf065adfcf0f9a53744d4a465f4ab816f735043084349f68e0b8327e5d2fdf7e10f8eaf21c3a92a0b61b92a7a92e775d22f993f0fc2d1 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/config-loader": ^1.10.3 + "@types/express": ^4.17.6 + express: ^4.17.1 + fs-extra: ^11.2.0 + checksum: 55c318129dce8848a9911284ed7833dac4b6172e14e4bafdf384812cdad2e6e42d9e56fd69cc5eb7a998b076338bdca1e4b8f601f161f67597195875a956e5ea languageName: node linkType: hard -"@backstage/plugin-app@npm:^0.1.7": - version: 0.1.7 - resolution: "@backstage/plugin-app@npm:0.1.7" - dependencies: - "@backstage/core-components": ^0.17.0 - "@backstage/core-plugin-api": ^1.10.5 - "@backstage/frontend-plugin-api": ^0.10.0 - "@backstage/integration-react": ^1.2.5 - "@backstage/plugin-permission-react": ^0.4.32 - "@backstage/theme": ^0.6.4 - "@backstage/types": ^1.2.1 +"@backstage/plugin-app@npm:^0.3.0, @backstage/plugin-app@npm:^0.3.1": + version: 0.3.1 + resolution: "@backstage/plugin-app@npm:0.3.1" + dependencies: + "@backstage/core-components": ^0.18.2 + "@backstage/core-plugin-api": ^1.11.1 + "@backstage/frontend-plugin-api": ^0.12.1 + "@backstage/integration-react": ^1.2.11 + "@backstage/plugin-permission-react": ^0.4.37 + "@backstage/theme": ^0.7.0 + "@backstage/types": ^1.2.2 + "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 + "@react-hookz/web": ^24.0.0 react-use: ^17.2.4 + zod: ^3.22.4 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 @@ -6149,18 +5830,18 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 55251477a365584f176adfbfa48c1ed71568d15edfc7db3fab2d49f66f43690889c19336c5c7d513f1af41cebca60d5beef2cf591936fd90fd92ff43da28dd4f + checksum: 69ca7efe694bf6c8a24aede8c791b119e5d940e7ed989578bec8a9afcbfaef8d8d6b047df0c9361d8ef5380f144defd95688552ce1d216172bc0d0a42b05e4da languageName: node linkType: hard -"@backstage/plugin-auth-node@npm:0.6.0": - version: 0.6.0 - resolution: "@backstage/plugin-auth-node@npm:0.6.0" +"@backstage/plugin-auth-node@npm:0.6.6": + version: 0.6.6 + resolution: "@backstage/plugin-auth-node@npm:0.6.6" dependencies: - "@backstage/backend-plugin-api": ^1.2.0 - "@backstage/catalog-client": ^1.9.1 - "@backstage/catalog-model": ^1.7.3 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 "@backstage/types": ^1.2.1 "@types/express": ^4.17.6 @@ -6172,103 +5853,34 @@ __metadata: zod: ^3.22.4 zod-to-json-schema: ^3.21.4 zod-validation-error: ^3.4.0 - checksum: 71990ab5af23d854ffee74480388a868ded317925c224583a233009c2dbdade5bf6de376e5a3a3d075f5c1f2cf51ba3be00c86bd6c7f980817cc7627909c228e + checksum: cb3e69133b2d27bd0d10a5bd65a0a2f23caf4211de8137713d0fd398e93e808768d5e45150782b3f8c562cf0921f67ecb52e336bf3fb33bbf5b74bce03e25370 languageName: node linkType: hard -"@backstage/plugin-auth-node@npm:^0.6.1": - version: 0.6.1 - resolution: "@backstage/plugin-auth-node@npm:0.6.1" +"@backstage/plugin-auth-react@npm:^0.1.18": + version: 0.1.18 + resolution: "@backstage/plugin-auth-react@npm:0.1.18" dependencies: - "@backstage/backend-plugin-api": ^1.2.1 - "@backstage/catalog-client": ^1.9.1 - "@backstage/catalog-model": ^1.7.3 - "@backstage/config": ^1.3.2 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 - "@types/express": ^4.17.6 - "@types/passport": ^1.0.3 - express: ^4.17.1 - jose: ^5.0.0 - lodash: ^4.17.21 - passport: ^0.7.0 - zod: ^3.22.4 - zod-to-json-schema: ^3.21.4 - zod-validation-error: ^3.4.0 - checksum: 3ea509a085cf864138819658608e53978ce7847303e021679a25a23a1a241daf15c95c4e14f1e823a833a89dbd0a462e35e428a40493875b8488be77ed3583af + "@material-ui/core": ^4.9.13 + "@react-hookz/web": ^24.0.0 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + react-router-dom: ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 7c550d47d9032a14caf03f55e21706cd59987e2bb71071028324e719f877f43402de2b0212421ed6e0083347856630254ced5937e384722f3f69e25088a80db6 languageName: node linkType: hard -"@backstage/plugin-auth-node@npm:^0.6.2, @backstage/plugin-auth-node@npm:^0.6.3, @backstage/plugin-auth-node@npm:^0.6.4": - version: 0.6.4 - resolution: "@backstage/plugin-auth-node@npm:0.6.4" - dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 - "@types/express": ^4.17.6 - "@types/passport": ^1.0.3 - express: ^4.17.1 - jose: ^5.0.0 - lodash: ^4.17.21 - passport: ^0.7.0 - zod: ^3.22.4 - zod-to-json-schema: ^3.21.4 - zod-validation-error: ^3.4.0 - checksum: 1b7580516568772106b560ef17bcd432244259b94b42560000abe8b230263d18cceca51c909da26ea1dd072218dfbe535e062315dde3a31534c7483eb6bbcffd - languageName: node - linkType: hard - -"@backstage/plugin-auth-node@patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch::locator=dynamic-plugins-root%40workspace%3A.": - version: 0.6.0 - resolution: "@backstage/plugin-auth-node@patch:@backstage/plugin-auth-node@npm%3A0.6.0#./.yarn/patches/@backstage-plugin-auth-node-npm-0.6.0-69f2f0dc3f.patch::version=0.6.0&hash=45bb46&locator=dynamic-plugins-root%40workspace%3A." - dependencies: - "@backstage/backend-plugin-api": ^1.2.0 - "@backstage/catalog-client": ^1.9.1 - "@backstage/catalog-model": ^1.7.3 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 - "@types/express": ^4.17.6 - "@types/passport": ^1.0.3 - express: ^4.17.1 - jose: ^5.0.0 - lodash: ^4.17.21 - passport: ^0.7.0 - zod: ^3.22.4 - zod-to-json-schema: ^3.21.4 - zod-validation-error: ^3.4.0 - checksum: 77ffbf96126a8c0dbacb70da872c6555f7d89f9ec010a437d11aab7fb33ebc99d61a6d73da767ec96c9eb4109e906cb19472e2d118056be43e2be8f421acba8a - languageName: node - linkType: hard - -"@backstage/plugin-auth-react@npm:^0.1.15": - version: 0.1.16 - resolution: "@backstage/plugin-auth-react@npm:0.1.16" - dependencies: - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/errors": ^1.2.7 - "@material-ui/core": ^4.9.13 - "@react-hookz/web": ^24.0.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 11d135702c0265729a51702c2070164cb46cd265d09aee9c6c8863d4fdb8e6e363d325400ab3ef9f54c65441e378de09305249c6247f107adb4af10115a666f7 - languageName: node - linkType: hard - -"@backstage/plugin-bitbucket-cloud-common@npm:^0.2.27": - version: 0.2.27 - resolution: "@backstage/plugin-bitbucket-cloud-common@npm:0.2.27" +"@backstage/plugin-bitbucket-cloud-common@npm:^0.2.27": + version: 0.2.27 + resolution: "@backstage/plugin-bitbucket-cloud-common@npm:0.2.27" dependencies: "@backstage/integration": ^1.16.1 cross-fetch: ^4.0.0 @@ -6276,78 +5888,78 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-bitbucket-cloud-common@npm:^0.3.0": - version: 0.3.0 - resolution: "@backstage/plugin-bitbucket-cloud-common@npm:0.3.0" +"@backstage/plugin-bitbucket-cloud-common@npm:^0.3.1": + version: 0.3.1 + resolution: "@backstage/plugin-bitbucket-cloud-common@npm:0.3.1" dependencies: - "@backstage/integration": ^1.17.0 + "@backstage/integration": ^1.17.1 cross-fetch: ^4.0.0 - checksum: 3b1909e17b3eabf061d5817950d7f7c1b9c2dd048c55cc07a787bcad4692745a635aba0b8f76e0b5539c657354aec65ebe59069acb72012c4992ecafa8d326ec + checksum: a92ce22e57f8ea84f99a51c644cda5f72400a4fc4b6571cf349aee311ce415ff62a9ababbbb17be91866353f071219ecce98c566db172c9b2e7328a612f5c370 languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-bitbucket-cloud@npm:0.4.8": - version: 0.4.8 - resolution: "@backstage/plugin-catalog-backend-module-bitbucket-cloud@npm:0.4.8" - dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-bitbucket-cloud-common": ^0.3.0 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-events-node": ^0.4.11 +"@backstage/plugin-catalog-backend-module-bitbucket-cloud@npm:0.5.2": + version: 0.5.2 + resolution: "@backstage/plugin-catalog-backend-module-bitbucket-cloud@npm:0.5.2" + dependencies: + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-bitbucket-cloud-common": ^0.3.1 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-events-node": ^0.4.14 uuid: ^11.0.0 - checksum: 6b36aeb9fde0a12404788888c5974ab8463249b3fe13c4d92bebf8e14d7e087d243eb1f6e76a27f95460093a8824810574f2874cc2bf185e0a725528822525fa + checksum: 3a04384fad299a207c0223f0cc67e5574b1e02517fcd6074aa3f0c2a8b648f343aa9969d25d6fa1fb42edd86f448442bc47c4f5d87f493f189d0baf607f9bb26 languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-bitbucket-server@npm:0.4.1": - version: 0.4.1 - resolution: "@backstage/plugin-catalog-backend-module-bitbucket-server@npm:0.4.1" +"@backstage/plugin-catalog-backend-module-bitbucket-server@npm:0.5.2": + version: 0.5.2 + resolution: "@backstage/plugin-catalog-backend-module-bitbucket-server@npm:0.5.2" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-events-node": ^0.4.11 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-events-node": ^0.4.14 uuid: ^11.0.0 - checksum: 0d5f0ec76c22603a50285b04c40ff5faaba55d67bd669b20784a95e7dd506b0da4df1f3872ca6eb4d9a0837c87078d5dfbad67072cf48b73b2f6ba934f01424d + checksum: 911aad97c35c1fe7f262b9cad2e502a6384755d2ae7f6e5284dc56c813399d92f75b5d886eef3c139d48ddd8d7b71a1536b6eb334ea42b313fe73ec8d2434ee7 languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-github-org@npm:0.3.10": - version: 0.3.10 - resolution: "@backstage/plugin-catalog-backend-module-github-org@npm:0.3.10" +"@backstage/plugin-catalog-backend-module-github-org@npm:0.3.13": + version: 0.3.13 + resolution: "@backstage/plugin-catalog-backend-module-github-org@npm:0.3.13" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 - "@backstage/plugin-catalog-backend-module-github": ^0.9.0 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-events-node": ^0.4.11 - checksum: 4982eb99c603488df1e7ff87c68c800f92a77bb9495fe1a4736e2fd7f49cf888cc20cba6c6c3cd4bf453a71913cdb1a781a354323326cb0eb4d5fb0f94c55f65 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 + "@backstage/plugin-catalog-backend-module-github": ^0.10.2 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-events-node": ^0.4.14 + checksum: e14f65284535d03c854936846310f0cf7e316f5049472f0acf571d26e1fd3de675ca9b314b9ed220da2fbaf9586acd3584272b6a5e8598ae6f193bb866855eba languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-github@npm:0.9.0, @backstage/plugin-catalog-backend-module-github@npm:^0.9.0": - version: 0.9.0 - resolution: "@backstage/plugin-catalog-backend-module-github@npm:0.9.0" +"@backstage/plugin-catalog-backend-module-github@npm:0.10.2, @backstage/plugin-catalog-backend-module-github@npm:^0.10.2": + version: 0.10.2 + resolution: "@backstage/plugin-catalog-backend-module-github@npm:0.10.2" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-catalog-backend": ^2.0.0 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-events-node": ^0.4.11 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-catalog-backend": ^3.0.1 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-events-node": ^0.4.14 "@octokit/core": ^5.2.0 "@octokit/graphql": ^7.0.2 "@octokit/plugin-throttling": ^8.1.3 @@ -6356,88 +5968,88 @@ __metadata: lodash: ^4.17.21 minimatch: ^9.0.0 uuid: ^11.0.0 - checksum: 8c2a502021cf7bab44c49ef8cfe860e7651e518c7bdf47d1f896bd790c0e2b56dccf665eef8dfeb003ba3a51b99cc14e14387dfc802ab243f4af817bdd70f233 + checksum: abc859c3cd48d4bc2a33123dfbace64c7fc303ecc8d38d8be9245d0ea2e72e93f068c0eca5ba06c3267c28133c516e550b03885fc63e6d8a8395cd7fe88e8c49 languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-gitlab-org@npm:0.2.9": - version: 0.2.9 - resolution: "@backstage/plugin-catalog-backend-module-gitlab-org@npm:0.2.9" +"@backstage/plugin-catalog-backend-module-gitlab-org@npm:0.2.12": + version: 0.2.12 + resolution: "@backstage/plugin-catalog-backend-module-gitlab-org@npm:0.2.12" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/plugin-catalog-backend-module-gitlab": ^0.6.6 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-events-node": ^0.4.11 - checksum: 2bbbc3aee04aebebd71e9ceef19eca7cc3526ed908aa80f8415cc1f24274a86b1e39240d43e0dd27ce902074c22e16bf1748f7cb4bea307b25820ad9d456df37 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/plugin-catalog-backend-module-gitlab": ^0.7.2 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-events-node": ^0.4.14 + checksum: a5389148849000738201a96a86d8b19041feb11fca6d065b6ef7abc938ae0c05d8b251a652beb55aac9787c90eb696009d1efde276beb3db48dfdb1483eab27d languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-gitlab@npm:0.6.6, @backstage/plugin-catalog-backend-module-gitlab@npm:^0.6.6": - version: 0.6.6 - resolution: "@backstage/plugin-catalog-backend-module-gitlab@npm:0.6.6" - dependencies: - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-events-node": ^0.4.11 +"@backstage/plugin-catalog-backend-module-gitlab@npm:0.7.2, @backstage/plugin-catalog-backend-module-gitlab@npm:^0.7.2": + version: 0.7.2 + resolution: "@backstage/plugin-catalog-backend-module-gitlab@npm:0.7.2" + dependencies: + "@backstage/backend-defaults": ^0.12.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-events-node": ^0.4.14 "@gitbeaker/rest": ^40.0.3 lodash: ^4.17.21 node-fetch: ^2.7.0 uuid: ^11.0.0 - checksum: 88593c6f2a48e972e9c5d58f257bea5e0c338231915b8fbc71af00a35c867b419be2ddd4e3b05f272bc868474b4ccccb1146fa4d9227134b070b55b6c07d5c2f + checksum: 18f7473ef42e8af244b6935a652787e02abfab7b429af4d978e78c047de8ec00606a4829eb2372ed7fed71ba89184e6d1a0cc697c7d393ecd8b288e10972b473 languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-ldap@npm:0.11.5": - version: 0.11.5 - resolution: "@backstage/plugin-catalog-backend-module-ldap@npm:0.11.5" +"@backstage/plugin-catalog-backend-module-ldap@npm:0.11.8": + version: 0.11.8 + resolution: "@backstage/plugin-catalog-backend-module-ldap@npm:0.11.8" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 "@backstage/types": ^1.2.1 "@types/ldapjs": ^2.2.5 ldapjs: ^2.3.3 lodash: ^4.17.21 uuid: ^11.0.0 - checksum: 35e727b79bef8b4629aa778e524d389f827fc8c454f817e5cc433ff098cc8e497fa07a85cf835c2dd281dcb75f5e7b2a77c6a7aa4bb0b6aa1d977e37944006f8 + checksum: 75133428cda67a19d23aece459a36f9a413199eb08dac4858061569ef9a515f08d3285f4500b36d7d842d1c4a2668314c97511338b33fab637d438b64179cdad languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-logs@npm:^0.1.10": - version: 0.1.11 - resolution: "@backstage/plugin-catalog-backend-module-logs@npm:0.1.11" +"@backstage/plugin-catalog-backend-module-logs@npm:^0.1.13": + version: 0.1.14 + resolution: "@backstage/plugin-catalog-backend-module-logs@npm:0.1.14" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/plugin-catalog-backend": ^2.1.0 - "@backstage/plugin-events-node": ^0.4.12 - checksum: b4d586071b87bd87479f4bc75bd32b41a2486d06e0f9c8a9196cda5fa34e3a28140232f53a0768c78f439d8b050b12064f5afb608419aef104cf2dfc4c476a85 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/plugin-catalog-backend": ^3.1.0 + "@backstage/plugin-events-node": ^0.4.15 + checksum: fa6a9258260ed68455ff835b6ac1009805ef21fdec8dca92536226f3293f38221b5c2d3bbdadfab6cb856f2604d0d395041bad619645b2d5b5b9171554f940f2 languageName: node linkType: hard -"@backstage/plugin-catalog-backend-module-msgraph@npm:0.7.0": - version: 0.7.0 - resolution: "@backstage/plugin-catalog-backend-module-msgraph@npm:0.7.0" +"@backstage/plugin-catalog-backend-module-msgraph@npm:0.7.3": + version: 0.7.3 + resolution: "@backstage/plugin-catalog-backend-module-msgraph@npm:0.7.3" dependencies: "@azure/identity": ^4.0.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 "@microsoft/microsoft-graph-types": ^2.6.0 lodash: ^4.17.21 p-limit: ^3.0.2 qs: ^6.9.4 uuid: ^11.0.0 - checksum: bbd900a2990b14b6818c9f9708c7f1c842345c84e8a1fcd2ff60ec95594d2fec6b28946d6af954c6fd3fa75865a80eb2728e75fc81b1a5edc68b28962c788a7c + checksum: 8053282da77b47565078dfaa8dfabbd21ddd20584eb9f15ab78a40030fab13ea3bf6ab4aa75ccf7fd5c3fbbd7a1eb6aeb2abfb29179172f8e915bf9930b9e834 languageName: node linkType: hard @@ -6454,23 +6066,23 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-catalog-backend@npm:^2.0.0, @backstage/plugin-catalog-backend@npm:^2.1.0": - version: 2.1.0 - resolution: "@backstage/plugin-catalog-backend@npm:2.1.0" +"@backstage/plugin-catalog-backend@npm:^3.0.1, @backstage/plugin-catalog-backend@npm:^3.1.0": + version: 3.1.1 + resolution: "@backstage/plugin-catalog-backend@npm:3.1.1" dependencies: - "@backstage/backend-openapi-utils": ^0.5.4 - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-openapi-utils": ^0.6.1 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.4 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.1 - "@backstage/plugin-events-node": ^0.4.12 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.1 - "@backstage/types": ^1.2.1 + "@backstage/integration": ^1.18.0 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.19.0 + "@backstage/plugin-events-node": ^0.4.15 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.4 + "@backstage/types": ^1.2.2 "@opentelemetry/api": ^1.9.0 codeowners-utils: ^1.0.2 core-js: ^3.6.5 @@ -6489,48 +6101,37 @@ __metadata: yaml: ^2.0.0 yn: ^4.0.0 zod: ^3.22.4 - checksum: b65875b66f57ff275846a882be9611d22af0372a01ce690520524618cd61af3be0d12ac88117efd219cffbc1c45d9a427bf3bd833c6b389f9be3a7aeb9355342 - languageName: node - linkType: hard - -"@backstage/plugin-catalog-common@npm:^1.0.25, @backstage/plugin-catalog-common@npm:^1.1.3": - version: 1.1.3 - resolution: "@backstage/plugin-catalog-common@npm:1.1.3" - dependencies: - "@backstage/catalog-model": ^1.7.3 - "@backstage/plugin-permission-common": ^0.8.4 - "@backstage/plugin-search-common": ^1.2.17 - checksum: 320551fc176152d6566cc7dfcd452e9a353119b9415275c7d2cf6bff5a73a82f064a522a397bb1dca9c89301a2c25d7f4412e86fa8f616b420764858aee411ff + checksum: c911a62b15d2642ade12f3133435208ae567ba6956587fb05e6243e2833e1cb32901f9c82e8fe4bcfbd358addc2047934495876c162f4e8d21132156e0cc882e languageName: node linkType: hard -"@backstage/plugin-catalog-common@npm:^1.1.4": - version: 1.1.4 - resolution: "@backstage/plugin-catalog-common@npm:1.1.4" +"@backstage/plugin-catalog-common@npm:^1.0.25, @backstage/plugin-catalog-common@npm:^1.1.3, @backstage/plugin-catalog-common@npm:^1.1.5, @backstage/plugin-catalog-common@npm:^1.1.6": + version: 1.1.6 + resolution: "@backstage/plugin-catalog-common@npm:1.1.6" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-search-common": ^1.2.18 - checksum: 24fd4ff866ff1190bfbef41e8d51a69613c30a9a29deb443257a761dfb89f2cac9550382c125db239347acb9b27cae56859d9784bd7464eef1f09d730d964176 + "@backstage/catalog-model": ^1.7.5 + "@backstage/plugin-permission-common": ^0.9.2 + "@backstage/plugin-search-common": ^1.2.20 + checksum: f1bb59535bfde7aded1fc2b220c7bdf5190e7cbd6e2ab493bdfd889fca76d53dd31f1a0f06dc3314936d2b5dcfd225041eab105eca5ef270744ce8df1da8bf00 languageName: node linkType: hard -"@backstage/plugin-catalog-import@npm:^0.13.0": - version: 0.13.1 - resolution: "@backstage/plugin-catalog-import@npm:0.13.1" +"@backstage/plugin-catalog-import@npm:^0.13.4": + version: 0.13.5 + resolution: "@backstage/plugin-catalog-import@npm:0.13.5" dependencies: - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/core-compat-api": ^0.4.3 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/core-compat-api": ^0.5.2 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/integration": ^1.17.0 - "@backstage/integration-react": ^1.2.8 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-react": ^1.19.0 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/integration": ^1.18.0 + "@backstage/integration-react": ^1.2.10 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-react": ^1.21.0 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -6549,101 +6150,44 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 8bcd572511e7fb14e9354160bdc3e07b012db94ac3cae719d4f6aeb994cf4a7f996f5f428dc4b8ade8eeaa2f519d19b4f052fdf694f0155a3c42ca8ffadaf368 - languageName: node - linkType: hard - -"@backstage/plugin-catalog-node@npm:^1.12.4, @backstage/plugin-catalog-node@npm:^1.16.0": - version: 1.16.0 - resolution: "@backstage/plugin-catalog-node@npm:1.16.0" - dependencies: - "@backstage/backend-plugin-api": ^1.2.0 - "@backstage/catalog-client": ^1.9.1 - "@backstage/catalog-model": ^1.7.3 - "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-common": ^1.1.3 - "@backstage/plugin-permission-common": ^0.8.4 - "@backstage/plugin-permission-node": ^0.8.8 - "@backstage/types": ^1.2.1 - checksum: 52a7d86e618cf704b25ba21724b5661c9fdc8d45ee0eec77bdc4b44f704ac0e1332ccb75c3c976738e6894d33883fde0229f13a9df1c683eb0c92b9ce31af23a - languageName: node - linkType: hard - -"@backstage/plugin-catalog-node@npm:^1.17.0, @backstage/plugin-catalog-node@npm:^1.17.1": - version: 1.17.1 - resolution: "@backstage/plugin-catalog-node@npm:1.17.1" - dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.1 - "@backstage/types": ^1.2.1 - lodash: ^4.17.21 - yaml: ^2.0.0 - checksum: c003c936dde86ac31c560d2d8c1f162489ae76ed00c256aab8fa37c0a3581b26340fcd8d5acac1bb076b286313cefb9e3ec54e9e34e6251de8ed6849d13fa6d0 + checksum: 802d0121f48b0fb0767c46724c077e734518f64cd7ecf0ec306f291003108e13133ce71a43a7de6d85828e4b81f53e842fe78cb27419963484667e6d8ea2990d languageName: node linkType: hard -"@backstage/plugin-catalog-react@npm:1.18.0": - version: 1.18.0 - resolution: "@backstage/plugin-catalog-react@npm:1.18.0" +"@backstage/plugin-catalog-node@npm:^1.12.4, @backstage/plugin-catalog-node@npm:^1.16.0, @backstage/plugin-catalog-node@npm:^1.17.2, @backstage/plugin-catalog-node@npm:^1.18.0, @backstage/plugin-catalog-node@npm:^1.19.0": + version: 1.19.0 + resolution: "@backstage/plugin-catalog-node@npm:1.19.0" dependencies: - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/frontend-test-utils": ^0.3.2 - "@backstage/integration-react": ^1.2.7 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/types": ^1.2.1 - "@backstage/version-bridge": ^1.0.11 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^24.0.0 - classnames: ^2.2.6 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.4 + "@backstage/types": ^1.2.2 lodash: ^4.17.21 - material-ui-popup-state: ^1.9.3 - qs: ^6.9.4 - react-use: ^17.2.4 yaml: ^2.0.0 - zen-observable: ^0.10.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: d60f5964750477427f15970e3b3646002398fafec40bb62a631ffff9615ac796bbcd1318986c6750666a3a206be2b4b3484a07ab409bd93e1d42616ec48b529d + checksum: c012b23757d679b6a029707c2ea7df9e375939cfcb9a0adf32ee0ebdde1b7176b41a93350d284b09e93095fb3f76d0230bf788bb26da04fa3cec5f2f296c30d9 languageName: node linkType: hard -"@backstage/plugin-catalog-react@npm:^1.12.2, @backstage/plugin-catalog-react@npm:^1.14.2, @backstage/plugin-catalog-react@npm:^1.16.0": - version: 1.16.0 - resolution: "@backstage/plugin-catalog-react@npm:1.16.0" +"@backstage/plugin-catalog-react@npm:1.20.1": + version: 1.20.1 + resolution: "@backstage/plugin-catalog-react@npm:1.20.1" dependencies: - "@backstage/catalog-client": ^1.9.1 - "@backstage/catalog-model": ^1.7.3 - "@backstage/core-compat-api": ^0.4.0 - "@backstage/core-components": ^0.17.0 - "@backstage/core-plugin-api": ^1.10.5 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.5.0 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.0 - "@backstage/frontend-test-utils": ^0.3.0 - "@backstage/integration-react": ^1.2.5 - "@backstage/plugin-catalog-common": ^1.1.3 - "@backstage/plugin-permission-common": ^0.8.4 - "@backstage/plugin-permission-react": ^0.4.32 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/frontend-test-utils": ^0.3.5 + "@backstage/integration-react": ^1.2.9 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-react": ^0.4.36 "@backstage/types": ^1.2.1 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.2 @@ -6665,27 +6209,27 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 7ac3b023d53e4f4102d73cb5c29db7d6adc47432ec696b1fbc4107d1c44154ae2314ceb048d032e1174a0170251edca482710b1e7fd7ec9de5b55f18c6a3a1ea + checksum: 875f5eb1aed72075706e25d6146dc0e4e50ef05c90fe1839143861cc25bd9f86345f530baa165bddd2c7997d6f0b4d85e7e16a05df0e3b428bd8124dcdcda1ed languageName: node linkType: hard -"@backstage/plugin-catalog-react@npm:^1.17.0, @backstage/plugin-catalog-react@npm:^1.18.0, @backstage/plugin-catalog-react@npm:^1.19.0": - version: 1.19.0 - resolution: "@backstage/plugin-catalog-react@npm:1.19.0" +"@backstage/plugin-catalog-react@npm:^1.19.0, @backstage/plugin-catalog-react@npm:^1.19.1, @backstage/plugin-catalog-react@npm:^1.20.0, @backstage/plugin-catalog-react@npm:^1.20.1, @backstage/plugin-catalog-react@npm:^1.21.0, @backstage/plugin-catalog-react@npm:^1.21.1, @backstage/plugin-catalog-react@npm:^1.21.2": + version: 1.21.2 + resolution: "@backstage/plugin-catalog-react@npm:1.21.2" dependencies: - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.3 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.5.3 + "@backstage/core-components": ^0.18.2 + "@backstage/core-plugin-api": ^1.11.1 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/frontend-test-utils": ^0.3.3 - "@backstage/integration-react": ^1.2.8 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-react": ^0.4.35 - "@backstage/types": ^1.2.1 + "@backstage/frontend-plugin-api": ^0.12.1 + "@backstage/frontend-test-utils": ^0.4.0 + "@backstage/integration-react": ^1.2.11 + "@backstage/plugin-catalog-common": ^1.1.6 + "@backstage/plugin-permission-common": ^0.9.2 + "@backstage/plugin-permission-react": ^0.4.37 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -6693,7 +6237,7 @@ __metadata: "@react-hookz/web": ^24.0.0 classnames: ^2.2.6 lodash: ^4.17.21 - material-ui-popup-state: ^1.9.3 + material-ui-popup-state: ^5.3.6 qs: ^6.9.4 react-use: ^17.2.4 yaml: ^2.0.0 @@ -6706,31 +6250,31 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 85220cadb17208def57dba164b5de3c9f690f7b3f1bad4b119835de01fdc4a0e8f09a281d00badc06989c609d95782353a78aa17018b94585c6f76e776a54e82 + checksum: 18efd42c2dcabe985c19f8a7ef2c28bb752b919bed9c4b941185348b1e5d472a400bf8c4a9f4a6a9cf53e4c7415a8797dc5b4086b163759b39990ea3fecb6c31 languageName: node linkType: hard -"@backstage/plugin-catalog@npm:^1.30.0": - version: 1.31.0 - resolution: "@backstage/plugin-catalog@npm:1.31.0" +"@backstage/plugin-catalog@npm:^1.31.2, @backstage/plugin-catalog@npm:^1.31.3": + version: 1.31.3 + resolution: "@backstage/plugin-catalog@npm:1.31.3" dependencies: - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.3 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.5.2 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/integration-react": ^1.2.8 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-react": ^1.19.0 - "@backstage/plugin-permission-react": ^0.4.35 - "@backstage/plugin-scaffolder-common": ^1.5.11 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/plugin-search-react": ^1.9.1 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/integration-react": ^1.2.10 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-react": ^1.21.0 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/plugin-scaffolder-common": ^1.7.1 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/plugin-search-react": ^1.9.4 "@backstage/plugin-techdocs-common": ^0.1.1 - "@backstage/plugin-techdocs-react": ^1.3.0 - "@backstage/types": ^1.2.1 + "@backstage/plugin-techdocs-react": ^1.3.3 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -6752,7 +6296,26 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 6ca4735f2a0263609c4aebeb64e529f2b392987f02584d3eb6d14a37c6b796d7937778053290012981891600097131d5ef1231271385dede6cbc56ab8d41875a + checksum: 75a21174cadcf5e3fb5c28e769fabd81aba1a3b7e514ec48dfafdd8104ef8440a8504a1617687fef375bcaaaa03ba7a16829a0f07babda1abfd4926beb9681e0 + languageName: node + linkType: hard + +"@backstage/plugin-events-backend@npm:^0.5.6": + version: 0.5.6 + resolution: "@backstage/plugin-events-backend@npm:0.5.6" + dependencies: + "@backstage/backend-openapi-utils": ^0.6.1 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/config": ^1.3.3 + "@backstage/errors": ^1.2.7 + "@backstage/plugin-events-node": ^0.4.15 + "@backstage/types": ^1.2.2 + "@types/express": ^4.17.6 + content-type: ^1.0.5 + express: ^4.17.1 + express-promise-router: ^4.1.0 + knex: ^3.0.0 + checksum: ff8fd9f01375c2313e46aaaa2d6ac7a0c55ab8bb0ffbb051d18144e9d1016172eabccede1586bdc5c6cf82ff6960ece7d8d60f2884ab50df00991ca8fd0acce4 languageName: node linkType: hard @@ -6765,68 +6328,30 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-events-node@npm:^0.4.11, @backstage/plugin-events-node@npm:^0.4.12": - version: 0.4.12 - resolution: "@backstage/plugin-events-node@npm:0.4.12" - dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 - "@types/content-type": ^1.1.8 - "@types/express": ^4.17.6 - content-type: ^1.0.5 - cross-fetch: ^4.0.0 - express: ^4.17.1 - uri-template: ^2.0.0 - checksum: 74d139f0aff95734aca807483c61397a7c9cb8a6ada46e32ba9354c98cb97062cba698e89f6a508d4ad2da421385b779f6ab13aef11f4ac7895cac4f7afd5394 - languageName: node - linkType: hard - -"@backstage/plugin-events-node@npm:^0.4.8, @backstage/plugin-events-node@npm:^0.4.9": - version: 0.4.9 - resolution: "@backstage/plugin-events-node@npm:0.4.9" +"@backstage/plugin-events-node@npm:^0.4.13, @backstage/plugin-events-node@npm:^0.4.14, @backstage/plugin-events-node@npm:^0.4.15, @backstage/plugin-events-node@npm:^0.4.8, @backstage/plugin-events-node@npm:^0.4.9": + version: 0.4.15 + resolution: "@backstage/plugin-events-node@npm:0.4.15" dependencies: - "@backstage/backend-plugin-api": ^1.2.1 + "@backstage/backend-plugin-api": ^1.4.3 "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 + "@backstage/types": ^1.2.2 "@types/content-type": ^1.1.8 "@types/express": ^4.17.6 content-type: ^1.0.5 cross-fetch: ^4.0.0 express: ^4.17.1 uri-template: ^2.0.0 - checksum: afb098250afd4be846bb5ed0ce86853373ec20890c4b264f2cad08fb36fb18db75c055dc476524a91528431c49b089776e2fe5239f7279b786845a96dd225a10 - languageName: node - linkType: hard - -"@backstage/plugin-home-react@npm:^0.1.15, @backstage/plugin-home-react@npm:^0.1.20": - version: 0.1.24 - resolution: "@backstage/plugin-home-react@npm:0.1.24" - dependencies: - "@backstage/core-components": ^0.17.0 - "@backstage/core-plugin-api": ^1.10.5 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.23.2 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 0dda9fd4b4646cc07322a0426f0a87f438626e08a7b0bfc1f5fc30c59ccc35710202a0c3222510a0d7a68f875ad54399f29e0e69bd1256403f719b8cde519f63 + checksum: 0439e5f44845a9113b2ad08235ca04fa0a57fb9bbefd5c1e9942390867a11cce006f1c9d4e551a3c7ee33b14dccb0773b28b72eb76695b018c43ea953e12af3c languageName: node linkType: hard -"@backstage/plugin-home-react@npm:^0.1.26, @backstage/plugin-home-react@npm:^0.1.27": - version: 0.1.27 - resolution: "@backstage/plugin-home-react@npm:0.1.27" +"@backstage/plugin-home-react@npm:^0.1.27, @backstage/plugin-home-react@npm:^0.1.29, @backstage/plugin-home-react@npm:^0.1.30": + version: 0.1.30 + resolution: "@backstage/plugin-home-react@npm:0.1.30" dependencies: - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/frontend-plugin-api": ^0.10.3 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 + "@backstage/frontend-plugin-api": ^0.12.0 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@rjsf/utils": 5.23.2 @@ -6838,25 +6363,25 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 543193be76d94053230a842af2781607551214af5b78e86d58ed48a0fc440a16e965523433191ace07ec995fc6304dce734ba9f8576dae902e2669d921f6a2c5 + checksum: 114d81eedf4f8dac2664bd9f2a5acdf9253388061e629f038be9e30186f622128e66f92d466bf149680fbafa313290ba836e489537060093048f8fff7bfd9a7a languageName: node linkType: hard -"@backstage/plugin-home@npm:^0.8.8": - version: 0.8.9 - resolution: "@backstage/plugin-home@npm:0.8.9" +"@backstage/plugin-home@npm:^0.8.11": + version: 0.8.12 + resolution: "@backstage/plugin-home@npm:0.8.12" dependencies: - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/core-app-api": ^1.17.1 - "@backstage/core-compat-api": ^0.4.3 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-catalog-react": ^1.19.0 - "@backstage/plugin-home-react": ^0.1.27 - "@backstage/theme": ^0.6.6 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/core-app-api": ^1.19.0 + "@backstage/core-compat-api": ^0.5.2 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/plugin-catalog-react": ^1.21.0 + "@backstage/plugin-home-react": ^0.1.30 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -6878,38 +6403,35 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 3c6e188a5b0adcbae91de5d4bd7e7d82e132a1ea2c0d9d050d30a154c0a7fe39bb05be703fc28c0ff86aadbcc347cfdc09305ee746b40d9798045401879339d0 + checksum: f8c0f0777a98e0c9c9f237573af8bdab4184f47757024d2e8a08535a6fe6c82cbd2d73346f77af58d8c765dce7b74d85f0baf1d4ea662fc57b5f5cd5404098fc languageName: node linkType: hard -"@backstage/plugin-kubernetes-backend@npm:0.19.6": - version: 0.19.6 - resolution: "@backstage/plugin-kubernetes-backend@npm:0.19.6" +"@backstage/plugin-kubernetes-backend@npm:0.20.1": + version: 0.20.1 + resolution: "@backstage/plugin-kubernetes-backend@npm:0.20.1" dependencies: "@aws-crypto/sha256-js": ^5.0.0 "@aws-sdk/credential-providers": ^3.350.0 "@aws-sdk/signature-v4": ^3.347.0 "@azure/identity": ^4.0.0 - "@backstage/backend-common": ^0.25.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration-aws-node": ^0.1.16 - "@backstage/plugin-auth-node": ^0.6.3 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-kubernetes-common": ^0.9.5 - "@backstage/plugin-kubernetes-node": ^0.3.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.0 + "@backstage/integration-aws-node": ^0.1.17 + "@backstage/plugin-auth-node": ^0.6.6 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-kubernetes-common": ^0.9.6 + "@backstage/plugin-kubernetes-node": ^0.3.3 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.3 "@backstage/types": ^1.2.1 "@google-cloud/container": ^5.0.0 "@jest-mock/express": ^2.0.1 "@kubernetes/client-node": 1.1.2 - "@types/express": ^4.17.6 "@types/http-proxy-middleware": ^1.0.0 - "@types/luxon": ^3.0.0 compression: ^1.7.4 cors: ^2.8.5 express: ^4.17.1 @@ -6924,102 +6446,50 @@ __metadata: stream-buffers: ^3.0.2 winston: ^3.2.1 yn: ^4.0.0 - checksum: e13779f44cc4c679d8a8b197d2fc5f4f13b509ca9e1578cc37a740ca31b1c9f8f4b651dd4d1b96be6c202c681745c4eedb5a0479821370e4a9562c421d246c20 - languageName: node - linkType: hard - -"@backstage/plugin-kubernetes-common@npm:^0.9.2, @backstage/plugin-kubernetes-common@npm:^0.9.4": - version: 0.9.4 - resolution: "@backstage/plugin-kubernetes-common@npm:0.9.4" - dependencies: - "@backstage/catalog-model": ^1.7.3 - "@backstage/plugin-permission-common": ^0.8.4 - "@backstage/types": ^1.2.1 - "@kubernetes/client-node": 1.0.0-rc7 - kubernetes-models: ^4.3.1 - lodash: ^4.17.21 - luxon: ^3.0.0 - checksum: 88f3e254a95058be2ac2907a47f4c682a2c2684c8321f060bc20243126aabb40306b139219302c339ceb8366ccf62947e05ab89cf77073a9dae2dcc6316cc4ba + checksum: a2fe776551303af628471146cabb58eb45618a15e5ebf04e777598765a7a6f8d93cb6da14d35da4731c98fd509a1198407255279a625a43c5e4bf58836068d6f languageName: node linkType: hard -"@backstage/plugin-kubernetes-common@npm:^0.9.5": - version: 0.9.5 - resolution: "@backstage/plugin-kubernetes-common@npm:0.9.5" +"@backstage/plugin-kubernetes-common@npm:^0.9.2, @backstage/plugin-kubernetes-common@npm:^0.9.6": + version: 0.9.6 + resolution: "@backstage/plugin-kubernetes-common@npm:0.9.6" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/plugin-permission-common": ^0.9.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/plugin-permission-common": ^0.9.1 "@backstage/types": ^1.2.1 "@kubernetes/client-node": 1.1.2 kubernetes-models: ^4.3.1 lodash: ^4.17.21 luxon: ^3.0.0 - checksum: 989b8d75d89140301dab31a2945f1371409928937d55dbcda1b91f030b1b9c2dc33f8825b452d8bcf331123e1758162ec9f7c366891e7640ff7540cf3129808d + checksum: f9a17461c7965be088853785bf163eae30c55044777bb604d1c764be5be95b0b1fb2a04994f5ee39ff6734844e5d88884a0269b5f7ed803ffbcb036e5db2581a languageName: node linkType: hard -"@backstage/plugin-kubernetes-node@npm:^0.3.0": - version: 0.3.1 - resolution: "@backstage/plugin-kubernetes-node@npm:0.3.1" +"@backstage/plugin-kubernetes-node@npm:^0.3.3": + version: 0.3.3 + resolution: "@backstage/plugin-kubernetes-node@npm:0.3.3" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/plugin-kubernetes-common": ^0.9.5 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/plugin-kubernetes-common": ^0.9.6 "@backstage/types": ^1.2.1 "@kubernetes/client-node": 1.1.2 node-fetch: ^2.7.0 winston: ^3.2.1 - checksum: 1874db902bafba3614cca3422ba5731cc5753747bfc223bdd6807da012df7e5bc51529c997fbd12d94aa4793fb13be0347c0ef58d4c694b02e4e8c3affd17f89 - languageName: node - linkType: hard - -"@backstage/plugin-kubernetes-react@npm:^0.5.3": - version: 0.5.5 - resolution: "@backstage/plugin-kubernetes-react@npm:0.5.5" - dependencies: - "@backstage/catalog-model": ^1.7.3 - "@backstage/core-components": ^0.17.0 - "@backstage/core-plugin-api": ^1.10.5 - "@backstage/errors": ^1.2.7 - "@backstage/plugin-kubernetes-common": ^0.9.4 - "@backstage/types": ^1.2.1 - "@kubernetes-models/apimachinery": ^2.0.0 - "@kubernetes-models/base": ^5.0.0 - "@kubernetes/client-node": 1.0.0-rc7 - "@material-ui/core": ^4.9.13 - "@material-ui/icons": ^4.11.3 - "@material-ui/lab": ^4.0.0-alpha.61 - cronstrue: ^2.32.0 - js-yaml: ^4.1.0 - kubernetes-models: ^4.3.1 - lodash: ^4.17.21 - luxon: ^3.0.0 - react-use: ^17.4.0 - xterm: ^5.3.0 - xterm-addon-attach: ^0.9.0 - xterm-addon-fit: ^0.8.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: d9a7bcaea12a139a2b05f5123b7ebd73860a52a48e2bd52777ebbced4b8108132f277e74f5729f4c8715608784767af940681cb69a45e705a72f3e5e86686016 + checksum: 88bfae308f6b6bb35c154f299587a2b3076c4c71d5ff5425f6703612b75adefeaacb52dab0306079b1d20d25a8409aca017919bfd0ae6278747fa2081d5abd78 languageName: node linkType: hard -"@backstage/plugin-kubernetes-react@npm:^0.5.7, @backstage/plugin-kubernetes-react@npm:^0.5.8": - version: 0.5.8 - resolution: "@backstage/plugin-kubernetes-react@npm:0.5.8" +"@backstage/plugin-kubernetes-react@npm:^0.5.10, @backstage/plugin-kubernetes-react@npm:^0.5.11, @backstage/plugin-kubernetes-react@npm:^0.5.3": + version: 0.5.11 + resolution: "@backstage/plugin-kubernetes-react@npm:0.5.11" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 "@backstage/errors": ^1.2.7 - "@backstage/plugin-kubernetes-common": ^0.9.5 - "@backstage/types": ^1.2.1 + "@backstage/plugin-kubernetes-common": ^0.9.6 + "@backstage/types": ^1.2.2 "@kubernetes-models/apimachinery": ^2.0.0 "@kubernetes-models/base": ^5.0.0 "@kubernetes/client-node": 1.1.2 @@ -7043,60 +6513,23 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 9e9fe295df84ac5b80a5f91a79a9cb362fd8faf378d0e7ab733d63f9d4d341ca5087d1e988ca75fe29884aa57248610c1d94059c41760fccfe5da3c22daadada - languageName: node - linkType: hard - -"@backstage/plugin-kubernetes@npm:0.12.7": - version: 0.12.7 - resolution: "@backstage/plugin-kubernetes@npm:0.12.7" - dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-kubernetes-common": ^0.9.5 - "@backstage/plugin-kubernetes-react": ^0.5.7 - "@backstage/plugin-permission-react": ^0.4.34 - "@kubernetes-models/apimachinery": ^2.0.0 - "@kubernetes-models/base": ^5.0.0 - "@kubernetes/client-node": 1.1.2 - "@material-ui/core": ^4.12.2 - cronstrue: ^2.2.0 - js-yaml: ^4.0.0 - kubernetes-models: ^4.1.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - xterm: ^5.2.1 - xterm-addon-attach: ^0.9.0 - xterm-addon-fit: ^0.8.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 191ac18d4bee6d0c3673815f757c058d94619ed8db08902bff541b3102fa1cd394043487ce1e2ed7de81a1bda6c45e87627efeb317e0cae58b73c3d34ae1e089 + checksum: fb790a4f7d64893bdd11039977318cbdfcff3e896b3077007a322687703b286261e7a6beb861752c22a0a234fa15b21776688e68389da29aadffa61d4a2a56a5 languageName: node linkType: hard -"@backstage/plugin-kubernetes@npm:^0.12.7": - version: 0.12.8 - resolution: "@backstage/plugin-kubernetes@npm:0.12.8" +"@backstage/plugin-kubernetes@npm:0.12.10": + version: 0.12.10 + resolution: "@backstage/plugin-kubernetes@npm:0.12.10" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-compat-api": ^0.4.3 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-catalog-react": ^1.19.0 - "@backstage/plugin-kubernetes-common": ^0.9.5 - "@backstage/plugin-kubernetes-react": ^0.5.8 - "@backstage/plugin-permission-react": ^0.4.35 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.5.0 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/plugin-catalog-react": ^1.20.0 + "@backstage/plugin-kubernetes-common": ^0.9.6 + "@backstage/plugin-kubernetes-react": ^0.5.10 + "@backstage/plugin-permission-react": ^0.4.36 "@kubernetes-models/apimachinery": ^2.0.0 "@kubernetes-models/base": ^5.0.0 "@kubernetes/client-node": 1.1.2 @@ -7117,49 +6550,48 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 0c1a3941637ad4f807de30e16c9e879c386624a26941316197717f64a37ad1517f6bcf88c4e8099031905ba93f5b7f40bea7e17b5f9b0ea04895a11c7593ffbe + checksum: 25667592402f6fc4ecd80326025d6b976270d0ad61e52d1830c83326b0bc91d6aebecc9ce1fe1d0cfa65daaf6ef0a64ec782808101bb1af354257ee618934786 languageName: node linkType: hard -"@backstage/plugin-notifications-backend-module-email@npm:0.3.9": - version: 0.3.9 - resolution: "@backstage/plugin-notifications-backend-module-email@npm:0.3.9" +"@backstage/plugin-notifications-backend-module-email@npm:0.3.12": + version: 0.3.12 + resolution: "@backstage/plugin-notifications-backend-module-email@npm:0.3.12" dependencies: "@aws-sdk/client-ses": ^3.550.0 "@aws-sdk/types": ^3.347.0 "@azure/communication-email": ^1.0.0 "@azure/identity": ^4.0.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/integration-aws-node": ^0.1.16 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-notifications-common": ^0.0.8 - "@backstage/plugin-notifications-node": ^0.2.15 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/integration-aws-node": ^0.1.17 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-notifications-common": ^0.1.0 + "@backstage/plugin-notifications-node": ^0.2.18 "@backstage/types": ^1.2.1 lodash: ^4.17.21 nodemailer: ^6.9.13 p-throttle: ^4.1.1 - checksum: ca58560f6199cd5611575494346a3a7a02ccd865414ac92d62efc79799932f78463199a670e1e2b22d41a340884430e9c793a1bc703e67ae649305edee4af293 + checksum: c893c84d275c1ed94294160ab783c92483766dd63d8b584ee3cce26a7b773f89ae750d0df7f689b48fc369d81beaf72411c3deac2327ba37fdc165ba8be67cce languageName: node linkType: hard -"@backstage/plugin-notifications-backend@npm:0.5.6": - version: 0.5.6 - resolution: "@backstage/plugin-notifications-backend@npm:0.5.6" +"@backstage/plugin-notifications-backend@npm:0.5.9": + version: 0.5.9 + resolution: "@backstage/plugin-notifications-backend@npm:0.5.9" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-auth-node": ^0.6.3 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-events-node": ^0.4.11 - "@backstage/plugin-notifications-common": ^0.0.8 - "@backstage/plugin-notifications-node": ^0.2.15 - "@backstage/plugin-signals-node": ^0.1.20 + "@backstage/plugin-auth-node": ^0.6.6 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-events-node": ^0.4.14 + "@backstage/plugin-notifications-common": ^0.1.0 + "@backstage/plugin-notifications-node": ^0.2.18 + "@backstage/plugin-signals-node": ^0.1.23 "@backstage/types": ^1.2.1 express: ^4.17.1 express-promise-router: ^4.1.0 @@ -7168,91 +6600,49 @@ __metadata: uuid: ^11.0.0 winston: ^3.2.1 yn: ^4.0.0 - checksum: 64513e09184f3a63f9fe645744189168681aff673454781975ad80301a6564f0ee6d499f62aa742190cf819ab72e7d062ffd1950ba6a31132c8219cacac2faf2 - languageName: node - linkType: hard - -"@backstage/plugin-notifications-common@npm:^0.0.8": - version: 0.0.8 - resolution: "@backstage/plugin-notifications-common@npm:0.0.8" - dependencies: - "@backstage/config": ^1.3.2 - "@material-ui/icons": ^4.9.1 - checksum: 50e1cc1182ba0f964057b03708a52d1d0b0b2b8c40835b90a391a4594443f335cc1317b8e52fcb3b5abd5ff0bf8b5a00c8b561b9cfd5d5135a5721439b1581e5 + checksum: 7254d0d6cecda3a660034fc7893ade76b0ed49a1227cb8cc4456b769c2a5eac45bd7b70d69d6eb3837494cfb96f781b4b885ab8464d188d7746502599f923a81 languageName: node linkType: hard -"@backstage/plugin-notifications-common@npm:^0.0.9": - version: 0.0.9 - resolution: "@backstage/plugin-notifications-common@npm:0.0.9" +"@backstage/plugin-notifications-common@npm:^0.1.0": + version: 0.1.0 + resolution: "@backstage/plugin-notifications-common@npm:0.1.0" dependencies: - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.3 + "@backstage/types": ^1.2.1 "@material-ui/icons": ^4.9.1 - checksum: d30bbd79eaa75eb395c761201dda6fd8e2045d50452ffcb15c410133b6cf071e3f59c05ceaf8ab86cb8660256a2000ae2a9b24f432613862136aca7aeabf0fa5 + checksum: ea9601f791d2621d34b77f27dd842fea262c030ccb80a5677ef0b112d915c8491fa2d9eec600990e4fc1019e92f0a8c773d7f94f6a0dd483719d85fcd90f2976 languageName: node linkType: hard -"@backstage/plugin-notifications-node@npm:^0.2.15": - version: 0.2.16 - resolution: "@backstage/plugin-notifications-node@npm:0.2.16" +"@backstage/plugin-notifications-node@npm:^0.2.18": + version: 0.2.19 + resolution: "@backstage/plugin-notifications-node@npm:0.2.19" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/plugin-notifications-common": ^0.0.9 - "@backstage/plugin-signals-node": ^0.1.21 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/plugin-notifications-common": ^0.1.0 + "@backstage/plugin-signals-node": ^0.1.24 knex: ^3.0.0 uuid: ^11.0.0 - checksum: 31ab26c5a16dfff289fa359b2784cd0d034c26d81ab212ab19f0b2e3a0c14a5510b6362a20b253e11c2830d0a1852b5429705f567ff75d4fa3fce8b4541424d2 - languageName: node - linkType: hard - -"@backstage/plugin-notifications@npm:0.5.5": - version: 0.5.5 - resolution: "@backstage/plugin-notifications@npm:0.5.5" - dependencies: - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/plugin-notifications-common": ^0.0.8 - "@backstage/plugin-signals-react": ^0.0.13 - "@backstage/theme": ^0.6.6 - "@backstage/types": ^1.2.1 - "@material-ui/core": ^4.9.13 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": ^4.0.0-alpha.61 - lodash: ^4.17.21 - material-ui-confirm: ^3.0.12 - notistack: ^3.0.1 - react-relative-time: ^0.0.9 - react-use: ^17.2.4 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 4865b1b911549c91321ac36537828856dd9d8877e93dc449b6bc58f2d7fffca4d5016002cc68bfac3ff69067b580a8d9895497f88a9537bbb9a9447310cd30de + checksum: 15a2d5f1e62b476a6c6e49c08dd9dce9d56d0fa54bb7f6051e22a0581109c39354cb91a24e582e35a9408dfe9c04fdcc6db50a3abfd77977e85cd367df4609b7 languageName: node linkType: hard -"@backstage/plugin-notifications@npm:^0.5.5": - version: 0.5.6 - resolution: "@backstage/plugin-notifications@npm:0.5.6" +"@backstage/plugin-notifications@npm:0.5.9, @backstage/plugin-notifications@npm:^0.5.8": + version: 0.5.9 + resolution: "@backstage/plugin-notifications@npm:0.5.9" dependencies: - "@backstage/core-compat-api": ^0.4.3 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/core-compat-api": ^0.5.2 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-notifications-common": ^0.0.9 - "@backstage/plugin-signals-react": ^0.0.14 - "@backstage/theme": ^0.6.6 - "@backstage/types": ^1.2.1 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/plugin-notifications-common": ^0.1.0 + "@backstage/plugin-signals-react": ^0.0.15 + "@backstage/theme": ^0.6.8 + "@backstage/types": ^1.2.2 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 @@ -7269,7 +6659,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 7cecdc12e1f7e1a99a6d2577b600d9a5fb68acdf4f67841d96a46286c15f2fb530e9933e1f968087100673f29a72f18bd726c744c69468a9c09aeed0cc321324 + checksum: 797dbe8f45cd00bcf9a753b62d67f4a22a4320c98f849a1cd8448b46b0124217a26cd311731d6e8db81575824a2a67fccba4ebc1c1fab6e29776376383bf817c languageName: node linkType: hard @@ -7302,36 +6692,36 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-common@npm:^0.9.0": - version: 0.9.0 - resolution: "@backstage/plugin-permission-common@npm:0.9.0" +"@backstage/plugin-permission-common@npm:^0.9.1, @backstage/plugin-permission-common@npm:^0.9.2": + version: 0.9.2 + resolution: "@backstage/plugin-permission-common@npm:0.9.2" dependencies: - "@backstage/config": ^1.3.2 + "@backstage/config": ^1.3.5 "@backstage/errors": ^1.2.7 - "@backstage/types": ^1.2.1 + "@backstage/types": ^1.2.2 cross-fetch: ^4.0.0 uuid: ^11.0.0 zod: ^3.22.4 zod-to-json-schema: ^3.20.4 - checksum: 15d9a0df8636aa164c43b4aced6a76eb86ee081f8baef5a1e0221312b37b2ae76ea1e1c4351f4cdb562ae7e2a1a94d696a08868ca2ea6fde15c47d29cdee375c + checksum: b8f74517affdd509b6028e11a324b2683d465fce96272a7096f0a7045d6e3d0a3e48cef3f9f3b51e04ab62cb469ec04aac6037735b3ca8b5c8f48b87f542647a languageName: node linkType: hard -"@backstage/plugin-permission-node@npm:^0.10.0, @backstage/plugin-permission-node@npm:^0.10.1": - version: 0.10.1 - resolution: "@backstage/plugin-permission-node@npm:0.10.1" +"@backstage/plugin-permission-node@npm:^0.10.2, @backstage/plugin-permission-node@npm:^0.10.3, @backstage/plugin-permission-node@npm:^0.10.4": + version: 0.10.4 + resolution: "@backstage/plugin-permission-node@npm:0.10.4" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-auth-node": ^0.6.4 - "@backstage/plugin-permission-common": ^0.9.0 + "@backstage/plugin-auth-node": ^0.6.7 + "@backstage/plugin-permission-common": ^0.9.1 "@types/express": ^4.17.6 express: ^4.17.1 express-promise-router: ^4.1.0 zod: ^3.22.4 zod-to-json-schema: ^3.20.4 - checksum: e6e5a4c201c08757df0c6380ad0b2de368ff06200436b394d7c271748734568e1fe09eff19eaaf011d0a4f843bae13b158a1f35325a41df7b858061b3dd1f287 + checksum: fc29a4168a2f04f539383f578f2fe930ea284568f6b1c804a39801611a3f39c60bc7a3a1c35ed95dcf7a9fd150baadf1f569ac153b3b02b0f727534337c1a5ca languageName: node linkType: hard @@ -7374,24 +6764,6 @@ __metadata: linkType: hard "@backstage/plugin-permission-node@npm:^0.9.0": - version: 0.9.0 - resolution: "@backstage/plugin-permission-node@npm:0.9.0" - dependencies: - "@backstage/backend-plugin-api": ^1.2.1 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/plugin-auth-node": ^0.6.1 - "@backstage/plugin-permission-common": ^0.8.4 - "@types/express": ^4.17.6 - express: ^4.17.1 - express-promise-router: ^4.1.0 - zod: ^3.22.4 - zod-to-json-schema: ^3.20.4 - checksum: c78374ebbb2de9b84b74289be8f06b35b8824e97415661d5310e22d4c4bae0f8f8cb2baf3d811898652b1667991819b2853122cdaf1691d33eef79410a1a8342 - languageName: node - linkType: hard - -"@backstage/plugin-permission-node@npm:^0.9.1": version: 0.9.1 resolution: "@backstage/plugin-permission-node@npm:0.9.1" dependencies: @@ -7409,33 +6781,13 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-react@npm:^0.4.32": - version: 0.4.32 - resolution: "@backstage/plugin-permission-react@npm:0.4.32" - dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-plugin-api": ^1.10.5 - "@backstage/plugin-permission-common": ^0.8.4 - swr: ^2.0.0 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: aeb0d710e80722bf1c7c63b1ad18f4ff8ddd43b1e7d7c3f64eb30548a9b4eead159cbc8796d89e75905afd026feaa9831d95ccb5168abb18a9ceffcf2510388d - languageName: node - linkType: hard - -"@backstage/plugin-permission-react@npm:^0.4.34, @backstage/plugin-permission-react@npm:^0.4.35": - version: 0.4.35 - resolution: "@backstage/plugin-permission-react@npm:0.4.35" +"@backstage/plugin-permission-react@npm:^0.4.36, @backstage/plugin-permission-react@npm:^0.4.37": + version: 0.4.37 + resolution: "@backstage/plugin-permission-react@npm:0.4.37" dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/plugin-permission-common": ^0.9.0 + "@backstage/config": ^1.3.5 + "@backstage/core-plugin-api": ^1.11.1 + "@backstage/plugin-permission-common": ^0.9.2 swr: ^2.0.0 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -7445,100 +6797,56 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 39148fa786eed315ca8607aa8708a104c4a505d21c4a2d975fadc6085db044c77b837af5506f04d20c92aeef4f82a014f80ab14ce7680fddd9c05019d64c7f56 + checksum: c86780da446f23f424ba181b3e42b48f5f4ad527da6f3f89289fc891fec46211264e505f164cb53d9774eefd0414b8f55ac4952990f59ca3233e82b02fa69227 languageName: node linkType: hard -"@backstage/plugin-scaffolder-backend-module-azure@npm:0.2.9": - version: 0.2.9 - resolution: "@backstage/plugin-scaffolder-backend-module-azure@npm:0.2.9" +"@backstage/plugin-scaffolder-backend-module-azure@npm:0.2.12, @backstage/plugin-scaffolder-backend-module-azure@npm:^0.2.6": + version: 0.2.12 + resolution: "@backstage/plugin-scaffolder-backend-module-azure@npm:0.2.12" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-scaffolder-node": ^0.8.2 - azure-devops-node-api: ^14.0.0 - yaml: ^2.0.0 - checksum: 28b749ccbba54c8cdaacc7aca04f3265f2c437d9e177eec1996087aedbc8b34c50bf0b49f97b5b67402ff476ddd5ee0214dd39df143ea936cb6ee8bd5c0f9d27 - languageName: node - linkType: hard - -"@backstage/plugin-scaffolder-backend-module-azure@npm:^0.2.6": - version: 0.2.6 - resolution: "@backstage/plugin-scaffolder-backend-module-azure@npm:0.2.6" - dependencies: - "@backstage/backend-plugin-api": ^1.2.0 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.16.1 - "@backstage/plugin-scaffolder-node": ^0.7.0 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-scaffolder-node": ^0.11.0 azure-devops-node-api: ^14.0.0 yaml: ^2.0.0 - checksum: fa5d1e73b3ce92ce55c808f84574c6ad83a8472d4b2a264fb74a9ef483eb38a6f298691b3a54bab14441e7ce1eeeb7eddd2cdcd7f3f40b4358b8453e8dcb54b2 + checksum: ad93fb1a9c2e95407330e7bc8c320a448b79af24b23271c235aeff6f63cd89b52c0a06417335278826b9561f862f97ba70ddf7c3035c7ac1338e49e488908590 languageName: node linkType: hard -"@backstage/plugin-scaffolder-backend-module-bitbucket-cloud@npm:0.2.9": - version: 0.2.9 - resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud@npm:0.2.9" +"@backstage/plugin-scaffolder-backend-module-bitbucket-cloud@npm:0.2.12, @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@npm:^0.2.6": + version: 0.2.12 + resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud@npm:0.2.12" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-bitbucket-cloud-common": ^0.3.0 - "@backstage/plugin-scaffolder-node": ^0.8.2 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-bitbucket-cloud-common": ^0.3.1 + "@backstage/plugin-scaffolder-node": ^0.11.0 bitbucket: ^2.12.0 fs-extra: ^11.2.0 yaml: ^2.0.0 - checksum: d9f6e5b19f85306777f78cec210ab20afb063dcc200bce7220b662010ddd3a3f8aa002d1167de5290e5223d8ed240c601601ee769ab2341222ef690d79c53e16 - languageName: node - linkType: hard - -"@backstage/plugin-scaffolder-backend-module-bitbucket-cloud@npm:^0.2.6": - version: 0.2.6 - resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud@npm:0.2.6" - dependencies: - "@backstage/backend-plugin-api": ^1.2.0 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.16.1 - "@backstage/plugin-bitbucket-cloud-common": ^0.2.27 - "@backstage/plugin-scaffolder-node": ^0.7.0 - fs-extra: ^11.2.0 - yaml: ^2.0.0 - checksum: f014f351164c6805f4ea3b8ff5cd819d814d934c1b15cbc94ce21cdfd4fe0bcfe5334940b6f10e74cadf75b8f458c6af0f12158fff3c999eb1ab4ac4b6611638 - languageName: node - linkType: hard - -"@backstage/plugin-scaffolder-backend-module-bitbucket-server@npm:0.2.9": - version: 0.2.9 - resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket-server@npm:0.2.9" - dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-scaffolder-node": ^0.8.2 - fs-extra: ^11.2.0 - yaml: ^2.0.0 - checksum: 552b163e9e505d5226e76d4129a3151ed5e525a98a46bfd7253181e6cf0be750647f9c0d8a3a9b8b8a97b763bfcca0b9d4e2b0a0f27bd4be26fc48c3d21952be + zod: ^3.22.4 + checksum: db0612a26e6d8fc28d3df455c677b97d0ae7d1695f8b3face5c7167df4070822f80ecedb1cb8e31cf07f263f05b004006a74a30cdf36a3842f96aa430f22582f languageName: node linkType: hard -"@backstage/plugin-scaffolder-backend-module-bitbucket-server@npm:^0.2.6": - version: 0.2.6 - resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket-server@npm:0.2.6" +"@backstage/plugin-scaffolder-backend-module-bitbucket-server@npm:0.2.12, @backstage/plugin-scaffolder-backend-module-bitbucket-server@npm:^0.2.6": + version: 0.2.12 + resolution: "@backstage/plugin-scaffolder-backend-module-bitbucket-server@npm:0.2.12" dependencies: - "@backstage/backend-plugin-api": ^1.2.0 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.16.1 - "@backstage/plugin-scaffolder-node": ^0.7.0 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-scaffolder-node": ^0.11.0 fs-extra: ^11.2.0 yaml: ^2.0.0 - checksum: 7ba8fe421a8576880b46c4201fbc2054792e6173c9d8d291683714db6013f4fa57d2394bb161a1f3c464e8383e7a87b10d319c9bba11d768fbf7f6777e001e45 + zod: ^3.22.4 + checksum: 04442d4ced6c3bfc2ac0f0f538ad82e630f5f3ecace65446a9ccba843f3c8c9c7eef9e8642812aa233dac456c49ffbbe8525e07f3a21bc1519ff1d2c447aebdc languageName: node linkType: hard @@ -7559,31 +6867,17 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-scaffolder-backend-module-gerrit@npm:0.2.9": - version: 0.2.9 - resolution: "@backstage/plugin-scaffolder-backend-module-gerrit@npm:0.2.9" - dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 - "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-scaffolder-node": ^0.8.2 - yaml: ^2.0.0 - checksum: 8421f140f8d9a23de9af8786be8521afa54b814c6e8ab46813142ce6b124ea8bc65607f105529c331742c3a80bf36a571fbfcbf68c6834f48a0610cff74fc2b3 - languageName: node - linkType: hard - -"@backstage/plugin-scaffolder-backend-module-gerrit@npm:^0.2.6": - version: 0.2.6 - resolution: "@backstage/plugin-scaffolder-backend-module-gerrit@npm:0.2.6" +"@backstage/plugin-scaffolder-backend-module-gerrit@npm:0.2.12, @backstage/plugin-scaffolder-backend-module-gerrit@npm:^0.2.6": + version: 0.2.12 + resolution: "@backstage/plugin-scaffolder-backend-module-gerrit@npm:0.2.12" dependencies: - "@backstage/backend-plugin-api": ^1.2.0 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.16.1 - "@backstage/plugin-scaffolder-node": ^0.7.0 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-scaffolder-node": ^0.11.0 yaml: ^2.0.0 - checksum: 33910425ad5aff12f1e2a306b6ce080ff9459011919622e79e712e60e654b8fda6c6bb91ce816768a9e8a3a40398ce2ddfd477fce5d90aa56c840020283a24e8 + checksum: 9e8f3a9ff52e8af1b207814d20928505bcb90969458baf05fa7d0bac2a0e0e7695282546a774478c5d080ec5dc22a9521496d1e5c3443508f9c67695a5fb1d54 languageName: node linkType: hard @@ -7601,24 +6895,25 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-scaffolder-backend-module-github@npm:0.7.1": - version: 0.7.1 - resolution: "@backstage/plugin-scaffolder-backend-module-github@npm:0.7.1" +"@backstage/plugin-scaffolder-backend-module-github@npm:0.8.2": + version: 0.8.2 + resolution: "@backstage/plugin-scaffolder-backend-module-github@npm:0.8.2" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-scaffolder-node": ^0.8.2 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-scaffolder-node": ^0.11.0 "@backstage/types": ^1.2.1 "@octokit/webhooks": ^10.9.2 libsodium-wrappers: ^0.7.11 octokit: ^3.0.0 octokit-plugin-create-pull-request: ^5.0.0 yaml: ^2.0.0 - checksum: 26f0dad275debab75add0f85241f4bbd31b54cbab690a76f3be353999c334d8b0a5df207c88697a25ca3c27d8ddb2da9a7e0dbee2260612790565ec063df9278 + zod: ^3.22.4 + checksum: 8d381b89d226eebec85a63280cd6c6e43c93c5dbcef56ea7fe6f489f438b6fff752bdf8dedfdc2399d4a85b0c7aedae5e855a7ad0bc94cc2f56b5aff97a9be6f languageName: node linkType: hard @@ -7643,21 +6938,22 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-scaffolder-backend-module-gitlab@npm:0.9.1": - version: 0.9.1 - resolution: "@backstage/plugin-scaffolder-backend-module-gitlab@npm:0.9.1" +"@backstage/plugin-scaffolder-backend-module-gitlab@npm:0.9.4": + version: 0.9.4 + resolution: "@backstage/plugin-scaffolder-backend-module-gitlab@npm:0.9.4" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-scaffolder-node": ^0.8.2 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-scaffolder-node": ^0.11.0 + "@gitbeaker/requester-utils": ^41.2.0 "@gitbeaker/rest": ^41.2.0 luxon: ^3.0.0 winston: ^3.2.1 yaml: ^2.0.0 zod: ^3.22.4 - checksum: 6cdffbbd89b2f03b477657dc9cdb24b0eb74a8f31678be6606968428decd2186a03919459ab6c86616db19f57fd32881df4e71482425b8b530750d62c233a789 + checksum: 53ec6deb3da36fe1dde6a20fa47b0ec5cf5b88d420455f4c098304f523248b892168492aad346cb4365155fc9a5253c2cf2f65625de9d91cf9fc0b7179346996 languageName: node linkType: hard @@ -7741,64 +7037,92 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-scaffolder-common@npm:^1.5.11": - version: 1.5.11 - resolution: "@backstage/plugin-scaffolder-common@npm:1.5.11" +"@backstage/plugin-scaffolder-common@npm:^1.5.11, @backstage/plugin-scaffolder-common@npm:^1.5.6, @backstage/plugin-scaffolder-common@npm:^1.5.9, @backstage/plugin-scaffolder-common@npm:^1.6.0, @backstage/plugin-scaffolder-common@npm:^1.7.1": + version: 1.7.2 + resolution: "@backstage/plugin-scaffolder-common@npm:1.7.2" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/types": ^1.2.1 - checksum: b0006712e3f8fbbdf6d531cf9d12aa2c92887a358858686d4743bfd226fb09a262d50620c212b2d280b78466a24aed2a7c22cc8bd404f8afdda8d447826c53e9 + "@backstage/catalog-model": ^1.7.5 + "@backstage/errors": ^1.2.7 + "@backstage/integration": ^1.18.1 + "@backstage/plugin-permission-common": ^0.9.2 + "@backstage/types": ^1.2.2 + "@microsoft/fetch-event-source": ^2.0.1 + "@types/json-schema": ^7.0.9 + cross-fetch: ^4.0.0 + json-schema: ^0.4.0 + uri-template: ^2.0.0 + zen-observable: ^0.10.0 + checksum: d55b8470c48cb30aa00ea25fad56e973b1d5f0e2cf9488fcb74fe389ce8445a8c9aae767c352246b6f07fa0b8295bdc3dcc5f459752c1e7fdc99eb05131158c6 languageName: node linkType: hard -"@backstage/plugin-scaffolder-common@npm:^1.5.6, @backstage/plugin-scaffolder-common@npm:^1.5.9": - version: 1.5.9 - resolution: "@backstage/plugin-scaffolder-common@npm:1.5.9" +"@backstage/plugin-scaffolder-node@npm:^0.10.0": + version: 0.10.0 + resolution: "@backstage/plugin-scaffolder-node@npm:0.10.0" dependencies: - "@backstage/catalog-model": ^1.7.3 - "@backstage/plugin-permission-common": ^0.8.4 + "@backstage/backend-plugin-api": ^1.4.1 + "@backstage/catalog-model": ^1.7.5 + "@backstage/errors": ^1.2.7 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-scaffolder-common": ^1.6.0 "@backstage/types": ^1.2.1 - checksum: e192066677d2a7d1dfe4870476043015018062e7b68020bd00e1eefa84142367626c85effe0777143c01afd0d5c978942fcbb12e598bcfdff5cbee3965713a5e - languageName: node - linkType: hard - -"@backstage/plugin-scaffolder-node@npm:^0.4.8": - version: 0.4.12 - resolution: "@backstage/plugin-scaffolder-node@npm:0.4.12" - dependencies: - "@backstage/backend-common": ^0.25.0 - "@backstage/backend-plugin-api": ^1.0.0 - "@backstage/catalog-model": ^1.7.0 - "@backstage/errors": ^1.2.4 - "@backstage/integration": ^1.15.0 - "@backstage/plugin-scaffolder-common": ^1.5.6 - "@backstage/types": ^1.1.1 + "@isomorphic-git/pgp-plugin": ^0.0.7 concat-stream: ^2.0.0 fs-extra: ^11.2.0 globby: ^11.0.0 isomorphic-git: ^1.23.0 - jsonschema: ^1.2.6 + jsonschema: ^1.5.0 + lodash: ^4.17.21 p-limit: ^3.1.0 tar: ^6.1.12 winston: ^3.2.1 + winston-transport: ^4.7.0 zod: ^3.22.4 zod-to-json-schema: ^3.20.4 - checksum: 1820b9c459bdb565ff0312cea58f2f4fa06031b46028cbc291ff8a9b61c338452219d690cd6c50cc9ba5ebae3a55f255bb8b7568250bfc55647072a0c1990784 + checksum: 0e9f5481f0dbffcdb0798be749575407fd8ce05246fe6cbb86fc6c5386ed02353521d178439369d8373bb988fc30305d2ac305db465b67e911c305a582a88a84 languageName: node linkType: hard -"@backstage/plugin-scaffolder-node@npm:^0.6.2": - version: 0.6.3 - resolution: "@backstage/plugin-scaffolder-node@npm:0.6.3" +"@backstage/plugin-scaffolder-node@npm:^0.11.0, @backstage/plugin-scaffolder-node@npm:^0.11.1": + version: 0.11.1 + resolution: "@backstage/plugin-scaffolder-node@npm:0.11.1" dependencies: - "@backstage/backend-common": ^0.25.0 - "@backstage/backend-plugin-api": ^1.1.1 - "@backstage/catalog-model": ^1.7.3 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/catalog-model": ^1.7.5 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.16.1 - "@backstage/plugin-scaffolder-common": ^1.5.9 - "@backstage/types": ^1.2.1 + "@backstage/integration": ^1.18.0 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-scaffolder-common": ^1.7.1 + "@backstage/types": ^1.2.2 + "@isomorphic-git/pgp-plugin": ^0.0.7 + concat-stream: ^2.0.0 + fs-extra: ^11.2.0 + globby: ^11.0.0 + isomorphic-git: ^1.23.0 + jsonschema: ^1.5.0 + lodash: ^4.17.21 + p-limit: ^3.1.0 + tar: ^6.1.12 + winston: ^3.2.1 + winston-transport: ^4.7.0 + zod: ^3.22.4 + zod-to-json-schema: ^3.20.4 + checksum: 4e4b30d97ba9d5a73483a9e81bd602db94089dbc229a6ebd2ca4b4e153193a1dfe80d4c0e957b103a2eebadd4da1bacfd1e9e7f06d65026c0671876143b12dd0 + languageName: node + linkType: hard + +"@backstage/plugin-scaffolder-node@npm:^0.4.8": + version: 0.4.12 + resolution: "@backstage/plugin-scaffolder-node@npm:0.4.12" + dependencies: + "@backstage/backend-common": ^0.25.0 + "@backstage/backend-plugin-api": ^1.0.0 + "@backstage/catalog-model": ^1.7.0 + "@backstage/errors": ^1.2.4 + "@backstage/integration": ^1.15.0 + "@backstage/plugin-scaffolder-common": ^1.5.6 + "@backstage/types": ^1.1.1 concat-stream: ^2.0.0 fs-extra: ^11.2.0 globby: ^11.0.0 @@ -7809,7 +7133,7 @@ __metadata: winston: ^3.2.1 zod: ^3.22.4 zod-to-json-schema: ^3.20.4 - checksum: 54b753f5dd49f67a6b09d6dfef3fdb2d68301e04c3e04c9c3dfda022d1a1ff1ae29c70f26d7967d411dfcc31c11493e681e5343c8e885b22ff8060a4018ef3eb + checksum: 1820b9c459bdb565ff0312cea58f2f4fa06031b46028cbc291ff8a9b61c338452219d690cd6c50cc9ba5ebae3a55f255bb8b7568250bfc55647072a0c1990784 languageName: node linkType: hard @@ -7838,11 +7162,11 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-scaffolder-node@npm:^0.8.2": - version: 0.8.2 - resolution: "@backstage/plugin-scaffolder-node@npm:0.8.2" +"@backstage/plugin-scaffolder-node@npm:^0.9.0": + version: 0.9.0 + resolution: "@backstage/plugin-scaffolder-node@npm:0.9.0" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 + "@backstage/backend-plugin-api": ^1.4.0 "@backstage/catalog-model": ^1.7.4 "@backstage/errors": ^1.2.7 "@backstage/integration": ^1.17.0 @@ -7861,154 +7185,124 @@ __metadata: winston-transport: ^4.7.0 zod: ^3.22.4 zod-to-json-schema: ^3.20.4 - checksum: ce70855113d2224ef0fa557c716c47fd4b93f581514efdec19240b598c479b77ac11e2eecf425c76330a0104d6c2e09c49f9a71166606b3de1ec3cae0b418999 + checksum: 90efbcdc6cb7a3dedcd3f24a0ef18be5069be6dc4ed4640c686b5e3ae7929db11400d99643edf85085b660aeb3cdf800067734374c9b7bb78b111743e3b66d78 languageName: node linkType: hard -"@backstage/plugin-search-backend-module-catalog@npm:^0.3.4": - version: 0.3.5 - resolution: "@backstage/plugin-search-backend-module-catalog@npm:0.3.5" +"@backstage/plugin-search-backend-module-catalog@npm:^0.3.7": + version: 0.3.8 + resolution: "@backstage/plugin-search-backend-module-catalog@npm:0.3.8" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.1 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-search-backend-node": ^1.3.12 - "@backstage/plugin-search-common": ^1.2.18 - checksum: 31a6e567a245beb41f9280fecf61161290d24e009f29e1a2d6891797a08d837753ca70d61e1890ba013d202188b714695e0649a0d03e916429c479548cd615cc + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.19.0 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-search-backend-node": ^1.3.15 + "@backstage/plugin-search-common": ^1.2.19 + checksum: 859cd1b46fb09f77f562a1b898329a1d8ec7cfdb54493531623efcf6f9189943e264099389cd4088afcfa998b3b39f123db088789e0f0fbbc63f6aa317a01b41 languageName: node linkType: hard -"@backstage/plugin-search-backend-module-pg@npm:^0.5.44": - version: 0.5.45 - resolution: "@backstage/plugin-search-backend-module-pg@npm:0.5.45" +"@backstage/plugin-search-backend-module-pg@npm:^0.5.47": + version: 0.5.48 + resolution: "@backstage/plugin-search-backend-module-pg@npm:0.5.48" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/config": ^1.3.2 - "@backstage/plugin-search-backend-node": ^1.3.12 - "@backstage/plugin-search-common": ^1.2.18 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/config": ^1.3.3 + "@backstage/plugin-search-backend-node": ^1.3.15 + "@backstage/plugin-search-common": ^1.2.19 knex: ^3.0.0 lodash: ^4.17.21 uuid: ^11.0.0 - checksum: 861c3db0d1675f3612a8df355029d8956730270bf673d7c79e4391bc54d27b8a81ceadabdbc966d904e4bb0387b2d8c4eacc50170960c286c448868d49f6e926 - languageName: node - linkType: hard - -"@backstage/plugin-search-backend-module-techdocs@npm:0.4.2": - version: 0.4.2 - resolution: "@backstage/plugin-search-backend-module-techdocs@npm:0.4.2" - dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-search-backend-node": ^1.3.11 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/plugin-techdocs-node": ^1.13.3 - lodash: ^4.17.21 - p-limit: ^3.1.0 - checksum: 82d6906ce7ae2aa7b551659267543929a23ff97e40a066b122e37a9070394951cb642425560ca70751546a270cf3ec1c60a66653aa85b9c958a1b92de9ceb2ee + checksum: 2de697d0a530a61099a2171bbddca2f83d59013f3f5a070450aa9984170baefae7b8d88ee39252a8da52fd0652b20577d492de9cd77040a471fc9d9e551e39ce languageName: node linkType: hard -"@backstage/plugin-search-backend-module-techdocs@npm:^0.4.2": - version: 0.4.3 - resolution: "@backstage/plugin-search-backend-module-techdocs@npm:0.4.3" - dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/catalog-client": ^1.10.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.1 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-search-backend-node": ^1.3.12 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/plugin-techdocs-node": ^1.13.4 +"@backstage/plugin-search-backend-module-techdocs@npm:0.4.5, @backstage/plugin-search-backend-module-techdocs@npm:^0.4.5": + version: 0.4.5 + resolution: "@backstage/plugin-search-backend-module-techdocs@npm:0.4.5" + dependencies: + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-search-backend-node": ^1.3.14 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/plugin-techdocs-node": ^1.13.6 lodash: ^4.17.21 p-limit: ^3.1.0 - checksum: 860a384a547704e3f91a1f9bd39b8eec2cecdfe88d7991b3730ee8c26f738ba64be0a3c1a6c1f6d72a628de18b3c013ac261703e77d2090487c75eff12c460f3 + checksum: 399f616730d4c225cbc2ed9307c25e71f1601a522186800b87e3146ed48d573c88baa54320213a26d60394dde968f6fa5a7862e848e98977252f0c3bb040b8a2 languageName: node linkType: hard -"@backstage/plugin-search-backend-node@npm:^1.3.11, @backstage/plugin-search-backend-node@npm:^1.3.12": - version: 1.3.12 - resolution: "@backstage/plugin-search-backend-node@npm:1.3.12" +"@backstage/plugin-search-backend-node@npm:^1.3.14, @backstage/plugin-search-backend-node@npm:^1.3.15": + version: 1.3.15 + resolution: "@backstage/plugin-search-backend-node@npm:1.3.15" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-search-common": ^1.2.18 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-search-common": ^1.2.19 "@types/lunr": ^2.3.3 lodash: ^4.17.21 lunr: ^2.3.9 ndjson: ^2.0.0 uuid: ^11.0.0 - checksum: 62314d04c77832f353b08aae1ca09bb3f6e7514ec5854625a09e340a089cc6985af8cafbb8ab93f4545f0317eb7622b77c8116917ffe741fb371608b6a216db6 + checksum: aa779b6276935e82840cadb6b14a98ca1de972425c7f864522e0a2c1d22fda30729eac1287226a0ad87a2a6a8b7d500f568125493bfc56917c6ac4ef9492d1b4 languageName: node linkType: hard -"@backstage/plugin-search-backend@npm:^2.0.2": - version: 2.0.3 - resolution: "@backstage/plugin-search-backend@npm:2.0.3" +"@backstage/plugin-search-backend@npm:^2.0.5": + version: 2.0.6 + resolution: "@backstage/plugin-search-backend@npm:2.0.6" dependencies: - "@backstage/backend-defaults": ^0.11.0 - "@backstage/backend-openapi-utils": ^0.5.4 - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/config": ^1.3.2 + "@backstage/backend-defaults": ^0.12.1 + "@backstage/backend-openapi-utils": ^0.6.1 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.1 - "@backstage/plugin-search-backend-node": ^1.3.12 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/types": ^1.2.1 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.4 + "@backstage/plugin-search-backend-node": ^1.3.15 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/types": ^1.2.2 dataloader: ^2.0.0 express: ^4.17.1 lodash: ^4.17.21 qs: ^6.10.1 yn: ^4.0.0 zod: ^3.22.4 - checksum: 523b493fbd7bfb745d8a65a7e89c5e83b8ea36600aaed56b80c411c9b97086688ba5c5355f67bd66e96c0e93814580e11e1308c65fad7fdceb7b32ac74ab8ca2 - languageName: node - linkType: hard - -"@backstage/plugin-search-common@npm:^1.2.17": - version: 1.2.17 - resolution: "@backstage/plugin-search-common@npm:1.2.17" - dependencies: - "@backstage/plugin-permission-common": ^0.8.4 - "@backstage/types": ^1.2.1 - checksum: 014ac5b4002daa36d2e3c8096d4f64d1ccc9a2b7733de43b6e95bae59e3eaa4f3d32f675b7c02b36b6fbb3c9a3828803fcd4b415bb930db1ac7da5976251de7e + checksum: d3476abe26001d5a9cd39d8dd23b0ef2df804908abb5d241a42c1589526191429848a25003e63e0214b4a4122dfba2ca2735f685e4d1416fb2b6395a952b810d languageName: node linkType: hard -"@backstage/plugin-search-common@npm:^1.2.18": - version: 1.2.18 - resolution: "@backstage/plugin-search-common@npm:1.2.18" +"@backstage/plugin-search-common@npm:^1.2.19, @backstage/plugin-search-common@npm:^1.2.20": + version: 1.2.20 + resolution: "@backstage/plugin-search-common@npm:1.2.20" dependencies: - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/types": ^1.2.1 - checksum: 2c3e380d5f97be4e251d97120db642a09528abd1fbcd4875f7ef121b8e9d63a9c385918da01e07aafb5ca93591dc4948ce5c2a675f11269749d0e6c9b32285ae + "@backstage/plugin-permission-common": ^0.9.2 + "@backstage/types": ^1.2.2 + checksum: 7b04a146b0e91c383797bc79a62b774d06a3358d4af052dd1fcf86958196511bc6dffdec7a72fc0735f3af752d0e977cbb6cc0e3baac7a1840bf0593c22c2cac languageName: node linkType: hard -"@backstage/plugin-search-react@npm:1.9.0": - version: 1.9.0 - resolution: "@backstage/plugin-search-react@npm:1.9.0" +"@backstage/plugin-search-react@npm:1.9.3": + version: 1.9.3 + resolution: "@backstage/plugin-search-react@npm:1.9.3" dependencies: - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/theme": ^0.6.6 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/theme": ^0.6.8 "@backstage/types": ^1.2.1 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.2 @@ -8026,20 +7320,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: e66cc34000406ab755c683d0572f122afb4669a4804ff408a6def982fea27d67d7b5b5e71a784ce875d62eaa87b000445a9bc906da76b8ae3a6be1400de5b7ea + checksum: 29a601312d2106574743671a3131ead4d3cbd5edbc26ce951478e1dfe4713f395e8d89f2b0f843a854f899434ed4e8cd5ae3210b45053f320c06382bede0adb0 languageName: node linkType: hard -"@backstage/plugin-search-react@npm:^1.9.0, @backstage/plugin-search-react@npm:^1.9.1": - version: 1.9.1 - resolution: "@backstage/plugin-search-react@npm:1.9.1" - dependencies: - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/theme": ^0.6.6 - "@backstage/types": ^1.2.1 +"@backstage/plugin-search-react@npm:^1.9.3, @backstage/plugin-search-react@npm:^1.9.4": + version: 1.9.4 + resolution: "@backstage/plugin-search-react@npm:1.9.4" + dependencies: + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/theme": ^0.6.8 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -8056,23 +7350,23 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: a90093a4098347a0ba1ffd9230fe3fcbf8e7047476b07380a11c474e650b358987b934fc5e37137b61587969265acbb3f56a1ee47a1383a0916ba58545d8bae0 + checksum: e72324887739bf3a27f7d1041a039a0fc050d33375878625a9ac9b801966c8f92b9f3ae62bcd90180cc4a8e9ad0a7b36223d01bca090190fc4da30f1670eb348 languageName: node linkType: hard -"@backstage/plugin-search@npm:^1.4.26": - version: 1.4.27 - resolution: "@backstage/plugin-search@npm:1.4.27" +"@backstage/plugin-search@npm:^1.4.29": + version: 1.4.30 + resolution: "@backstage/plugin-search@npm:1.4.30" dependencies: - "@backstage/core-compat-api": ^0.4.3 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/core-compat-api": ^0.5.2 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-catalog-react": ^1.19.0 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/plugin-search-react": ^1.9.1 - "@backstage/types": ^1.2.1 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/plugin-catalog-react": ^1.21.0 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/plugin-search-react": ^1.9.4 + "@backstage/types": ^1.2.2 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 @@ -8086,19 +7380,19 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 22f6aab03a05b7e4a5a66ee1a154dcb7daaf6fec87b163a1e28bdc4675bb38207936c4d606bf5a4dae3f0e7c67b02dcf105507c4b542d6b589cdbad87a2162bc + checksum: 00e7c5ee6231fe7a72f0cf81b7bc09c37448b781814c687541225378aa05ab1258e9da1db8108da1dab2079e31654cd6bbc4c0f455bad296f15ca4fc56c27844 languageName: node linkType: hard -"@backstage/plugin-signals-backend@npm:0.3.4": - version: 0.3.4 - resolution: "@backstage/plugin-signals-backend@npm:0.3.4" +"@backstage/plugin-signals-backend@npm:0.3.7": + version: 0.3.7 + resolution: "@backstage/plugin-signals-backend@npm:0.3.7" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 - "@backstage/plugin-auth-node": ^0.6.3 - "@backstage/plugin-events-node": ^0.4.11 - "@backstage/plugin-signals-node": ^0.1.20 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 + "@backstage/plugin-auth-node": ^0.6.6 + "@backstage/plugin-events-node": ^0.4.14 + "@backstage/plugin-signals-node": ^0.1.23 "@backstage/types": ^1.2.1 express: ^4.17.1 express-promise-router: ^4.1.0 @@ -8107,66 +7401,47 @@ __metadata: winston: ^3.2.1 ws: ^8.18.0 yn: ^4.0.0 - checksum: f6c2ffadbf965c5d8ce13af531e6d66a6471d2a89a60bb14fb96106de6fa594de4946200f0df29185b39d778cdf7c70706bcf8e31f3e2f4897b33159eedf51dc + checksum: c9694eaaba251f68c285c5cecb582afb0b611d1b6d5f5d2f8d19102cd3353669f0b398ea4e818284e7d13c56d2b07bc50900694346e74516438558bc3cb53eff languageName: node linkType: hard -"@backstage/plugin-signals-node@npm:0.1.20": - version: 0.1.20 - resolution: "@backstage/plugin-signals-node@npm:0.1.20" +"@backstage/plugin-signals-node@npm:0.1.23": + version: 0.1.23 + resolution: "@backstage/plugin-signals-node@npm:0.1.23" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/config": ^1.3.2 - "@backstage/plugin-auth-node": ^0.6.3 - "@backstage/plugin-events-node": ^0.4.11 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 + "@backstage/plugin-auth-node": ^0.6.6 + "@backstage/plugin-events-node": ^0.4.14 "@backstage/types": ^1.2.1 express: ^4.17.1 uuid: ^11.0.0 ws: ^8.18.0 - checksum: b54194eccb55ebc2ef2728bf594f020df21703fda6cbf3aa05f0976214832a77bd2b92fb8671e8f125d3219574865cfa83e188d95ca2441f7abd15a89818da76 + checksum: ddca6a7ae61798ca95507252bd620e10060be066af9fbd45bde7a8b1a1d17efb49e81a17882c27ad3f2d96710954db4d99a0a5797f2027cb7eec6f32d336363b languageName: node linkType: hard -"@backstage/plugin-signals-node@npm:^0.1.20, @backstage/plugin-signals-node@npm:^0.1.21": - version: 0.1.21 - resolution: "@backstage/plugin-signals-node@npm:0.1.21" +"@backstage/plugin-signals-node@npm:^0.1.23, @backstage/plugin-signals-node@npm:^0.1.24": + version: 0.1.24 + resolution: "@backstage/plugin-signals-node@npm:0.1.24" dependencies: - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/config": ^1.3.2 - "@backstage/plugin-auth-node": ^0.6.4 - "@backstage/plugin-events-node": ^0.4.12 - "@backstage/types": ^1.2.1 + "@backstage/backend-plugin-api": ^1.4.3 + "@backstage/config": ^1.3.3 + "@backstage/plugin-auth-node": ^0.6.7 + "@backstage/plugin-events-node": ^0.4.15 + "@backstage/types": ^1.2.2 express: ^4.17.1 uuid: ^11.0.0 ws: ^8.18.0 - checksum: bd5a6fefaa853e6869100e3f6d342305d94995b0165bc7c757fe0a30d1f90cfe959c5b07c72abf36ad80d3ab08dede7c2db325bfce772e6e932f19aa3285f0b6 - languageName: node - linkType: hard - -"@backstage/plugin-signals-react@npm:^0.0.13": - version: 0.0.13 - resolution: "@backstage/plugin-signals-react@npm:0.0.13" - dependencies: - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/types": ^1.2.1 - "@material-ui/core": ^4.12.4 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: d874c8fe7dee12ad7dbc9282a3580630bc595210c915411388169a00dba994be49752667e7d44d291692f1df73278724d1401ab20d597e95d15c9efa30ac386e + checksum: 87a30ea84c000212f3c86da6fcef5a5151f804f7f5947763bbe1a167a61489b255065feeb55bbe00f7a40d40df15b994c95a8d5c8c8447bdf37682fcab127518 languageName: node linkType: hard -"@backstage/plugin-signals-react@npm:^0.0.14": - version: 0.0.14 - resolution: "@backstage/plugin-signals-react@npm:0.0.14" +"@backstage/plugin-signals-react@npm:^0.0.15": + version: 0.0.15 + resolution: "@backstage/plugin-signals-react@npm:0.0.15" dependencies: - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/types": ^1.2.1 "@material-ui/core": ^4.12.4 peerDependencies: @@ -8177,19 +7452,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: b3e139835651787d00cc30587c5efa226741cbc5814bacc98b820a4ee380a9217f89a94ef4184d0609770865d7bccb0d02d050a2184f0254068285f6dcf5bec5 + checksum: f5e50bc8d10f9e8c24475eac1bf9d0b293f4ed5f07f82e908121471b4cff57762d96de5c48d5f4a63d192180a8a91f8531afce4e949bbdcb4994ed1cb1c77652 languageName: node linkType: hard -"@backstage/plugin-signals@npm:0.0.19": - version: 0.0.19 - resolution: "@backstage/plugin-signals@npm:0.0.19" +"@backstage/plugin-signals@npm:0.0.22": + version: 0.0.22 + resolution: "@backstage/plugin-signals@npm:0.0.22" dependencies: - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/plugin-signals-react": ^0.0.13 - "@backstage/theme": ^0.6.6 + "@backstage/core-compat-api": ^0.5.0 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/plugin-signals-react": ^0.0.15 + "@backstage/theme": ^0.6.8 "@backstage/types": ^1.2.1 "@material-ui/core": ^4.12.4 "@material-ui/icons": ^4.9.1 @@ -8204,27 +7480,27 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: ac76decf82fc6cf46e76d384e994107f6a482908ab29cf79e121596b745c1ac0c569bed823d86e502a7ae2f25a39f0334d8147e919215b324fdc1720efa80e71 + checksum: 0d14d3d918bd37c6735ac105c565d174817d133ef5027873ddf18a671606d71f480af3aba7e23f948f5c890ffba92b30fe3ecaa31bc78504333226ba6039c11a languageName: node linkType: hard -"@backstage/plugin-techdocs-backend@npm:2.0.2": - version: 2.0.2 - resolution: "@backstage/plugin-techdocs-backend@npm:2.0.2" +"@backstage/plugin-techdocs-backend@npm:2.0.5": + version: 2.0.5 + resolution: "@backstage/plugin-techdocs-backend@npm:2.0.5" dependencies: - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-defaults": ^0.12.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-search-backend-module-techdocs": ^0.4.2 - "@backstage/plugin-techdocs-common": ^0.1.0 - "@backstage/plugin-techdocs-node": ^1.13.3 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-search-backend-module-techdocs": ^0.4.5 + "@backstage/plugin-techdocs-common": ^0.1.1 + "@backstage/plugin-techdocs-node": ^1.13.6 express: ^4.17.1 express-promise-router: ^4.1.0 fs-extra: ^11.2.0 @@ -8232,14 +7508,7 @@ __metadata: lodash: ^4.17.21 p-limit: ^3.1.0 winston: ^3.2.1 - checksum: 9623f475663dcf8bf2478c47b49610318f92f863024715942139ec75fa8e6fe050e921d1da004b8c1f8a645a56631b3aa6f750c404f85d1cd9f0be5b25c8e4eb - languageName: node - linkType: hard - -"@backstage/plugin-techdocs-common@npm:^0.1.0": - version: 0.1.0 - resolution: "@backstage/plugin-techdocs-common@npm:0.1.0" - checksum: e38752e54cd4d516e6ab4908dca16cad7863ecd8c81cf4f0d52a4dbe159c3a2080788f3941395b45011dd47d72930236cd44567a5c7a39efb9a3a037df1b2cba + checksum: 4e5c4a2bed5988de59e498c91a390443790c7407044e7ec73a2adc2420ffaf9799d6c7ea4438aabab7925ec2ed69e9a9553ead89e037004c381dbaeb3eb03162 languageName: node linkType: hard @@ -8250,16 +7519,16 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-techdocs-module-addons-contrib@npm:1.1.24": - version: 1.1.24 - resolution: "@backstage/plugin-techdocs-module-addons-contrib@npm:1.1.24" +"@backstage/plugin-techdocs-module-addons-contrib@npm:1.1.27": + version: 1.1.27 + resolution: "@backstage/plugin-techdocs-module-addons-contrib@npm:1.1.27" dependencies: - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/integration": ^1.17.0 - "@backstage/integration-react": ^1.2.7 - "@backstage/plugin-techdocs-react": ^1.2.17 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/integration": ^1.17.1 + "@backstage/integration-react": ^1.2.9 + "@backstage/plugin-techdocs-react": ^1.3.2 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@react-hookz/web": ^24.0.0 @@ -8273,13 +7542,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 9e1a27ad20e23cf9404b7ac981da9e11fe389f65b79a9380b12df2baf1996cd61cf1e1ff9fb25bbb25fc92ba292b57eac056cd537d7763c44335af57637b9d21 + checksum: f52cb0ddd8ecb8c268db7f534a213fb5fe04397c042034e6ab5e02a6518f1c324ef0752a78096c5fce8d4e751d299cc8d60b2a142590a2bb880a2180f64b4362 languageName: node linkType: hard -"@backstage/plugin-techdocs-node@npm:^1.13.3, @backstage/plugin-techdocs-node@npm:^1.13.4": - version: 1.13.4 - resolution: "@backstage/plugin-techdocs-node@npm:1.13.4" +"@backstage/plugin-techdocs-node@npm:^1.13.6": + version: 1.13.6 + resolution: "@backstage/plugin-techdocs-node@npm:1.13.6" dependencies: "@aws-sdk/client-s3": ^3.350.0 "@aws-sdk/credential-providers": ^3.350.0 @@ -8287,13 +7556,13 @@ __metadata: "@aws-sdk/types": ^3.347.0 "@azure/identity": ^4.0.0 "@azure/storage-blob": ^12.5.0 - "@backstage/backend-plugin-api": ^1.4.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/integration-aws-node": ^0.1.16 - "@backstage/plugin-search-common": ^1.2.18 + "@backstage/integration": ^1.17.1 + "@backstage/integration-aws-node": ^0.1.17 + "@backstage/plugin-search-common": ^1.2.19 "@backstage/plugin-techdocs-common": ^0.1.1 "@google-cloud/storage": ^7.0.0 "@smithy/node-http-handler": ^3.0.0 @@ -8310,19 +7579,20 @@ __metadata: p-limit: ^3.1.0 recursive-readdir: ^2.2.2 winston: ^3.2.1 - checksum: 6f6a2c7f6e53e3cbf10ed8b107de54d6b7f83aa1327fac2ecf4637ec19d28cf2033834f853ffb1141a4c311c4905ef4fbdff6eabb53a78414085e2434f9643b5 + checksum: 928b73e10f6bd970e4885cd523cd394cd328cb4df73862bf92c9b4158de3150603e11cf4e02429be5061e934184cfd2039f1bbc2c63055eae516594752f22dfc languageName: node linkType: hard -"@backstage/plugin-techdocs-react@npm:1.2.17": - version: 1.2.17 - resolution: "@backstage/plugin-techdocs-react@npm:1.2.17" +"@backstage/plugin-techdocs-react@npm:1.3.2": + version: 1.3.2 + resolution: "@backstage/plugin-techdocs-react@npm:1.3.2" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/frontend-plugin-api": ^0.10.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/plugin-techdocs-common": ^0.1.1 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.2 "@material-ui/styles": ^4.11.0 @@ -8338,19 +7608,19 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 03776bde75dc249e432712b87a419e0c525c0e0cb952a614dd59c6420b7bf3ea85a2963e563fcfa306cc9ad8a7ae287b9b1915d0cc4b2450a6b86af77fa3f4d6 + checksum: 81545bcbce892f867d3ff8f141ecbecd6f863de6776cff83d20d9f3310dd0b0518759765e60451bc804851d46a721acac38027fb725ab6e918fe66a599e9f96d languageName: node linkType: hard -"@backstage/plugin-techdocs-react@npm:^1.2.17, @backstage/plugin-techdocs-react@npm:^1.3.0": - version: 1.3.0 - resolution: "@backstage/plugin-techdocs-react@npm:1.3.0" +"@backstage/plugin-techdocs-react@npm:^1.3.2, @backstage/plugin-techdocs-react@npm:^1.3.3": + version: 1.3.3 + resolution: "@backstage/plugin-techdocs-react@npm:1.3.3" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/frontend-plugin-api": ^0.10.3 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 + "@backstage/frontend-plugin-api": ^0.12.0 "@backstage/plugin-techdocs-common": ^0.1.1 "@backstage/version-bridge": ^1.0.11 "@material-ui/core": ^4.12.2 @@ -8367,31 +7637,31 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 8a2fef98a9501e982c238604548f051fe7b76376a887629bc3ef62298cd3c06cb9bc07d2defe3be27a742a75b42814e07dbd74fcd4e4bc7a8ed6a11e4c435545 + checksum: 2d2db27ca65f5fed40df6fb3b7b4b823296a79fa6d1c98180fae52ce56ab9a80b30ee59837ac6c5ba561bf7dd6b77b91a0f355b1fd51a84ed5a19d244689d189 languageName: node linkType: hard -"@backstage/plugin-techdocs@npm:1.12.6": - version: 1.12.6 - resolution: "@backstage/plugin-techdocs@npm:1.12.6" - dependencies: - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/config": ^1.3.2 - "@backstage/core-compat-api": ^0.4.2 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 +"@backstage/plugin-techdocs@npm:1.14.1": + version: 1.14.1 + resolution: "@backstage/plugin-techdocs@npm:1.14.1" + dependencies: + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 + "@backstage/core-compat-api": ^0.5.1 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.2 - "@backstage/integration": ^1.17.0 - "@backstage/integration-react": ^1.2.7 - "@backstage/plugin-auth-react": ^0.1.15 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/plugin-search-react": ^1.9.0 - "@backstage/plugin-techdocs-common": ^0.1.0 - "@backstage/plugin-techdocs-react": ^1.2.17 - "@backstage/theme": ^0.6.6 + "@backstage/frontend-plugin-api": ^0.11.0 + "@backstage/integration": ^1.17.1 + "@backstage/integration-react": ^1.2.9 + "@backstage/plugin-auth-react": ^0.1.18 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/plugin-search-react": ^1.9.3 + "@backstage/plugin-techdocs-common": ^0.1.1 + "@backstage/plugin-techdocs-react": ^1.3.2 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -8411,7 +7681,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: e4f003e558b512e96b6f306a218bbee09e5961d30c28f07197354cefdd71ab3a1aa9ef6752e2decd8969340aa82741711f58b8b20f51fc1f299b03d9a41a9d4c + checksum: 3dec259e94c19080126f3c19bc24f5bddff164a3528f86143bf510ba2652368b26c7d8c01b04b31f3fdf62ce424c07054296e5bddaf742a99001e40b8a9089e7 languageName: node linkType: hard @@ -8422,22 +7692,22 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-user-settings@npm:^0.8.22": - version: 0.8.23 - resolution: "@backstage/plugin-user-settings@npm:0.8.23" +"@backstage/plugin-user-settings@npm:^0.8.25": + version: 0.8.26 + resolution: "@backstage/plugin-user-settings@npm:0.8.26" dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-app-api": ^1.17.1 - "@backstage/core-compat-api": ^0.4.3 - "@backstage/core-components": ^0.17.3 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-app-api": ^1.19.0 + "@backstage/core-compat-api": ^0.5.2 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 "@backstage/errors": ^1.2.7 - "@backstage/frontend-plugin-api": ^0.10.3 - "@backstage/plugin-catalog-react": ^1.19.0 - "@backstage/plugin-signals-react": ^0.0.14 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/plugin-catalog-react": ^1.21.0 + "@backstage/plugin-signals-react": ^0.0.15 "@backstage/plugin-user-settings-common": ^0.0.1 - "@backstage/theme": ^0.6.6 - "@backstage/types": ^1.2.1 + "@backstage/theme": ^0.6.8 + "@backstage/types": ^1.2.2 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -8451,7 +7721,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 1379a2cfd921e85da291771035116b2438b0bcab8add141842e5911f91cacbb78a179bb03a68c1d6cfb86c6131ecd44c8242d2a0ee60910ca67b113c366cf271 + checksum: fb21f77793e769c1b3c028aa5576dec9f5774f4019ccf9717b29b9c883bec22965814ab06319179b404d8c5b87d9943ca69c3d8aac99b6a34ae90ecb34a74374 languageName: node linkType: hard @@ -8464,53 +7734,24 @@ __metadata: languageName: node linkType: hard -"@backstage/release-manifests@npm:^0.0.12": - version: 0.0.12 - resolution: "@backstage/release-manifests@npm:0.0.12" - checksum: 11b1706884d455ab4a2a0069b81f49f8da977374ed8057630fd7ca3eb38c26f2633514c75fd802a49e983f65fbc91b012555bb06a60acda1bf4108e6a2c3114e - languageName: node - linkType: hard - -"@backstage/test-utils@npm:^1.7.6": - version: 1.7.6 - resolution: "@backstage/test-utils@npm:1.7.6" - dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-app-api": ^1.16.0 - "@backstage/core-plugin-api": ^1.10.5 - "@backstage/plugin-permission-common": ^0.8.4 - "@backstage/plugin-permission-react": ^0.4.32 - "@backstage/theme": ^0.6.4 - "@backstage/types": ^1.2.1 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - cross-fetch: ^4.0.0 - i18next: ^22.4.15 - zen-observable: ^0.10.0 - peerDependencies: - "@testing-library/react": ^16.0.0 - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^6.3.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: cca5c7a6e53b3ce86bd8496fb0a5b9abb50f2fe5e66cdaf1ca431df808381f7e4dcdd32412210840d9918dbff0f2e9b460434d7b2e4c70a499394448cb2f2091 +"@backstage/release-manifests@npm:^0.0.13": + version: 0.0.13 + resolution: "@backstage/release-manifests@npm:0.0.13" + checksum: 7a97c3369bef227fa8b56908d2043d0ee5a1a10d66332d0f1373b0c9fed050e7b2bd65595676faa9908144f4ea31d917fc329c7dbe5dc47d53f44abcf6a5bb2a languageName: node linkType: hard -"@backstage/test-utils@npm:^1.7.9": - version: 1.7.9 - resolution: "@backstage/test-utils@npm:1.7.9" +"@backstage/test-utils@npm:^1.7.11, @backstage/test-utils@npm:^1.7.12": + version: 1.7.12 + resolution: "@backstage/test-utils@npm:1.7.12" dependencies: - "@backstage/config": ^1.3.2 - "@backstage/core-app-api": ^1.17.1 - "@backstage/core-plugin-api": ^1.10.8 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-react": ^0.4.35 - "@backstage/theme": ^0.6.6 - "@backstage/types": ^1.2.1 + "@backstage/config": ^1.3.5 + "@backstage/core-app-api": ^1.19.1 + "@backstage/core-plugin-api": ^1.11.1 + "@backstage/plugin-permission-common": ^0.9.2 + "@backstage/plugin-permission-react": ^0.4.37 + "@backstage/theme": ^0.7.0 + "@backstage/types": ^1.2.2 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 cross-fetch: ^4.0.0 @@ -8525,7 +7766,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 0913f9e5697581bc4914e074507c88b2826979bf30a75cbe5baddb641d5b1c0d168d8af10a48e1ba062e996d915b47a4b528c9e6be56b68554ad97c6bc7bf1fa + checksum: 4be157a133f7e464a5cde24dd822c123dfb0f88de784fbbe031f7584827880a5c2a06d70830e672b2ad7ec5fc59e611c4482904c3eb17627f41f54153c1a2dc0 languageName: node linkType: hard @@ -8545,9 +7786,9 @@ __metadata: languageName: node linkType: hard -"@backstage/theme@npm:^0.6.2, @backstage/theme@npm:^0.6.4": - version: 0.6.4 - resolution: "@backstage/theme@npm:0.6.4" +"@backstage/theme@npm:^0.6.4, @backstage/theme@npm:^0.6.6, @backstage/theme@npm:^0.6.7, @backstage/theme@npm:^0.6.8": + version: 0.6.8 + resolution: "@backstage/theme@npm:0.6.8" dependencies: "@emotion/react": ^11.10.5 "@emotion/styled": ^11.10.5 @@ -8561,13 +7802,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: d4c4781af6a38616e12768cd65466ec0f6624d992f4048707d57ee81f395924edd52431279e8a5da17cff5a7050530256a8ce4ac1742177ca94c59d61ff9301a + checksum: 7e208b777ae4f6ea0c546c0a44862986188aaacdb1aca9833c4cc004eb60edaf53ed3f428e90246e165eaa2141cc6e12ba2ec553bf4ca7479c11e4e14d67180d languageName: node linkType: hard -"@backstage/theme@npm:^0.6.5, @backstage/theme@npm:^0.6.6": - version: 0.6.6 - resolution: "@backstage/theme@npm:0.6.6" +"@backstage/theme@npm:^0.7.0": + version: 0.7.0 + resolution: "@backstage/theme@npm:0.7.0" dependencies: "@emotion/react": ^11.10.5 "@emotion/styled": ^11.10.5 @@ -8581,18 +7822,40 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: fdc96e1debf056013bd8a4d726caa53708a3a51ec96bdcf97dad5282daf363c1315779b4942c3117eb2152c3ac5321bd0627f8f972f4b306adaad28a292577a9 + checksum: c6cc3c8bdbeb4fde673e6062242ca1d840edb772b04999e68a42cd731673d0422948aa0b89db4ec4971973175966e528ddfa14f4f009614636c45a2cc3719ba0 languageName: node linkType: hard -"@backstage/types@npm:^1.1.1, @backstage/types@npm:^1.2.1": - version: 1.2.1 - resolution: "@backstage/types@npm:1.2.1" - checksum: 4cf2f2fd5ca6e5f4716c5511ca00cdc8502387976a796098fec9cfd2aea6c6d077c13a46da43b1a7ff1c05fd7b208e7a45b51bbbd024319e9e7a053254fd2222 +"@backstage/types@npm:^1.1.1, @backstage/types@npm:^1.2.1, @backstage/types@npm:^1.2.2": + version: 1.2.2 + resolution: "@backstage/types@npm:1.2.2" + checksum: 12aa576ab6d25db6709b12e25ae69887c4e886f71d5db527c0bbc019d761140fcbc3438b42a32328c4f255514dd23a776c3357f7c21965919ded058d453c67a2 + languageName: node + linkType: hard + +"@backstage/ui@npm:^0.6.1": + version: 0.6.1 + resolution: "@backstage/ui@npm:0.6.1" + dependencies: + "@base-ui-components/react": 1.0.0-alpha.7 + "@remixicon/react": ^4.6.0 + "@tanstack/react-table": ^8.21.3 + clsx: ^2.1.1 + motion: ^12.20.1 + react-aria-components: ^1.10.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + react-router-dom: ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 56cb4b577b7acd2ac5c27843ce6a07a49d8ebc6ec7aa923cf155dea71e2e9e984a87c21b5f5df05da2274859a24431287286ce8855cf0107e1d0c66c4f9c3435 languageName: node linkType: hard -"@backstage/version-bridge@npm:^1.0.11, @backstage/version-bridge@npm:^1.0.8": +"@backstage/version-bridge@npm:^1.0.11": version: 1.0.11 resolution: "@backstage/version-bridge@npm:1.0.11" peerDependencies: @@ -8614,6 +7877,27 @@ __metadata: languageName: node linkType: hard +"@base-ui-components/react@npm:1.0.0-alpha.7": + version: 1.0.0-alpha.7 + resolution: "@base-ui-components/react@npm:1.0.0-alpha.7" + dependencies: + "@babel/runtime": ^7.26.10 + "@floating-ui/react": ^0.27.5 + "@floating-ui/utils": ^0.2.9 + "@react-aria/overlays": ^3.26.1 + prop-types: ^15.8.1 + use-sync-external-store: ^1.4.0 + peerDependencies: + "@types/react": ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: d20f951097500baa13a5856f6c364956e226efa882a8dc1e3787f892d1d103386788b4ce72beb5d5ef92bb4382d9936c63f247b8fc0c87c4345644326bb88fbc + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -8701,6 +7985,13 @@ __metadata: languageName: node linkType: hard +"@date-io/core@npm:^3.0.0, @date-io/core@npm:^3.2.0": + version: 3.2.0 + resolution: "@date-io/core@npm:3.2.0" + checksum: 711e43b449bc29f5f1aaf49e34e722a9fe42238b1ee20e81e3a11692118002872d915c2a289f1ed24e53f88bd220ce3888d7ec0a1705c131e305478f534a3450 + languageName: node + linkType: hard + "@date-io/date-fns@npm:^1.3.13": version: 1.3.13 resolution: "@date-io/date-fns@npm:1.3.13" @@ -8726,6 +8017,20 @@ __metadata: languageName: node linkType: hard +"@date-io/date-fns@npm:^3.0.0": + version: 3.2.1 + resolution: "@date-io/date-fns@npm:3.2.1" + dependencies: + "@date-io/core": ^3.2.0 + peerDependencies: + date-fns: ^3.2.0 || ^4.1.0 + peerDependenciesMeta: + date-fns: + optional: true + checksum: 3c8ab25d604c36b47e8309d50bdb9c0052cb3697a391be030839605449eaff4527e0a9c1bc99e917f40268a6bbff8d8548daaa3bbc864cdcbe79702b53c649db + languageName: node + linkType: hard + "@date-io/dayjs@npm:^2.15.0": version: 2.17.0 resolution: "@date-io/dayjs@npm:2.17.0" @@ -8768,6 +8073,34 @@ __metadata: languageName: node linkType: hard +"@emnapi/core@npm:^1.4.5": + version: 1.4.5 + resolution: "@emnapi/core@npm:1.4.5" + dependencies: + "@emnapi/wasi-threads": 1.0.4 + tslib: ^2.4.0 + checksum: ae4800fe2bcc1c790e588ce19e299fa85c6e1fe2a4ac44eda26be1ad4220b6121de18a735d5fa81307a86576fe2038ab53bde5f8f6aa3708b9276d6600a50b52 + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.4.5": + version: 1.4.5 + resolution: "@emnapi/runtime@npm:1.4.5" + dependencies: + tslib: ^2.4.0 + checksum: 99ab25d55cf1ceeec12f83b60f48e744f8e1dfc8d52a2ed81b3b09bf15182e61ef55f25b69d51ec83044861bddaa4404e7c3285bf71dd518a7980867e41c2a10 + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.0.4": + version: 1.0.4 + resolution: "@emnapi/wasi-threads@npm:1.0.4" + dependencies: + tslib: ^2.4.0 + checksum: 106cbb0c86e0e5a8830a3262105a6531e09ebcc21724f0da64ec49d76d87cbf894e0afcbc3a3621a104abf7465e3f758bffb5afa61a308c31abc847525c10d93 + languageName: node + linkType: hard + "@emotion/babel-plugin@npm:^11.13.5": version: 11.13.5 resolution: "@emotion/babel-plugin@npm:11.13.5" @@ -8800,6 +8133,13 @@ __metadata: languageName: node linkType: hard +"@emotion/core@npm:^11.0.0": + version: 11.0.0 + resolution: "@emotion/core@npm:11.0.0" + checksum: d9beeff0c120ec4d3cd89aa74e1ee3ff658976f27d14820e4e8f8e9981b4461b4a78c9e9c0853397ba09dff36b4e19357858ac8773ee5eb72bfd4b185926b5f3 + languageName: node + linkType: hard + "@emotion/hash@npm:^0.8.0": version: 0.8.0 resolution: "@emotion/hash@npm:0.8.0" @@ -8830,7 +8170,7 @@ __metadata: languageName: node linkType: hard -"@emotion/react@npm:^11.10.5, @emotion/react@npm:^11.11.4": +"@emotion/react@npm:^11.10.4, @emotion/react@npm:^11.10.5, @emotion/react@npm:^11.11.4": version: 11.14.0 resolution: "@emotion/react@npm:11.14.0" dependencies: @@ -8871,9 +8211,9 @@ __metadata: languageName: node linkType: hard -"@emotion/styled@npm:^11.10.5, @emotion/styled@npm:^11.11.5": - version: 11.14.0 - resolution: "@emotion/styled@npm:11.14.0" +"@emotion/styled@npm:^11.10.4, @emotion/styled@npm:^11.10.5, @emotion/styled@npm:^11.11.5": + version: 11.14.1 + resolution: "@emotion/styled@npm:11.14.1" dependencies: "@babel/runtime": ^7.18.3 "@emotion/babel-plugin": ^11.13.5 @@ -8887,7 +8227,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 9c1b842e942e69fb6037d1ab161046d2bcfeff95fd2ccfdab30acaaf6b89dc07b14bb00f8cc8ec14df11e6746c8e4e1d781bc54d10bd739aab44966ded64d4fb + checksum: 86238d9f5c41232a73499e441fa9112e855545519d6772f489fa885634bb8f31b422a9ba9d1e8bc0b4ad66132f9d398b1c309d92c19c5ee21356b41671ec984a languageName: node linkType: hard @@ -8942,9 +8282,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/aix-ppc64@npm:0.24.0" +"@esbuild/aix-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/aix-ppc64@npm:0.25.9" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -8977,9 +8317,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/android-arm64@npm:0.24.0" +"@esbuild/android-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm64@npm:0.25.9" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -9012,9 +8352,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/android-arm@npm:0.24.0" +"@esbuild/android-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm@npm:0.25.9" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -9047,9 +8387,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/android-x64@npm:0.24.0" +"@esbuild/android-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-x64@npm:0.25.9" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -9082,9 +8422,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/darwin-arm64@npm:0.24.0" +"@esbuild/darwin-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-arm64@npm:0.25.9" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -9117,9 +8457,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/darwin-x64@npm:0.24.0" +"@esbuild/darwin-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-x64@npm:0.25.9" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -9152,9 +8492,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/freebsd-arm64@npm:0.24.0" +"@esbuild/freebsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-arm64@npm:0.25.9" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -9187,9 +8527,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/freebsd-x64@npm:0.24.0" +"@esbuild/freebsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-x64@npm:0.25.9" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -9222,9 +8562,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-arm64@npm:0.24.0" +"@esbuild/linux-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm64@npm:0.25.9" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -9257,9 +8597,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-arm@npm:0.24.0" +"@esbuild/linux-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm@npm:0.25.9" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -9292,9 +8632,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-ia32@npm:0.24.0" +"@esbuild/linux-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ia32@npm:0.25.9" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -9327,9 +8667,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-loong64@npm:0.24.0" +"@esbuild/linux-loong64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-loong64@npm:0.25.9" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -9362,9 +8702,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-mips64el@npm:0.24.0" +"@esbuild/linux-mips64el@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-mips64el@npm:0.25.9" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -9397,9 +8737,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-ppc64@npm:0.24.0" +"@esbuild/linux-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ppc64@npm:0.25.9" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -9432,9 +8772,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-riscv64@npm:0.24.0" +"@esbuild/linux-riscv64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-riscv64@npm:0.25.9" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -9467,9 +8807,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-s390x@npm:0.24.0" +"@esbuild/linux-s390x@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-s390x@npm:0.25.9" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -9502,13 +8842,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/linux-x64@npm:0.24.0" +"@esbuild/linux-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-x64@npm:0.25.9" conditions: os=linux & cpu=x64 languageName: node linkType: hard +"@esbuild/netbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-arm64@npm:0.25.9" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.16.17": version: 0.16.17 resolution: "@esbuild/netbsd-x64@npm:0.16.17" @@ -9537,9 +8884,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/netbsd-x64@npm:0.24.0" +"@esbuild/netbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-x64@npm:0.25.9" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -9551,9 +8898,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/openbsd-arm64@npm:0.24.0" +"@esbuild/openbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-arm64@npm:0.25.9" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -9586,13 +8933,20 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/openbsd-x64@npm:0.24.0" +"@esbuild/openbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-x64@npm:0.25.9" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard +"@esbuild/openharmony-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openharmony-arm64@npm:0.25.9" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.16.17": version: 0.16.17 resolution: "@esbuild/sunos-x64@npm:0.16.17" @@ -9621,9 +8975,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/sunos-x64@npm:0.24.0" +"@esbuild/sunos-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/sunos-x64@npm:0.25.9" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -9656,9 +9010,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/win32-arm64@npm:0.24.0" +"@esbuild/win32-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-arm64@npm:0.25.9" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -9691,9 +9045,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/win32-ia32@npm:0.24.0" +"@esbuild/win32-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-ia32@npm:0.25.9" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -9726,9 +9080,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.24.0": - version: 0.24.0 - resolution: "@esbuild/win32-x64@npm:0.24.0" +"@esbuild/win32-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-x64@npm:0.25.9" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -9782,41 +9136,113 @@ __metadata: languageName: node linkType: hard -"@floating-ui/core@npm:^1.0.0": - version: 1.6.0 - resolution: "@floating-ui/core@npm:1.6.0" +"@fastify/busboy@npm:^2.0.0": + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 42c32ef75e906c9a4809c1e1930a5ca6d4ddc8d138e1a8c8ba5ea07f997db32210617d23b2e4a85fe376316a41a1a0439fc6ff2dedf5126d96f45a9d80754fb2 + languageName: node + linkType: hard + +"@floating-ui/core@npm:^1.7.3": + version: 1.7.3 + resolution: "@floating-ui/core@npm:1.7.3" dependencies: - "@floating-ui/utils": ^0.2.1 - checksum: 2e25c53b0c124c5c9577972f8ae21d081f2f7895e6695836a53074463e8c65b47722744d6d2b5a993164936da006a268bcfe87fe68fd24dc235b1cb86bed3127 + "@floating-ui/utils": ^0.2.10 + checksum: 5adfb28ddfa1776ec83516439256b9026e5d62b5413f62ae51e50a870cf0df4bea9abf72aacc0610ee84bc00e85883d0d32f2a0976ee7fa89728a717a7494f27 languageName: node linkType: hard -"@floating-ui/dom@npm:^1.6.1": - version: 1.6.3 - resolution: "@floating-ui/dom@npm:1.6.3" +"@floating-ui/dom@npm:^1.7.4": + version: 1.7.4 + resolution: "@floating-ui/dom@npm:1.7.4" dependencies: - "@floating-ui/core": ^1.0.0 - "@floating-ui/utils": ^0.2.0 - checksum: 81cbb18ece3afc37992f436e469e7fabab2e433248e46fff4302d12493a175b0c64310f8a971e6e1eda7218df28ace6b70237b0f3c22fe12a21bba05b5579555 + "@floating-ui/core": ^1.7.3 + "@floating-ui/utils": ^0.2.10 + checksum: 806923e6f5b09e024c366070f2115a4db6e8ad28462bac29cd075170a6f7d900497da3ee542439bd0770b8e2fff12b636cc30873d1c82e9ec4a487870b080643 languageName: node linkType: hard -"@floating-ui/react-dom@npm:^2.0.8": - version: 2.0.8 - resolution: "@floating-ui/react-dom@npm:2.0.8" +"@floating-ui/react-dom@npm:^2.0.8, @floating-ui/react-dom@npm:^2.1.6": + version: 2.1.6 + resolution: "@floating-ui/react-dom@npm:2.1.6" dependencies: - "@floating-ui/dom": ^1.6.1 + "@floating-ui/dom": ^1.7.4 peerDependencies: react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 5da7f13a69281e38859a3203a608fe9de1d850b332b355c10c0c2427c7b7209a0374c10f6295b6577c1a70237af8b678340bd4cc0a4b1c66436a94755d81e526 + checksum: 24ff266806cd4cba6ad066f0eda7b99583f68af877f41df0b2a8d10a392692e3a1c1d666ebb75571a060818ede940bae59d833aa517ed538f7dba9dddd9991ae languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.0, @floating-ui/utils@npm:^0.2.1": - version: 0.2.1 - resolution: "@floating-ui/utils@npm:0.2.1" - checksum: 9ed4380653c7c217cd6f66ae51f20fdce433730dbc77f95b5abfb5a808f5fdb029c6ae249b4e0490a816f2453aa6e586d9a873cd157fdba4690f65628efc6e06 +"@floating-ui/react@npm:^0.27.5": + version: 0.27.16 + resolution: "@floating-ui/react@npm:0.27.16" + dependencies: + "@floating-ui/react-dom": ^2.1.6 + "@floating-ui/utils": ^0.2.10 + tabbable: ^6.0.0 + peerDependencies: + react: ">=17.0.0" + react-dom: ">=17.0.0" + checksum: 4f242f843ca51c57a0f5c20555da7dfd3b7a4e08e10112371dbf1eff0f390b17b518fa33e72277db85e2c756c1e23ec4605e79850763ad8a17df21bede624fe5 + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.10, @floating-ui/utils@npm:^0.2.9": + version: 0.2.10 + resolution: "@floating-ui/utils@npm:0.2.10" + checksum: ffc4c24a46a665cfd0337e9aaf7de8415b572f8a0f323af39175e4b575582aed13d172e7f049eedeece9eaf022bad019c140a2d192580451984ae529bdf1285c + languageName: node + linkType: hard + +"@formatjs/ecma402-abstract@npm:2.3.6": + version: 2.3.6 + resolution: "@formatjs/ecma402-abstract@npm:2.3.6" + dependencies: + "@formatjs/fast-memoize": 2.2.7 + "@formatjs/intl-localematcher": 0.6.2 + decimal.js: ^10.4.3 + tslib: ^2.8.0 + checksum: ceb2a4b771f63792ed9de1c342da0e27004874c67de963a43b805d21b7a930ccdc62b7aa9ff2ef5da0a750c01b6df02168079218d57a6a37930f927c145c26d2 + languageName: node + linkType: hard + +"@formatjs/fast-memoize@npm:2.2.7": + version: 2.2.7 + resolution: "@formatjs/fast-memoize@npm:2.2.7" + dependencies: + tslib: ^2.8.0 + checksum: e7e6efc677d63a13d99a854305db471b69f64cbfebdcb6dbe507dab9aa7eaae482ca5de86f343c856ca0a2c8f251672bd1f37c572ce14af602c0287378097d43 + languageName: node + linkType: hard + +"@formatjs/icu-messageformat-parser@npm:2.11.4": + version: 2.11.4 + resolution: "@formatjs/icu-messageformat-parser@npm:2.11.4" + dependencies: + "@formatjs/ecma402-abstract": 2.3.6 + "@formatjs/icu-skeleton-parser": 1.8.16 + tslib: ^2.8.0 + checksum: 5213e61e729d0dca2e89f7774d8ef6a84916a50b8bb6cf42acddd8d8174a22b1a3e8ecec0b7a262921b05d1bf55842dea743c4390de3419168e85e7d250c3baa + languageName: node + linkType: hard + +"@formatjs/icu-skeleton-parser@npm:1.8.16": + version: 1.8.16 + resolution: "@formatjs/icu-skeleton-parser@npm:1.8.16" + dependencies: + "@formatjs/ecma402-abstract": 2.3.6 + tslib: ^2.8.0 + checksum: 05dc404c425c1bf09a03a8ca0f69ec95e4ba3cf8ef15555f8ae39f3a775cfb2904f9c60a3e0b8f1b27b8fc17c7b09ca380964e55b32b89bec8d69f83ddfcbd73 + languageName: node + linkType: hard + +"@formatjs/intl-localematcher@npm:0.6.2": + version: 0.6.2 + resolution: "@formatjs/intl-localematcher@npm:0.6.2" + dependencies: + tslib: ^2.8.0 + checksum: 8ed56dc9360f1eac79febfc292243f3607006db54552de847880d201dcf5c9758e44fe3d1b05778f484f899da0db315af24db0ba9f7440e66b447f8fe2d46ff7 languageName: node linkType: hard @@ -9842,6 +9268,17 @@ __metadata: languageName: node linkType: hard +"@gitbeaker/core@npm:^43.5.0": + version: 43.5.0 + resolution: "@gitbeaker/core@npm:43.5.0" + dependencies: + "@gitbeaker/requester-utils": ^43.5.0 + qs: ^6.14.0 + xcase: ^2.0.1 + checksum: 61d0578036f414ed94e6173a16fee85389353fa5022e1a86f77864f44bf1d3dc5a11c9ded623a2351140cea3d5a2263b116e7c6b7ce4b1a747d125ece4bcee82 + languageName: node + linkType: hard + "@gitbeaker/requester-utils@npm:^40.0.3": version: 40.0.3 resolution: "@gitbeaker/requester-utils@npm:40.0.3" @@ -9854,7 +9291,7 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/requester-utils@npm:^41.3.0": +"@gitbeaker/requester-utils@npm:^41.2.0, @gitbeaker/requester-utils@npm:^41.3.0": version: 41.3.0 resolution: "@gitbeaker/requester-utils@npm:41.3.0" dependencies: @@ -9866,6 +9303,18 @@ __metadata: languageName: node linkType: hard +"@gitbeaker/requester-utils@npm:^43.5.0": + version: 43.5.0 + resolution: "@gitbeaker/requester-utils@npm:43.5.0" + dependencies: + picomatch-browser: ^2.2.6 + qs: ^6.14.0 + rate-limiter-flexible: ^7.2.0 + xcase: ^2.0.1 + checksum: 35486080c264f8717e62709a2ec62d89d7db868d431b2f6a8c8e5377e8afa4615074489d61b1539141d46dbe19aa2e6a652a095257d89bf3e016002fc1da757e + languageName: node + linkType: hard + "@gitbeaker/rest@npm:^40.0.3": version: 40.0.3 resolution: "@gitbeaker/rest@npm:40.0.3" @@ -9886,6 +9335,16 @@ __metadata: languageName: node linkType: hard +"@gitbeaker/rest@npm:^43.4.0": + version: 43.5.0 + resolution: "@gitbeaker/rest@npm:43.5.0" + dependencies: + "@gitbeaker/core": ^43.5.0 + "@gitbeaker/requester-utils": ^43.5.0 + checksum: 5e8a957e6f402da54fac5aacd8ec1d32ad1c1cafaab4d09ae6c21601291a34a2c632e4106d3e63aa3d0fb2f6f842f9a0b0e18b0515bb53d86c7a6da3e6444274 + languageName: node + linkType: hard + "@google-cloud/container@npm:^5.0.0": version: 5.8.0 resolution: "@google-cloud/container@npm:5.8.0" @@ -10026,6 +9485,24 @@ __metadata: languageName: node linkType: hard +"@hello-pangea/dnd@npm:^16.0.0": + version: 16.6.0 + resolution: "@hello-pangea/dnd@npm:16.6.0" + dependencies: + "@babel/runtime": ^7.24.1 + css-box-model: ^1.2.1 + memoize-one: ^6.0.0 + raf-schd: ^4.0.3 + react-redux: ^8.1.3 + redux: ^4.2.1 + use-memo-one: ^1.1.3 + peerDependencies: + react: ^16.8.5 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.5 || ^17.0.0 || ^18.0.0 + checksum: 00dcf9c2a7632e56c13e4a38c888081f65cec6bac0640b975b6cd17f2afa8995e8df02735db6f17de3a7ade3779386fc8375d7cedc884f8704e2e6c2977ebcec + languageName: node + linkType: hard + "@httptoolkit/httpolyglot@npm:^2.2.1": version: 2.2.2 resolution: "@httptoolkit/httpolyglot@npm:2.2.2" @@ -10091,31 +9568,31 @@ __metadata: languageName: node linkType: hard -"@immobiliarelabs/backstage-plugin-gitlab-backend@npm:6.12.0": - version: 6.12.0 - resolution: "@immobiliarelabs/backstage-plugin-gitlab-backend@npm:6.12.0" +"@immobiliarelabs/backstage-plugin-gitlab-backend@npm:6.13.0": + version: 6.13.0 + resolution: "@immobiliarelabs/backstage-plugin-gitlab-backend@npm:6.13.0" dependencies: - "@backstage/backend-plugin-api": ^1.3.0 - "@backstage/config": ^1.3.2 - "@backstage/integration": ^1.16.3 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/config": ^1.3.3 + "@backstage/integration": ^1.17.1 body-parser: ^1.20.2 express: ^4.17.3 express-promise-router: ^4.1.0 http-proxy-middleware: ^2.0.6 winston: ^3.2.1 yn: ^4.0.0 - checksum: fc214697796bb577ee246f1c4f618f8c1001ef76c0985d443d2b3954d7b8611fbc64d5a1b48323070f0c76571a8687011cc15289e24162f049357a1f3d21886b + checksum: fa467e99bb76800d56ed5fc58fad6bcec4b4ba025ca7b4094c13de1c2e79fec06c52318af1727ad66f1240ef1c43f39c2159ea930da480d9d6a7efc7aa3d16c7 languageName: node linkType: hard -"@immobiliarelabs/backstage-plugin-gitlab@npm:6.12.0": - version: 6.12.0 - resolution: "@immobiliarelabs/backstage-plugin-gitlab@npm:6.12.0" +"@immobiliarelabs/backstage-plugin-gitlab@npm:6.13.0": + version: 6.13.0 + resolution: "@immobiliarelabs/backstage-plugin-gitlab@npm:6.13.0" dependencies: - "@backstage/core-components": ^0.17.1 - "@backstage/core-plugin-api": ^1.10.6 - "@backstage/plugin-catalog-react": ^1.17.0 - "@backstage/theme": ^0.6.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 @@ -10133,7 +9610,44 @@ __metadata: react-dom: ^16.13.1 || ^18.0.0 react-router: 6.0.0-beta.0 || ^6.20.0 react-router-dom: 6.0.0-beta.0 || ^6.20.0 - checksum: 2692144f56ab89e1dbefd0b9bdbab56c51cb4cd1420d6b5bfb2c6002821a7cae89360999c82c90435a5389136549b86070f1abe85bff1629fc08a1c5d3f6e08d + checksum: e2e55924d9cc5a5362c840a1f934e8d1d7b7a1809ea9a0009b79dacfeab36bb4bc39f6c18381e8cf207306ddb8b716f4fd23b139214a792e4969a24eb4484581 + languageName: node + linkType: hard + +"@internationalized/date@npm:^3.10.0": + version: 3.10.0 + resolution: "@internationalized/date@npm:3.10.0" + dependencies: + "@swc/helpers": ^0.5.0 + checksum: cb6a33622ad368e42fd2d05f9c9111644d0861ea6c9305d7d73b85ddb0cd9259c5af37087d8ed05a2a07d76b798b386c89fb85a2dd567b0f4b0cc19770e0d42b + languageName: node + linkType: hard + +"@internationalized/message@npm:^3.1.8": + version: 3.1.8 + resolution: "@internationalized/message@npm:3.1.8" + dependencies: + "@swc/helpers": ^0.5.0 + intl-messageformat: ^10.1.0 + checksum: 2650af228bd227e7eacf667bc01d9bd647af01c5632917fe22cb8fddeb21602abf1417f7a488d37096bf0fccababcacea0d9d064344f98c489c8c8f59a0367fa + languageName: node + linkType: hard + +"@internationalized/number@npm:^3.6.5": + version: 3.6.5 + resolution: "@internationalized/number@npm:3.6.5" + dependencies: + "@swc/helpers": ^0.5.0 + checksum: 233bcb21da564313bfaf6748ecdab8d35212fd86be784330ff9e95b9bdea9791c23363cd2c530a6a71b1d1aae322c8836254d9d8bce9c9b37c46a7598e98b071 + languageName: node + linkType: hard + +"@internationalized/string@npm:^3.2.7": + version: 3.2.7 + resolution: "@internationalized/string@npm:3.2.7" + dependencies: + "@swc/helpers": ^0.5.0 + checksum: 98b84ff3ca6fae9985340a0d73ce550674d23e6a30fec1d8844c67ba914a4a7b36b44599777ea8b5054a080026c8866a7fe6ccb18f0a77c3963ea6b1e5ac15a4 languageName: node linkType: hard @@ -10325,32 +9839,7 @@ __metadata: languageName: node linkType: hard -"@janus-idp/shared-react@npm:^2.16.0": - version: 2.16.0 - resolution: "@janus-idp/shared-react@npm:2.16.0" - dependencies: - "@backstage/catalog-model": ^1.7.3 - "@backstage/core-components": ^0.16.3 - "@backstage/core-plugin-api": ^1.10.3 - "@backstage/plugin-kubernetes-common": ^0.9.2 - "@backstage/plugin-kubernetes-react": ^0.5.3 - "@kubernetes/client-node": 1.0.0-rc7 - "@material-ui/core": ^4.12.4 - "@mui/icons-material": 5.15.17 - "@mui/material": ^5.15.17 - classnames: ^2.3.2 - date-fns: ^2.30.0 - file-saver: ^2.0.5 - lodash: ^4.17.21 - mathjs: ^11.11.2 - react-use: ^17.5.0 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: 99587964aa0ca9ca4a052751d018f9736f241fadbbdb3c2a738b4efc3b1a1737817d74cedaf898f2500baa2f2c6d8a9030194a32bec6a47c01133b4787fdf226 - languageName: node - linkType: hard - -"@janus-idp/shared-react@npm:^2.18.0": +"@janus-idp/shared-react@npm:^2.16.0, @janus-idp/shared-react@npm:^2.18.0": version: 2.18.0 resolution: "@janus-idp/shared-react@npm:2.18.0" dependencies: @@ -10717,7 +10206,7 @@ __metadata: languageName: node linkType: hard -"@jsonjoy.com/base64@npm:^1.1.1": +"@jsonjoy.com/base64@npm:^1.1.2": version: 1.1.2 resolution: "@jsonjoy.com/base64@npm:1.1.2" peerDependencies: @@ -10726,37 +10215,73 @@ __metadata: languageName: node linkType: hard -"@jsonjoy.com/json-pack@npm:^1.0.3": - version: 1.0.4 - resolution: "@jsonjoy.com/json-pack@npm:1.0.4" +"@jsonjoy.com/buffers@npm:^1.0.0": + version: 1.0.0 + resolution: "@jsonjoy.com/buffers@npm:1.0.0" + peerDependencies: + tslib: 2 + checksum: 2d58ccbab0906cd4006a6428d55d1ef7183ae9b83249824fc6ae23645801c41710109d795a96e44a0aef8a67773af7b15cc6145035dc96d26906905110285b96 + languageName: node + linkType: hard + +"@jsonjoy.com/codegen@npm:^1.0.0": + version: 1.0.0 + resolution: "@jsonjoy.com/codegen@npm:1.0.0" + peerDependencies: + tslib: 2 + checksum: 77383ed703dacc0ee35783589f3289e464d9fd047675f2f628b4d8a567c2b9c87f0121f4445203d51645b5777d24c3b50ed7e12525f4064a0614caae81b1dc2e + languageName: node + linkType: hard + +"@jsonjoy.com/json-pack@npm:^1.11.0": + version: 1.11.0 + resolution: "@jsonjoy.com/json-pack@npm:1.11.0" dependencies: - "@jsonjoy.com/base64": ^1.1.1 - "@jsonjoy.com/util": ^1.1.2 + "@jsonjoy.com/base64": ^1.1.2 + "@jsonjoy.com/buffers": ^1.0.0 + "@jsonjoy.com/codegen": ^1.0.0 + "@jsonjoy.com/json-pointer": ^1.0.1 + "@jsonjoy.com/util": ^1.9.0 hyperdyperid: ^1.2.0 - thingies: ^1.20.0 + thingies: ^2.5.0 peerDependencies: tslib: 2 - checksum: 21e5166d5b5f4856791c2c7019dfba0e8313d2501937543691cdffd5fbe1f9680548a456d2c8aa78929aa69b2ac4c787ca8dbc7cf8e4926330decedcd0d9b8ea + checksum: 72b9fce19d8acbd4b3a3ae8d32869bd170781e7b2bdd5920cf5b756bc02bd79e4a6be68c1de746ff74ec948982ba6316af517916530588603a52fff5781b9e30 languageName: node linkType: hard -"@jsonjoy.com/util@npm:^1.1.2": - version: 1.1.3 - resolution: "@jsonjoy.com/util@npm:1.1.3" +"@jsonjoy.com/json-pointer@npm:^1.0.1": + version: 1.0.2 + resolution: "@jsonjoy.com/json-pointer@npm:1.0.2" + dependencies: + "@jsonjoy.com/codegen": ^1.0.0 + "@jsonjoy.com/util": ^1.9.0 peerDependencies: tslib: 2 - checksum: 144df56aafcae8984d43ebf0f2a11cecb69052286c83522758823710fbf2caabbe93946bdf5c343d3b50073bb0a1c332fea0e797eb8b4df35db480a75b0946ac + checksum: 93b45eb2e5ea3864778dab45c9fd2313cd9fb0fc9fa9a6401c8dea0365e44551fa8debbf3d0efb8b5131c0fde689f4509248b3e2ba12852a8c75739028ec3c1b languageName: node linkType: hard -"@keycloak/keycloak-admin-client@npm:26.1.4": - version: 26.1.4 - resolution: "@keycloak/keycloak-admin-client@npm:26.1.4" +"@jsonjoy.com/util@npm:^1.9.0": + version: 1.9.0 + resolution: "@jsonjoy.com/util@npm:1.9.0" + dependencies: + "@jsonjoy.com/buffers": ^1.0.0 + "@jsonjoy.com/codegen": ^1.0.0 + peerDependencies: + tslib: 2 + checksum: a22c49af0736cede94c24ad8da7230f42697eb5c4a6016450d5bf1cbcb51cd5b45a08989e7ec4cad1cc47718cb5b26e0ba583189f238d095eae4b15cbbe8c9e7 + languageName: node + linkType: hard + +"@keycloak/keycloak-admin-client@npm:26.3.4": + version: 26.3.4 + resolution: "@keycloak/keycloak-admin-client@npm:26.3.4" dependencies: camelize-ts: ^3.0.0 url-join: ^5.0.0 url-template: ^3.1.1 - checksum: ab88b9826fbf91969c94c6e801e8da966c19eb5855d1b3d8e982726c01f53b2ec98cf63cb78dd15438fce37a65e60d1ee6f5e657223cf8625ae4a35b086e3d23 + checksum: 6c181aa0eb2bf1f1a9a19b031d12e8a44547ad8fa34747d72afe1bdcc07d3592a74ccf074e605a3a9574e5e4344be9bd5aebfa417e8961bd339d2a833030619d languageName: node linkType: hard @@ -11069,6 +10594,36 @@ __metadata: languageName: node linkType: hard +"@material-table/core@npm:^6.4.4": + version: 6.4.4 + resolution: "@material-table/core@npm:6.4.4" + dependencies: + "@babel/runtime": ^7.19.0 + "@date-io/core": ^3.0.0 + "@date-io/date-fns": ^3.0.0 + "@emotion/core": ^11.0.0 + "@emotion/react": ^11.10.4 + "@emotion/styled": ^11.10.4 + "@hello-pangea/dnd": ^16.0.0 + "@mui/icons-material": ">=5.10.6" + "@mui/material": ">=5.11.12" + "@mui/x-date-pickers": ^6.19.0 + classnames: ^2.3.2 + date-fns: ^3.2.0 + debounce: ^1.2.1 + deep-eql: ^4.1.1 + deepmerge: ^4.2.2 + prop-types: ^15.8.1 + uuid: ^9.0.0 + zustand: ^4.3.0 + peerDependencies: + "@mui/system": ">=5.15.5" + react: ">=18.0.0" + react-dom: ">=18.0.0" + checksum: 1f4c38951981c9112e3223bd31e5a8b0f486e635f727cd269b6d8d7fec0522c4bf7f3fe02c72be3281ff98e633bd4cb0ec83692c925ef4663dae56863857563e + languageName: node + linkType: hard + "@material-ui/core@npm:4.12.4, @material-ui/core@npm:^4.12.2, @material-ui/core@npm:^4.12.4, @material-ui/core@npm:^4.9.13": version: 4.12.4 resolution: "@material-ui/core@npm:4.12.4" @@ -11298,28 +10853,28 @@ __metadata: languageName: node linkType: hard -"@module-federation/bridge-react-webpack-plugin@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/bridge-react-webpack-plugin@npm:0.8.9" +"@module-federation/bridge-react-webpack-plugin@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/bridge-react-webpack-plugin@npm:0.9.1" dependencies: - "@module-federation/sdk": 0.8.9 + "@module-federation/sdk": 0.9.1 "@types/semver": 7.5.8 semver: 7.6.3 - checksum: f731e42ca14af20634d5a3b41af12f0969a4df5d48270206524fe5a79f1603235a397419c9ba0343735f5c345b1ac67f5c88172d56ed58953b20beb40bea37a0 + checksum: 9515a6a170fdcd5539171fb977730e99474860d1bb39b215a826f936e249ad7ed997a918e72df851e4ddae75a25964fd89c758491317d9b669735d7edc255ed8 languageName: node linkType: hard -"@module-federation/data-prefetch@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/data-prefetch@npm:0.8.9" +"@module-federation/data-prefetch@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/data-prefetch@npm:0.9.1" dependencies: - "@module-federation/runtime": 0.8.9 - "@module-federation/sdk": 0.8.9 + "@module-federation/runtime": 0.9.1 + "@module-federation/sdk": 0.9.1 fs-extra: 9.1.0 peerDependencies: react: ">=16.9.0" react-dom: ">=16.9.0" - checksum: 1b1a078eec13cc0f7e9ca2f3346326c1e4f19cc899e124fd0c351ad717094b2772995660cd622f01a2eb22ad795bb03369699a2dabe0e23ebc7f26109d104458 + checksum: 716c0960d9778269f129eb0c4b17247f1cd4d1c2e086df1ab25f237ffb6a8e69b05d26b483fca2afa33328b5ea482c36c36b5406d3cd6b924978843a962aec18 languageName: node linkType: hard @@ -11352,21 +10907,21 @@ __metadata: languageName: node linkType: hard -"@module-federation/dts-plugin@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/dts-plugin@npm:0.8.9" +"@module-federation/dts-plugin@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/dts-plugin@npm:0.9.1" dependencies: - "@module-federation/error-codes": 0.8.9 - "@module-federation/managers": 0.8.9 - "@module-federation/sdk": 0.8.9 - "@module-federation/third-party-dts-extractor": 0.8.9 + "@module-federation/error-codes": 0.9.1 + "@module-federation/managers": 0.9.1 + "@module-federation/sdk": 0.9.1 + "@module-federation/third-party-dts-extractor": 0.9.1 adm-zip: ^0.5.10 ansi-colors: ^4.1.3 axios: ^1.7.4 chalk: 3.0.0 fs-extra: 9.1.0 isomorphic-ws: 5.0.0 - koa: 2.15.3 + koa: 2.15.4 lodash.clonedeepwith: 4.5.0 log4js: 6.9.1 node-schedule: 2.1.1 @@ -11378,7 +10933,7 @@ __metadata: peerDependenciesMeta: vue-tsc: optional: true - checksum: e5e09c08ca186559a06f539272d2ff9005cc24ee69dd207c992ce9fcf8496640cbbdd022574e8bbdd4d21df886d71975215c3c5b2ae946defaa33f2156cd8bc8 + checksum: 1cd359cf6f154e073261541d09faedbe471888f31980ea4cc4a2813e9b8d37bf84004710e54d4e9cf20db6938c1e576f6a9998810c3f6ca94578f3fda1a3cb67 languageName: node linkType: hard @@ -11408,20 +10963,20 @@ __metadata: languageName: node linkType: hard -"@module-federation/enhanced@npm:^0.8.0": - version: 0.8.9 - resolution: "@module-federation/enhanced@npm:0.8.9" - dependencies: - "@module-federation/bridge-react-webpack-plugin": 0.8.9 - "@module-federation/data-prefetch": 0.8.9 - "@module-federation/dts-plugin": 0.8.9 - "@module-federation/error-codes": 0.8.9 - "@module-federation/inject-external-runtime-core-plugin": 0.8.9 - "@module-federation/managers": 0.8.9 - "@module-federation/manifest": 0.8.9 - "@module-federation/rspack": 0.8.9 - "@module-federation/runtime-tools": 0.8.9 - "@module-federation/sdk": 0.8.9 +"@module-federation/enhanced@npm:^0.9.0": + version: 0.9.1 + resolution: "@module-federation/enhanced@npm:0.9.1" + dependencies: + "@module-federation/bridge-react-webpack-plugin": 0.9.1 + "@module-federation/data-prefetch": 0.9.1 + "@module-federation/dts-plugin": 0.9.1 + "@module-federation/error-codes": 0.9.1 + "@module-federation/inject-external-runtime-core-plugin": 0.9.1 + "@module-federation/managers": 0.9.1 + "@module-federation/manifest": 0.9.1 + "@module-federation/rspack": 0.9.1 + "@module-federation/runtime-tools": 0.9.1 + "@module-federation/sdk": 0.9.1 btoa: ^1.2.1 upath: 2.0.1 peerDependencies: @@ -11435,23 +10990,30 @@ __metadata: optional: true webpack: optional: true - checksum: 12b0cafc428bc65e06cbab407e369fe24739923e1555005b6954cebc379c8c2f8c10758081e479293687fe6c2dba437204f3f8fe7f83545a565a80484c322f82 + checksum: eca72019e3e25f36d835235fbd114aef04c6383cbaf9371f1c6ce9d68e21b5ae75a8ae4d0ae35df0df206d54add98134a0b09cd4169cdafaa4dfaca33c234d28 + languageName: node + linkType: hard + +"@module-federation/error-codes@npm:0.18.0": + version: 0.18.0 + resolution: "@module-federation/error-codes@npm:0.18.0" + checksum: b78b8c8f445de8257caecb6ac6839a3a91fcde2175fbca082f6c70bde44b9af944a9632659adcebd817bb9f52a990fd77d5d7799a8deb1b5e9ff401399203b47 languageName: node linkType: hard -"@module-federation/error-codes@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/error-codes@npm:0.8.9" - checksum: afeacc27a133e7867db4df6f8245b5d5c465fdd2faaec8608aea2b34bd922f38f23c02ed6dcd95303dddb2735b8fcc1bc137a08d470e605ca17807b705053578 +"@module-federation/error-codes@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/error-codes@npm:0.9.1" + checksum: e8584db85db959f1216cffe67dbf3a88e7e0ea63d3732b2615f0709f15fbc118cc51b3c34edd0f33d0991524f57463c3678804ca71f45f9867c2a3f5059e3002 languageName: node linkType: hard -"@module-federation/inject-external-runtime-core-plugin@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/inject-external-runtime-core-plugin@npm:0.8.9" +"@module-federation/inject-external-runtime-core-plugin@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/inject-external-runtime-core-plugin@npm:0.9.1" peerDependencies: - "@module-federation/runtime-tools": 0.8.9 - checksum: 77d8361051d54345d346cf3a3d967ed71d9a0bf83182a101c0dfa5c1f6593219521e80a8fb048a4a47e40a3fc4cd552e388728c853fcdcd52bb8870c7e345069 + "@module-federation/runtime-tools": 0.9.1 + checksum: 931eef6292c278450fc8cdb017073fa0b721796461eee12a254fc60a88a2f17e91395b12371f2c8b3b25b4056fc2dd2b76d1022e679be7353947c3d797e75ea5 languageName: node linkType: hard @@ -11466,14 +11028,14 @@ __metadata: languageName: node linkType: hard -"@module-federation/managers@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/managers@npm:0.8.9" +"@module-federation/managers@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/managers@npm:0.9.1" dependencies: - "@module-federation/sdk": 0.8.9 + "@module-federation/sdk": 0.9.1 find-pkg: 2.0.0 fs-extra: 9.1.0 - checksum: b477542ad7faf02c5fce1c50a5d49ed704aebf11091c942c8cfc8615cced35efd1f3180afd0d281959a6deae792b0f6910d2da9187a83dd7761042a56dfd27b4 + checksum: 78cfb6d0f909c276e16a1898a9c0b52cb71b668513112d8b85baeb38149eae30efdae987f86969a74f498298aff7e39a0b598b62af898d1092a4107c26436cc5 languageName: node linkType: hard @@ -11490,16 +11052,16 @@ __metadata: languageName: node linkType: hard -"@module-federation/manifest@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/manifest@npm:0.8.9" +"@module-federation/manifest@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/manifest@npm:0.9.1" dependencies: - "@module-federation/dts-plugin": 0.8.9 - "@module-federation/managers": 0.8.9 - "@module-federation/sdk": 0.8.9 + "@module-federation/dts-plugin": 0.9.1 + "@module-federation/managers": 0.9.1 + "@module-federation/sdk": 0.9.1 chalk: 3.0.0 find-pkg: 2.0.0 - checksum: a5221fccfc626250f5256a656b55d693077076fcb0b88d103b97c6e4d18f4656752734f5966ded0ac1e1a5a501629d179d23017857da640af0fe46ad2fecdb33 + checksum: 8014325984e5ed51745a8d46153dd5606222d7c998538b1aa9009c5b7bddafef1859e7acace6e25a5d8991bde8835c494a9a1a56b56b3a7d775998681fcde963 languageName: node linkType: hard @@ -11516,17 +11078,17 @@ __metadata: languageName: node linkType: hard -"@module-federation/rspack@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/rspack@npm:0.8.9" +"@module-federation/rspack@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/rspack@npm:0.9.1" dependencies: - "@module-federation/bridge-react-webpack-plugin": 0.8.9 - "@module-federation/dts-plugin": 0.8.9 - "@module-federation/inject-external-runtime-core-plugin": 0.8.9 - "@module-federation/managers": 0.8.9 - "@module-federation/manifest": 0.8.9 - "@module-federation/runtime-tools": 0.8.9 - "@module-federation/sdk": 0.8.9 + "@module-federation/bridge-react-webpack-plugin": 0.9.1 + "@module-federation/dts-plugin": 0.9.1 + "@module-federation/inject-external-runtime-core-plugin": 0.9.1 + "@module-federation/managers": 0.9.1 + "@module-federation/manifest": 0.9.1 + "@module-federation/runtime-tools": 0.9.1 + "@module-federation/sdk": 0.9.1 peerDependencies: "@rspack/core": ">=0.7" typescript: ^4.9.0 || ^5.0.0 @@ -11536,17 +11098,27 @@ __metadata: optional: true vue-tsc: optional: true - checksum: 027b759e0c2b05f55b50835e3dad556ad4b889885fe64de3ee55d62850d3cff7fa746f517f8bc127be3a6d5ac4b6d78bc5c639ed378afe29d3917e4dfef67a8a + checksum: 7ba20a56baac02624aeae412d3dc53b6543a1845cec83920432a0cdc8d2f030116d9780c6429bd1606105ad07df751837ee5b575c4f0d02396b58b10c1b83f86 + languageName: node + linkType: hard + +"@module-federation/runtime-core@npm:0.18.0": + version: 0.18.0 + resolution: "@module-federation/runtime-core@npm:0.18.0" + dependencies: + "@module-federation/error-codes": 0.18.0 + "@module-federation/sdk": 0.18.0 + checksum: 328376a3981c4db185c60dd2806008c9fa7876fd3289a2d2f0f2398e24bdf22a45dbf583809bc252de87c3983f6b21e3fd2b471e82881637ca5f60196dad1274 languageName: node linkType: hard -"@module-federation/runtime-core@npm:0.6.17": - version: 0.6.17 - resolution: "@module-federation/runtime-core@npm:0.6.17" +"@module-federation/runtime-core@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/runtime-core@npm:0.9.1" dependencies: - "@module-federation/error-codes": 0.8.9 - "@module-federation/sdk": 0.8.9 - checksum: c7da28d11137b1d0925461d77660b4e431b2a6f0d66e851f34609c9d7acf515f2db9d993b6c2e993e3721753fb2df8fcd4d0bf62ee7b84cde9367b3bfce873e9 + "@module-federation/error-codes": 0.9.1 + "@module-federation/sdk": 0.9.1 + checksum: 190cec9bd566130cf4670456d31df19f2caa6c7e40d4de336d70602e76f3494eaf87ed23f0bcf308f3d1bafc7e78513b9d154bfdf01ef87ebbdeffebd437c610 languageName: node linkType: hard @@ -11560,13 +11132,23 @@ __metadata: languageName: node linkType: hard -"@module-federation/runtime-tools@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/runtime-tools@npm:0.8.9" +"@module-federation/runtime-tools@npm:0.18.0": + version: 0.18.0 + resolution: "@module-federation/runtime-tools@npm:0.18.0" + dependencies: + "@module-federation/runtime": 0.18.0 + "@module-federation/webpack-bundler-runtime": 0.18.0 + checksum: c6b1483899865e4c73be0ae77e6e1a5f517798f7ab3b8c6df2bb7ed22463e7a471f68d5f9528b2aff5b45e2db67596805028206f3956aafec5a36dcefb94afd2 + languageName: node + linkType: hard + +"@module-federation/runtime-tools@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/runtime-tools@npm:0.9.1" dependencies: - "@module-federation/runtime": 0.8.9 - "@module-federation/webpack-bundler-runtime": 0.8.9 - checksum: d59ba1620d7da5ee8ce2b7cebc4f813efe202b3af1bce9a395409a17f08633f864c0980744069c378896ef5f8bfd68574110873d42d615c36b51bd36e2e48c74 + "@module-federation/runtime": 0.9.1 + "@module-federation/webpack-bundler-runtime": 0.9.1 + checksum: ad5bba8d9e2df15530780eb236075c569f5ae98cf95c12f014ea428efb1222c81e54c620bfc977c2278c42dad02e82e769d0074bf3171600a7357fe5c292a59e languageName: node linkType: hard @@ -11579,14 +11161,25 @@ __metadata: languageName: node linkType: hard -"@module-federation/runtime@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/runtime@npm:0.8.9" +"@module-federation/runtime@npm:0.18.0": + version: 0.18.0 + resolution: "@module-federation/runtime@npm:0.18.0" + dependencies: + "@module-federation/error-codes": 0.18.0 + "@module-federation/runtime-core": 0.18.0 + "@module-federation/sdk": 0.18.0 + checksum: 6164597782b21840e3b8f159000338d8e20a817a60909015c11402e9e6442d60d9c3b4b6f25d92d7261011ef1fc0e8caafbb91f25c29b372f28764cbea8ef9eb + languageName: node + linkType: hard + +"@module-federation/runtime@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/runtime@npm:0.9.1" dependencies: - "@module-federation/error-codes": 0.8.9 - "@module-federation/runtime-core": 0.6.17 - "@module-federation/sdk": 0.8.9 - checksum: 20495c029401431c43f5c5744d83d18c2f8ecafcc97cb960c3973119ec9d8ae313c5ceacbd1ae181331ccf51afb4185a2c8cde6e81ae372d7fa2d42f5af9de0b + "@module-federation/error-codes": 0.9.1 + "@module-federation/runtime-core": 0.9.1 + "@module-federation/sdk": 0.9.1 + checksum: fb74cf6d25d2bfc3c36ef65bf7c3599738dec37ef88be7ebca2193ac872a9049edfa2000c1b395591168c5d4ac000da602f07879bb3419603b308879c0e36852 languageName: node linkType: hard @@ -11597,12 +11190,17 @@ __metadata: languageName: node linkType: hard -"@module-federation/sdk@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/sdk@npm:0.8.9" - dependencies: - isomorphic-rslog: 0.0.7 - checksum: 74effd5aa86b3c9d7a08efc435a8b0bb244010de05b8e84a6269931bc72d59a467654b57c7870380502a1999bcd22c5c138b3558ab26663f366b6cec6b0fe225 +"@module-federation/sdk@npm:0.18.0": + version: 0.18.0 + resolution: "@module-federation/sdk@npm:0.18.0" + checksum: 170104d4d1059ad739a5442e9511027d60aac067a704586119e371a2a15ce0f52dd109ce318896bf4de3346283efe383d0ec0799b68430384e0f89f22e9af4f6 + languageName: node + linkType: hard + +"@module-federation/sdk@npm:0.9.1, @module-federation/sdk@npm:^0.9.0": + version: 0.9.1 + resolution: "@module-federation/sdk@npm:0.9.1" + checksum: e04b9af0993013c43c18765191fcd17eb2324bf22a03460eec79c916252ff6d0a1eaf6f6e238f20410837946bd79ef3d25e2d1b3710ff8892c40a6a03988589d languageName: node linkType: hard @@ -11617,14 +11215,14 @@ __metadata: languageName: node linkType: hard -"@module-federation/third-party-dts-extractor@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/third-party-dts-extractor@npm:0.8.9" +"@module-federation/third-party-dts-extractor@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/third-party-dts-extractor@npm:0.9.1" dependencies: find-pkg: 2.0.0 fs-extra: 9.1.0 resolve: 1.22.8 - checksum: d5e67563ff80a107ba811477271d12bbc5c89869a13499d278961c1f13947f6fb85d9f5316fc9017be77692d876e8b7304136d4154a313023486b521548abafd + checksum: 68c70c79573cd927212d95879aa7b35490519d0ec9f58dd264c9d61e22fea8d452e45a52a94155128d8378e5cdcaecb229707b5b0f4e4c0d53ae96e2fbac366a languageName: node linkType: hard @@ -11638,13 +11236,23 @@ __metadata: languageName: node linkType: hard -"@module-federation/webpack-bundler-runtime@npm:0.8.9": - version: 0.8.9 - resolution: "@module-federation/webpack-bundler-runtime@npm:0.8.9" +"@module-federation/webpack-bundler-runtime@npm:0.18.0": + version: 0.18.0 + resolution: "@module-federation/webpack-bundler-runtime@npm:0.18.0" + dependencies: + "@module-federation/runtime": 0.18.0 + "@module-federation/sdk": 0.18.0 + checksum: e2234ed13508dd047d53a13e3aac1c81b5bc83bd73e4fd70fead2b312a2e46f15a87b5cffa9e224271403d7f2c15717759a19194821d6450bbfcd9af3e0e9550 + languageName: node + linkType: hard + +"@module-federation/webpack-bundler-runtime@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/webpack-bundler-runtime@npm:0.9.1" dependencies: - "@module-federation/runtime": 0.8.9 - "@module-federation/sdk": 0.8.9 - checksum: 1ca36a54976207682cbac0e74eae7ceb7be102aff5008ed5b5f77a8aeab7e74198cd4c26a7c521ab6b38d4e7c31c86115901aa69753e76094012d171a1f79e4d + "@module-federation/runtime": 0.9.1 + "@module-federation/sdk": 0.9.1 + checksum: a1597a9760424ccd89ceb72c3333264af215ebf15fb3e6c6703e11afe3c8ad2002072a65782aa3ae3909edf31bc007f63aacc190aa9f1dce2e5863e0bb96438a languageName: node linkType: hard @@ -11696,28 +11304,6 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.40-0": - version: 5.0.0-beta.40-0 - resolution: "@mui/base@npm:5.0.0-beta.40-0" - dependencies: - "@babel/runtime": ^7.23.9 - "@floating-ui/react-dom": ^2.0.8 - "@mui/types": ^7.2.15 - "@mui/utils": ^5.16.12 - "@popperjs/core": ^2.11.8 - clsx: ^2.1.0 - prop-types: ^15.8.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: e2661562fa2e213dadd6c5900bd02ef50a7af193e5205c0ef7b2c3549656672a6b670aad3020c2a0a5f7ff741f3ed854196110441fd8ed2555578e68004f91a6 - languageName: node - linkType: hard - "@mui/base@npm:5.0.0-beta.40-1": version: 5.0.0-beta.40-1 resolution: "@mui/base@npm:5.0.0-beta.40-1" @@ -11762,13 +11348,6 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.17.1": - version: 5.17.1 - resolution: "@mui/core-downloads-tracker@npm:5.17.1" - checksum: 40a697aa031f089dde29812563320221efa1ec18840b0d0b744ba8846b558146d58910b5b4e67b7eb1942c6817ffc389b4b6b28456c762d39d250bc1e54423f7 - languageName: node - linkType: hard - "@mui/core-downloads-tracker@npm:^5.18.0": version: 5.18.0 resolution: "@mui/core-downloads-tracker@npm:5.18.0" @@ -11776,6 +11355,13 @@ __metadata: languageName: node linkType: hard +"@mui/core-downloads-tracker@npm:^7.3.2": + version: 7.3.2 + resolution: "@mui/core-downloads-tracker@npm:7.3.2" + checksum: 01c0976e5fb6a8f0b59ebd58019af5452d7761e97daf0f2ef121bc3323508edf2fea1b13ea1a54b0098d6ee5eef70041c9722fe43291b237b989b6813a24b71e + languageName: node + linkType: hard + "@mui/icons-material@npm:5.15.17": version: 5.15.17 resolution: "@mui/icons-material@npm:5.15.17" @@ -11792,25 +11378,9 @@ __metadata: languageName: node linkType: hard -"@mui/icons-material@npm:5.16.14": - version: 5.16.14 - resolution: "@mui/icons-material@npm:5.16.14" - dependencies: - "@babel/runtime": ^7.23.9 - peerDependencies: - "@mui/material": ^5.0.0 - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 14c01298e47972099ce71a8f142e2bb93dfc61a3ac0239030c55b3e5c6719f692e9c2fac131247c52f4922e74b08291ecb1f3398117222cc7baa82ec6f38e073 - languageName: node - linkType: hard - -"@mui/icons-material@npm:5.17.1, @mui/icons-material@npm:^5.15.17, @mui/icons-material@npm:^5.15.19, @mui/icons-material@npm:^5.16.4, @mui/icons-material@npm:^5.16.7, @mui/icons-material@npm:^5.17.1": - version: 5.17.1 - resolution: "@mui/icons-material@npm:5.17.1" +"@mui/icons-material@npm:5.18.0, @mui/icons-material@npm:^5.15.17, @mui/icons-material@npm:^5.15.19, @mui/icons-material@npm:^5.16.4, @mui/icons-material@npm:^5.16.7, @mui/icons-material@npm:^5.17.1": + version: 5.18.0 + resolution: "@mui/icons-material@npm:5.18.0" dependencies: "@babel/runtime": ^7.23.9 peerDependencies: @@ -11820,23 +11390,23 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 015149e65add85ab0c669829fabf2cfb9c0a95e33a527716f05f8bdc48247a1f0db5e4c83406d70e22600f7c8e54c339a7237e5d8223b73caa724d7b87ce2b0a + checksum: 1ee4ee2817278c72095860c81e742270ee01fd320e48f865d371abfeacf83e43a7c6edbfd060ee66ef2a4f02c6cf79de0aca1e73a4d5f6320112bbfcac8176c3 languageName: node linkType: hard -"@mui/icons-material@npm:5.18.0": - version: 5.18.0 - resolution: "@mui/icons-material@npm:5.18.0" +"@mui/icons-material@npm:>=5.10.6": + version: 7.3.2 + resolution: "@mui/icons-material@npm:7.3.2" dependencies: - "@babel/runtime": ^7.23.9 + "@babel/runtime": ^7.28.3 peerDependencies: - "@mui/material": ^5.0.0 + "@mui/material": ^7.3.2 "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 1ee4ee2817278c72095860c81e742270ee01fd320e48f865d371abfeacf83e43a7c6edbfd060ee66ef2a4f02c6cf79de0aca1e73a4d5f6320112bbfcac8176c3 + checksum: 30d31b05510c9da3bd5ba97960a0210298c101abf58efc77b2b6647b1edaf0d4b81aa671a9f5790f17977970e8cdca9139da8cfac4de31be618908754e9a3d7f languageName: node linkType: hard @@ -11856,42 +11426,13 @@ __metadata: languageName: node linkType: hard -"@mui/lab@npm:5.0.0-alpha.175": - version: 5.0.0-alpha.175 - resolution: "@mui/lab@npm:5.0.0-alpha.175" - dependencies: - "@babel/runtime": ^7.23.9 - "@mui/base": 5.0.0-beta.40-0 - "@mui/system": ^5.16.12 - "@mui/types": ^7.2.15 - "@mui/utils": ^5.16.12 - clsx: ^2.1.0 - prop-types: ^15.8.1 - peerDependencies: - "@emotion/react": ^11.5.0 - "@emotion/styled": ^11.3.0 - "@mui/material": ">=5.15.0" - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 - react: ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": - optional: true - "@types/react": - optional: true - checksum: 416e43279a1db35d33f89311e6e6b5113433cd4e51bcb3f1fb90f254c632e653eb30c14e7241d64a0de73443276c8a7b0ff60250b75c2178c895b542f0a3b368 - languageName: node - linkType: hard - -"@mui/lab@npm:5.0.0-alpha.176": - version: 5.0.0-alpha.176 - resolution: "@mui/lab@npm:5.0.0-alpha.176" +"@mui/lab@npm:5.0.0-alpha.177": + version: 5.0.0-alpha.177 + resolution: "@mui/lab@npm:5.0.0-alpha.177" dependencies: "@babel/runtime": ^7.23.9 "@mui/base": 5.0.0-beta.40-1 - "@mui/system": ^5.17.1 + "@mui/system": ^5.18.0 "@mui/types": ~7.2.15 "@mui/utils": ^5.17.1 clsx: ^2.1.0 @@ -11910,17 +11451,17 @@ __metadata: optional: true "@types/react": optional: true - checksum: afa6da4c4583fc201ac3e6f6ae143d1a4fd0cf8a79e1ce8d6cefe2b9fb3862fa9eae490c4a60cde12923128d70d583e9fcc3f0a1a31c9ff930fd3d1e0c8aa378 + checksum: 58a3983ae28993b91c1d3cca29d0dbf904b252ab7a7edc81eebd0696dc53dbdc8144d1727761cc09cd9833cf3ce2fd5e422864c2feac37161d6dc60ad88bf88a languageName: node linkType: hard -"@mui/material@npm:5.17.1, @mui/material@npm:^5.12.2, @mui/material@npm:^5.14.18, @mui/material@npm:^5.15.16, @mui/material@npm:^5.15.17, @mui/material@npm:^5.15.19": - version: 5.17.1 - resolution: "@mui/material@npm:5.17.1" +"@mui/material@npm:5.18.0, @mui/material@npm:^5.12.2, @mui/material@npm:^5.14.18, @mui/material@npm:^5.15.16, @mui/material@npm:^5.15.17, @mui/material@npm:^5.15.19": + version: 5.18.0 + resolution: "@mui/material@npm:5.18.0" dependencies: "@babel/runtime": ^7.23.9 - "@mui/core-downloads-tracker": ^5.17.1 - "@mui/system": ^5.17.1 + "@mui/core-downloads-tracker": ^5.18.0 + "@mui/system": ^5.18.0 "@mui/types": ~7.2.15 "@mui/utils": ^5.17.1 "@popperjs/core": ^2.11.8 @@ -11943,29 +11484,30 @@ __metadata: optional: true "@types/react": optional: true - checksum: 26ff24f6d7ec1e429cf1dbe502046c8bcb684852bcfc32250b545c609ed38cef01985bbeec7ff294abe8b48be896cf9774e1198495b588d6c93cc56c9aecfbae + checksum: b9d6cf638774e65924adf6f58ad50639c55050b33dc6223aa74686f733e137d173b4594b28be70e8ea3baf413a7fcd3bee40d35e3af12a42b7ba03def71ea217 languageName: node linkType: hard -"@mui/material@npm:5.18.0": - version: 5.18.0 - resolution: "@mui/material@npm:5.18.0" +"@mui/material@npm:>=5.11.12": + version: 7.3.2 + resolution: "@mui/material@npm:7.3.2" dependencies: - "@babel/runtime": ^7.23.9 - "@mui/core-downloads-tracker": ^5.18.0 - "@mui/system": ^5.18.0 - "@mui/types": ~7.2.15 - "@mui/utils": ^5.17.1 + "@babel/runtime": ^7.28.3 + "@mui/core-downloads-tracker": ^7.3.2 + "@mui/system": ^7.3.2 + "@mui/types": ^7.4.6 + "@mui/utils": ^7.3.2 "@popperjs/core": ^2.11.8 - "@types/react-transition-group": ^4.4.10 - clsx: ^2.1.0 + "@types/react-transition-group": ^4.4.12 + clsx: ^2.1.1 csstype: ^3.1.3 prop-types: ^15.8.1 - react-is: ^19.0.0 + react-is: ^19.1.1 react-transition-group: ^4.4.5 peerDependencies: "@emotion/react": ^11.5.0 "@emotion/styled": ^11.3.0 + "@mui/material-pigment-css": ^7.3.2 "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -11974,13 +11516,15 @@ __metadata: optional: true "@emotion/styled": optional: true + "@mui/material-pigment-css": + optional: true "@types/react": optional: true - checksum: b9d6cf638774e65924adf6f58ad50639c55050b33dc6223aa74686f733e137d173b4594b28be70e8ea3baf413a7fcd3bee40d35e3af12a42b7ba03def71ea217 + checksum: 993e0c33ed5d180cdac13fadfa067bd753ceb3a01940a777b6dcdbd347324ae0d0c000ef567f6cc358e065033e131ce0e9bc8790a29502146b805978938c5c0f languageName: node linkType: hard -"@mui/private-theming@npm:^5.16.14, @mui/private-theming@npm:^5.17.1": +"@mui/private-theming@npm:^5.17.1": version: 5.17.1 resolution: "@mui/private-theming@npm:5.17.1" dependencies: @@ -12014,28 +11558,24 @@ __metadata: languageName: node linkType: hard -"@mui/styled-engine@npm:5.16.14, @mui/styled-engine@npm:^5.16.14": - version: 5.16.14 - resolution: "@mui/styled-engine@npm:5.16.14" +"@mui/private-theming@npm:^7.3.2": + version: 7.3.2 + resolution: "@mui/private-theming@npm:7.3.2" dependencies: - "@babel/runtime": ^7.23.9 - "@emotion/cache": ^11.13.5 - csstype: ^3.1.3 + "@babel/runtime": ^7.28.3 + "@mui/utils": ^7.3.2 prop-types: ^15.8.1 peerDependencies: - "@emotion/react": ^11.4.1 - "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: - "@emotion/react": - optional: true - "@emotion/styled": + "@types/react": optional: true - checksum: 5868683e6dd4004b34a0ce9de8842c180f7b7618c0b8cff904771659ef2da3aae574ea10b0c5ad6ffe59db396f699773ebb99f3f9d831d8b5adc398ecc618195 + checksum: 443f898565cbe4a99742a84d68c6e18c2ab306a4279a00313d42a07a59cf75e8cde9356bfe9e1fd6e99d0eb08e0fa9797de34d2df12004ee3185c025feb2a7c5 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.18.0": +"@mui/styled-engine@npm:5.18.0, @mui/styled-engine@npm:^5.18.0": version: 5.18.0 resolution: "@mui/styled-engine@npm:5.18.0" dependencies: @@ -12057,40 +11597,32 @@ __metadata: languageName: node linkType: hard -"@mui/styles@npm:5.16.14": - version: 5.16.14 - resolution: "@mui/styles@npm:5.16.14" +"@mui/styled-engine@npm:^7.3.2": + version: 7.3.2 + resolution: "@mui/styled-engine@npm:7.3.2" dependencies: - "@babel/runtime": ^7.23.9 - "@emotion/hash": ^0.9.1 - "@mui/private-theming": ^5.16.14 - "@mui/types": ^7.2.15 - "@mui/utils": ^5.16.14 - clsx: ^2.1.0 + "@babel/runtime": ^7.28.3 + "@emotion/cache": ^11.14.0 + "@emotion/serialize": ^1.3.3 + "@emotion/sheet": ^1.4.0 csstype: ^3.1.3 - hoist-non-react-statics: ^3.3.2 - jss: ^10.10.0 - jss-plugin-camel-case: ^10.10.0 - jss-plugin-default-unit: ^10.10.0 - jss-plugin-global: ^10.10.0 - jss-plugin-nested: ^10.10.0 - jss-plugin-props-sort: ^10.10.0 - jss-plugin-rule-value-function: ^10.10.0 - jss-plugin-vendor-prefixer: ^10.10.0 prop-types: ^15.8.1 peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + "@emotion/react": ^11.4.1 + "@emotion/styled": ^11.3.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: - "@types/react": + "@emotion/react": optional: true - checksum: 1d579e005f26a76e39feeda8634cbf41d041dcfe85ca6cfa19180ca1e6477bc909966a4738a6a875bd9d18b4157272d60869bbf94546c4813db551df19c0e6aa + "@emotion/styled": + optional: true + checksum: 452ab8bfa9a4e06b6b9a227f06465d356602459dac92fe3197eed6b5d278ec178b902405217071cc2490e515fe56b9993bb7610db75204a7eb58fd8ab840c167 languageName: node linkType: hard -"@mui/styles@npm:5.17.1": - version: 5.17.1 - resolution: "@mui/styles@npm:5.17.1" +"@mui/styles@npm:5.18.0": + version: 5.18.0 + resolution: "@mui/styles@npm:5.18.0" dependencies: "@babel/runtime": ^7.23.9 "@emotion/hash": ^0.9.1 @@ -12115,7 +11647,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 3e9de5bc582cc99be5ea8bf3c6ec81cd1472d96c7c11fef70fa21e1e5ea7f3dc10d1a9be793ea39e37eb1896e44263adc313e42d711fdf9c4e2d9172d00997df + checksum: 290cd7b7d738277c7024ac3f0840b2fd9f973008bd18a67294a8e1f401ffbca992311101c9af5cc1b799abd8c3ec469a0096c5d8cccc6b540218c433b0040f28 languageName: node linkType: hard @@ -12150,13 +11682,13 @@ __metadata: languageName: node linkType: hard -"@mui/system@npm:^5.16.12, @mui/system@npm:^5.16.5, @mui/system@npm:^5.17.1": - version: 5.17.1 - resolution: "@mui/system@npm:5.17.1" +"@mui/system@npm:^5.16.5, @mui/system@npm:^5.18.0": + version: 5.18.0 + resolution: "@mui/system@npm:5.18.0" dependencies: "@babel/runtime": ^7.23.9 "@mui/private-theming": ^5.17.1 - "@mui/styled-engine": ^5.16.14 + "@mui/styled-engine": ^5.18.0 "@mui/types": ~7.2.15 "@mui/utils": ^5.17.1 clsx: ^2.1.0 @@ -12174,20 +11706,20 @@ __metadata: optional: true "@types/react": optional: true - checksum: 104f57a82c4b314aa49fb8e1d52885b415e4a65d80431f8eb94c93769ba798feabc7107abbdbc3793a99d4a71f122edf87e1874151c2c7e714677aeb0c734df4 + checksum: 451f43889c2638da7c52b898e6174eafcdbcbcaaf3a79f954fdd58d9a043786d76fa4fca902cfdd6ab1aa250f5b1f932ef93d789c5a15987d893c0741bf7a1ad languageName: node linkType: hard -"@mui/system@npm:^5.18.0": - version: 5.18.0 - resolution: "@mui/system@npm:5.18.0" +"@mui/system@npm:^7.3.2": + version: 7.3.2 + resolution: "@mui/system@npm:7.3.2" dependencies: - "@babel/runtime": ^7.23.9 - "@mui/private-theming": ^5.17.1 - "@mui/styled-engine": ^5.18.0 - "@mui/types": ~7.2.15 - "@mui/utils": ^5.17.1 - clsx: ^2.1.0 + "@babel/runtime": ^7.28.3 + "@mui/private-theming": ^7.3.2 + "@mui/styled-engine": ^7.3.2 + "@mui/types": ^7.4.6 + "@mui/utils": ^7.3.2 + clsx: ^2.1.1 csstype: ^3.1.3 prop-types: ^15.8.1 peerDependencies: @@ -12202,21 +11734,21 @@ __metadata: optional: true "@types/react": optional: true - checksum: 451f43889c2638da7c52b898e6174eafcdbcbcaaf3a79f954fdd58d9a043786d76fa4fca902cfdd6ab1aa250f5b1f932ef93d789c5a15987d893c0741bf7a1ad + checksum: 9a7b97e22991959dcdb60b4b0d60b359df4dce3735235db4fa51a214cf515f584ff84fd10f15849c91aeda7b8d39658eb9378253d3fac2a6db0b9baca693e3a7 languageName: node linkType: hard -"@mui/types@npm:^7.2.14-dev.20240529-082515-213b5e33ab, @mui/types@npm:^7.2.15, @mui/types@npm:^7.2.19": - version: 7.4.1 - resolution: "@mui/types@npm:7.4.1" +"@mui/types@npm:^7.2.14-dev.20240529-082515-213b5e33ab, @mui/types@npm:^7.2.19, @mui/types@npm:^7.4.6": + version: 7.4.6 + resolution: "@mui/types@npm:7.4.6" dependencies: - "@babel/runtime": ^7.27.0 + "@babel/runtime": ^7.28.3 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 97a43ab55e48de9a1c64cf03328ffdac4759d407171833d2c3e43c96b6c862bf2ec8832eea603c3e7de638692a953d3400d7df1d136b11acaaa1ef00885cca1d + checksum: 7e4b4ae06066468e8a8211376d0a08250325f4b92f6d2ea24576df37dfcd0f683602567debdf15889e0e4510eb48d677aa0d71a2ed9423c16dbd4b4ecfbccbb9 languageName: node linkType: hard @@ -12232,7 +11764,7 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.10.3, @mui/utils@npm:^5.14.15, @mui/utils@npm:^5.16.12, @mui/utils@npm:^5.16.14, @mui/utils@npm:^5.16.5, @mui/utils@npm:^5.17.1": +"@mui/utils@npm:^5.10.3, @mui/utils@npm:^5.14.15, @mui/utils@npm:^5.14.16, @mui/utils@npm:^5.16.5, @mui/utils@npm:^5.17.1": version: 5.17.1 resolution: "@mui/utils@npm:5.17.1" dependencies: @@ -12272,6 +11804,26 @@ __metadata: languageName: node linkType: hard +"@mui/utils@npm:^7.3.2": + version: 7.3.2 + resolution: "@mui/utils@npm:7.3.2" + dependencies: + "@babel/runtime": ^7.28.3 + "@mui/types": ^7.4.6 + "@types/prop-types": ^15.7.15 + clsx: ^2.1.1 + prop-types: ^15.8.1 + react-is: ^19.1.1 + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 201fb1f49434c3ee12de3a177660af04cb6411a68f8c13dc62ea828c522758b53040046daf2341b38da3b0a8a455ef4454a49cca4fa4e7b4d345d05e3ca61ecc + languageName: node + linkType: hard + "@mui/x-charts@npm:^6.0.0-alpha.7": version: 6.19.5 resolution: "@mui/x-charts@npm:6.19.5" @@ -12345,6 +11897,54 @@ __metadata: languageName: node linkType: hard +"@mui/x-date-pickers@npm:^6.19.0": + version: 6.20.2 + resolution: "@mui/x-date-pickers@npm:6.20.2" + dependencies: + "@babel/runtime": ^7.23.2 + "@mui/base": ^5.0.0-beta.22 + "@mui/utils": ^5.14.16 + "@types/react-transition-group": ^4.4.8 + clsx: ^2.0.0 + prop-types: ^15.8.1 + react-transition-group: ^4.4.5 + peerDependencies: + "@emotion/react": ^11.9.0 + "@emotion/styled": ^11.8.1 + "@mui/material": ^5.8.6 + "@mui/system": ^5.8.0 + date-fns: ^2.25.0 || ^3.2.0 + date-fns-jalali: ^2.13.0-0 + dayjs: ^1.10.7 + luxon: ^3.0.2 + moment: ^2.29.4 + moment-hijri: ^2.1.2 + moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + date-fns: + optional: true + date-fns-jalali: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + moment-hijri: + optional: true + moment-jalaali: + optional: true + checksum: 0447b911ea0d78d4ee2080827bc075d8c1ed4764bd289d6bf65ee2ff870ac8ef72daef8a1858ccf27aad6c296cfece5455f6834a2d18a2c8e719518cd5464a0b + languageName: node + linkType: hard + "@mui/x-date-pickers@npm:^7.6.1": version: 7.11.1 resolution: "@mui/x-date-pickers@npm:7.11.1" @@ -12393,6 +11993,17 @@ __metadata: languageName: node linkType: hard +"@napi-rs/wasm-runtime@npm:^1.0.1": + version: 1.0.3 + resolution: "@napi-rs/wasm-runtime@npm:1.0.3" + dependencies: + "@emnapi/core": ^1.4.5 + "@emnapi/runtime": ^1.4.5 + "@tybys/wasm-util": ^0.10.0 + checksum: e105c8f3bfc07ccbbccc17e6abb6d3f5a9cf685930842c4f5439c6d4a7ccab3d89da43fc8627f222a021beb7f78171f80ce3c488e3bd3a2156a049cd8224ebf0 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -12648,13 +12259,13 @@ __metadata: languageName: node linkType: hard -"@octokit/endpoint@npm:^9.0.1": - version: 9.0.5 - resolution: "@octokit/endpoint@npm:9.0.5" +"@octokit/endpoint@npm:^9.0.6": + version: 9.0.6 + resolution: "@octokit/endpoint@npm:9.0.6" dependencies: "@octokit/types": ^13.1.0 universal-user-agent: ^6.0.0 - checksum: d5cc2df9bd4603844c163eea05eec89c677cfe699c6f065fe86b83123e34554ec16d429e8142dec1e2b4cf56591ef0ce5b1763f250c87bc8e7bf6c74ba59ae82 + checksum: f853c08f0777a8cc7c3d2509835d478e11a76d722f807d4f2ad7c0e64bf4dd159536409f466b367a907886aa3b78574d3d09ed95ac462c769e4fccaaad81e72a languageName: node linkType: hard @@ -12921,14 +12532,14 @@ __metadata: languageName: node linkType: hard -"@octokit/request-error@npm:^5.0.0, @octokit/request-error@npm:^5.1.0": - version: 5.1.0 - resolution: "@octokit/request-error@npm:5.1.0" +"@octokit/request-error@npm:^5.0.0, @octokit/request-error@npm:^5.1.0, @octokit/request-error@npm:^5.1.1": + version: 5.1.1 + resolution: "@octokit/request-error@npm:5.1.1" dependencies: "@octokit/types": ^13.1.0 deprecation: ^2.0.0 once: ^1.4.0 - checksum: 2cdbb8e44072323b5e1c8c385727af6700e3e492d55bc1e8d0549c4a3d9026914f915866323d371b1f1772326d6e902341c872679cc05c417ffc15cadf5f4a4e + checksum: 17d0b3f59c2a8a285715bfe6a85168d9c417aa7a0ff553b9be4198a3bc8bb00384a3530221a448eb19f8f07ea9fc48d264869624f5f84fa63a948a7af8cddc8c languageName: node linkType: hard @@ -12946,15 +12557,15 @@ __metadata: languageName: node linkType: hard -"@octokit/request@npm:^8.3.0, @octokit/request@npm:^8.3.1": - version: 8.4.0 - resolution: "@octokit/request@npm:8.4.0" +"@octokit/request@npm:^8.0.0, @octokit/request@npm:^8.3.0, @octokit/request@npm:^8.3.1": + version: 8.4.1 + resolution: "@octokit/request@npm:8.4.1" dependencies: - "@octokit/endpoint": ^9.0.1 - "@octokit/request-error": ^5.1.0 + "@octokit/endpoint": ^9.0.6 + "@octokit/request-error": ^5.1.1 "@octokit/types": ^13.1.0 universal-user-agent: ^6.0.0 - checksum: 3d937e817a85c0adf447ab46b428ccd702c31b2091e47adec90583ec2242bd64666306fe8188628fb139aa4752e19400eb7652b0f5ca33cd9e77bbb2c60b202a + checksum: 0ba76728583543baeef9fda98690bc86c57e0a3ccac8c189d2b7d144d248c89167eb37a071ed8fead8f4da0a1c55c4dd98a8fc598769c263b95179fb200959de languageName: node linkType: hard @@ -13126,9 +12737,9 @@ __metadata: languageName: node linkType: hard -"@pagerduty/backstage-plugin-backend@npm:0.9.6": - version: 0.9.6 - resolution: "@pagerduty/backstage-plugin-backend@npm:0.9.6" +"@pagerduty/backstage-plugin-backend@npm:0.9.11": + version: 0.9.11 + resolution: "@pagerduty/backstage-plugin-backend@npm:0.9.11" dependencies: "@backstage/backend-common": ^0.23.3 "@backstage/backend-defaults": ^0.4.1 @@ -13142,7 +12753,7 @@ __metadata: "@backstage/plugin-catalog-node": ^1.12.4 "@backstage/plugin-scaffolder-node": ^0.4.8 "@material-ui/core": ^4.12.4 - "@pagerduty/backstage-plugin-common": ^0.2.1 + "@pagerduty/backstage-plugin-common": ~0.2.3 "@rjsf/core": ^5.14.3 "@types/express": ^4.17.6 express: ^4.20.0 @@ -13153,28 +12764,33 @@ __metadata: uuid: ^9.0.1 winston: ^3.2.1 yn: ^4.0.0 - checksum: 46c79691583ac4f3e1befd199dc181b9b9d9e722f543afd168d51b79e84a81934a2e67fbe58f411af466fb1722383b1989a4bfb1db8a180a3d63afa8a4401b95 + checksum: dc43c0379cb3585a5888c48ca3a711b424519f39a5e8ef46468db46e3daebd9817c37a89ef8e6497d00062b97a13dd65e0f818ec52584e412a941f62189b4971 languageName: node linkType: hard -"@pagerduty/backstage-plugin-common@npm:^0.2.1": - version: 0.2.2 - resolution: "@pagerduty/backstage-plugin-common@npm:0.2.2" - checksum: 79f012e04758a3cc0d6ce94f41182f3c96d7984b622e0bcbb32a5989d3bcdec68ccaf90c19d635027f9c5df3fd774e890b6bf9b8f3e3394e761bebc072ac5137 +"@pagerduty/backstage-plugin-common@npm:~0.2.3": + version: 0.2.3 + resolution: "@pagerduty/backstage-plugin-common@npm:0.2.3" + checksum: ee35802fd36850abd6856161737cc7631f211c24d268ed50f058cd2b77621c39bf3fed8f52bd8672069b9bec2337e9a0daf893d73843c91de891dea48c3a0fdb languageName: node linkType: hard -"@pagerduty/backstage-plugin@npm:0.15.5": - version: 0.15.5 - resolution: "@pagerduty/backstage-plugin@npm:0.15.5" +"@pagerduty/backstage-plugin@npm:0.16.0": + version: 0.16.0 + resolution: "@pagerduty/backstage-plugin@npm:0.16.0" dependencies: - "@backstage/catalog-model": ^1.5.0 - "@backstage/core-components": ^0.14.9 - "@backstage/core-plugin-api": ^1.9.3 - "@backstage/errors": ^1.2.4 - "@backstage/plugin-catalog-react": ^1.12.2 - "@backstage/plugin-home-react": ^0.1.15 + "@backstage/catalog-client": ^1.12.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-compat-api": ^0.5.2 + "@backstage/core-components": ^0.18.0 + "@backstage/core-plugin-api": ^1.11.0 + "@backstage/errors": ^1.2.7 + "@backstage/frontend-plugin-api": ^0.12.0 + "@backstage/plugin-catalog": ^1.31.3 + "@backstage/plugin-catalog-react": ^1.21.0 + "@backstage/plugin-home-react": ^0.1.30 "@backstage/theme": ^0.5.6 + "@backstage/ui": ^0.6.1 "@emotion/react": ^11.11.4 "@emotion/styled": ^11.11.5 "@material-ui/core": ^4.12.2 @@ -13183,7 +12799,7 @@ __metadata: "@mui/icons-material": ^5.15.19 "@mui/material": ^5.15.19 "@mui/x-date-pickers": ^7.6.1 - "@pagerduty/backstage-plugin-common": ^0.2.1 + "@pagerduty/backstage-plugin-common": ~0.2.3 "@tanstack/react-query": ^5.40.1 classnames: ^2.2.6 luxon: ^3.4.1 @@ -13195,7 +12811,7 @@ __metadata: react: ^18.0.0 || ^20.0.0 react-dom: ^18.0.0 || ^20.0.0 react-router-dom: ^6.3.0 - checksum: a162f21db1a49051491ac7114b6a8c46bf2e0aae6a21be4556ddb36aac05a2a1c4c1a33e0e45ec93350eed50ca19f0fd5851c3b57f3fe9fdcc3e2f82f168772a + checksum: 974cd2c2533719e7d9a0fd9a28acd9f7175434acc11688231e0f618bd32882905048e2d5c65e254c06244981a55c5c0d0a4df316a69dece4a16993f51d69367d languageName: node linkType: hard @@ -13225,39 +12841,6 @@ __metadata: languageName: node linkType: hard -"@patternfly/react-charts@npm:^7.1.1": - version: 7.3.0 - resolution: "@patternfly/react-charts@npm:7.3.0" - dependencies: - "@patternfly/react-styles": ^5.3.0 - "@patternfly/react-tokens": ^5.3.0 - hoist-non-react-statics: ^3.3.0 - lodash: ^4.17.21 - tslib: ^2.5.0 - victory-area: ^36.9.1 - victory-axis: ^36.9.1 - victory-bar: ^36.9.1 - victory-box-plot: ^36.9.1 - victory-chart: ^36.9.1 - victory-core: ^36.9.1 - victory-create-container: ^36.9.1 - victory-cursor-container: ^36.9.1 - victory-group: ^36.9.1 - victory-legend: ^36.9.1 - victory-line: ^36.9.1 - victory-pie: ^36.9.1 - victory-scatter: ^36.9.1 - victory-stack: ^36.9.1 - victory-tooltip: ^36.9.1 - victory-voronoi-container: ^36.9.1 - victory-zoom-container: ^36.9.1 - peerDependencies: - react: ^17 || ^18 - react-dom: ^17 || ^18 - checksum: 131fb6e81f7be8b237cfc28f13da9eb124c9ffac65990f5546a7470add7d66c0f81767f5fb9926eb90957210117558770e664db7e883742bc3a1ace09dfeca0e - languageName: node - linkType: hard - "@patternfly/react-charts@npm:^8.1.0": version: 8.1.0 resolution: "@patternfly/react-charts@npm:8.1.0" @@ -13353,13 +12936,6 @@ __metadata: languageName: node linkType: hard -"@patternfly/react-styles@npm:^5.3.0": - version: 5.4.1 - resolution: "@patternfly/react-styles@npm:5.4.1" - checksum: 6fb1ec38a017acd1cf1262b39c69f70a650ed7f205d5433c83087957395e6e487914ed1992a67de37718ea536145fc974d7d9dbc6460ae38d668035f4c6d0c1b - languageName: node - linkType: hard - "@patternfly/react-styles@npm:^6.0.0, @patternfly/react-styles@npm:^6.1.0": version: 6.1.0 resolution: "@patternfly/react-styles@npm:6.1.0" @@ -13384,13 +12960,6 @@ __metadata: languageName: node linkType: hard -"@patternfly/react-tokens@npm:^5.3.0": - version: 5.4.1 - resolution: "@patternfly/react-tokens@npm:5.4.1" - checksum: d6f51cbd31db797ed42b148f58ecb28bcc93bdcdf39d0f20b8db5ac40ac2998002ddfad764af38c2f00bc366ac57b1c12fdd42a55e7a30fe3b01e26739e770cf - languageName: node - linkType: hard - "@patternfly/react-tokens@npm:^6.0.0, @patternfly/react-tokens@npm:^6.1.0": version: 6.1.0 resolution: "@patternfly/react-tokens@npm:6.1.0" @@ -13550,6 +13119,931 @@ __metadata: languageName: node linkType: hard +"@react-aria/autocomplete@npm:3.0.0-rc.3": + version: 3.0.0-rc.3 + resolution: "@react-aria/autocomplete@npm:3.0.0-rc.3" + dependencies: + "@react-aria/combobox": ^3.14.0 + "@react-aria/focus": ^3.21.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/listbox": ^3.15.0 + "@react-aria/searchfield": ^3.8.9 + "@react-aria/textfield": ^3.18.2 + "@react-aria/utils": ^3.31.0 + "@react-stately/autocomplete": 3.0.0-beta.3 + "@react-stately/combobox": ^3.12.0 + "@react-types/autocomplete": 3.0.0-alpha.35 + "@react-types/button": ^3.14.1 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: a64227a01ee870e8f945d573e2d03fb3562219406031f59df3df0d6815703d28e47791bb80c2d56b06ba2a6fabf60f729c8a5ed691a5025dee4cc5ef06dc10c0 + languageName: node + linkType: hard + +"@react-aria/breadcrumbs@npm:^3.5.29": + version: 3.5.29 + resolution: "@react-aria/breadcrumbs@npm:3.5.29" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/link": ^3.8.6 + "@react-aria/utils": ^3.31.0 + "@react-types/breadcrumbs": ^3.7.17 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 90a4e6c0ded9d95044d678035cd085f011a7b16e0d21af28e809fe20d2137dbced9aa19e686fb5566576468f2fe3defca8adf21450316b5d44c1b28c8facba22 + languageName: node + linkType: hard + +"@react-aria/button@npm:^3.14.2": + version: 3.14.2 + resolution: "@react-aria/button@npm:3.14.2" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/toolbar": 3.0.0-beta.21 + "@react-aria/utils": ^3.31.0 + "@react-stately/toggle": ^3.9.2 + "@react-types/button": ^3.14.1 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: f858d7af4db8ec470fae0c1d26e81157fbb5db959a41383f622fd28d83b6da85315548c551d585929a9d7e6f80a12cf81f95324ece03617c9bdb8b601ec48a76 + languageName: node + linkType: hard + +"@react-aria/calendar@npm:^3.9.2": + version: 3.9.2 + resolution: "@react-aria/calendar@npm:3.9.2" + dependencies: + "@internationalized/date": ^3.10.0 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/live-announcer": ^3.4.4 + "@react-aria/utils": ^3.31.0 + "@react-stately/calendar": ^3.9.0 + "@react-types/button": ^3.14.1 + "@react-types/calendar": ^3.8.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 632f6ed1af806f400897b62d6dec79ca2501c9c9690bed8764a6b6d83eba16edb0a070345fee53e65be3ac4ac1442f18c76ef0459b530a5642f2881f4423cb1f + languageName: node + linkType: hard + +"@react-aria/checkbox@npm:^3.16.2": + version: 3.16.2 + resolution: "@react-aria/checkbox@npm:3.16.2" + dependencies: + "@react-aria/form": ^3.1.2 + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/toggle": ^3.12.2 + "@react-aria/utils": ^3.31.0 + "@react-stately/checkbox": ^3.7.2 + "@react-stately/form": ^3.2.2 + "@react-stately/toggle": ^3.9.2 + "@react-types/checkbox": ^3.10.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: e8abf192f946b200d6bd3763a23db1a46bea4ab8ff3719d3f7523a5e53611eff284b4348a9a2ab8befc31df6fead79f0f1ceb664847db0559aac97269fe7c723 + languageName: node + linkType: hard + +"@react-aria/collections@npm:^3.0.0": + version: 3.0.0 + resolution: "@react-aria/collections@npm:3.0.0" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/ssr": ^3.9.10 + "@react-aria/utils": ^3.31.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + use-sync-external-store: ^1.4.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: cc19d2c634ef55a1ebe507f9018707b91f8787d4f56988b91cd68f6df45fd32ea8ed594333052f9519040de7c5fe50ba2f36303d3daa7c7b543d025b02b173ca + languageName: node + linkType: hard + +"@react-aria/color@npm:^3.1.2": + version: 3.1.2 + resolution: "@react-aria/color@npm:3.1.2" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/numberfield": ^3.12.2 + "@react-aria/slider": ^3.8.2 + "@react-aria/spinbutton": ^3.6.19 + "@react-aria/textfield": ^3.18.2 + "@react-aria/utils": ^3.31.0 + "@react-aria/visually-hidden": ^3.8.28 + "@react-stately/color": ^3.9.2 + "@react-stately/form": ^3.2.2 + "@react-types/color": ^3.1.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 89ff6e81b30590c6af970982f0fbe55020bc79c2b97b94a6a777a12d78b637d3d3dd56337e237996fd8362bf4ee739bb44bbef17fc3db9ce8a370fff22aa1e2c + languageName: node + linkType: hard + +"@react-aria/combobox@npm:^3.14.0": + version: 3.14.0 + resolution: "@react-aria/combobox@npm:3.14.0" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/listbox": ^3.15.0 + "@react-aria/live-announcer": ^3.4.4 + "@react-aria/menu": ^3.19.3 + "@react-aria/overlays": ^3.30.0 + "@react-aria/selection": ^3.26.0 + "@react-aria/textfield": ^3.18.2 + "@react-aria/utils": ^3.31.0 + "@react-stately/collections": ^3.12.8 + "@react-stately/combobox": ^3.12.0 + "@react-stately/form": ^3.2.2 + "@react-types/button": ^3.14.1 + "@react-types/combobox": ^3.13.9 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 22a908831f28ca6f22ce2945f8c873a0b592f24005901a0389b3e0e772eb9e64f1dc75ca66bc0a54a6c913a457f396d7ee39476c8be1a6b6313b05b545d38e20 + languageName: node + linkType: hard + +"@react-aria/datepicker@npm:^3.15.2": + version: 3.15.2 + resolution: "@react-aria/datepicker@npm:3.15.2" + dependencies: + "@internationalized/date": ^3.10.0 + "@internationalized/number": ^3.6.5 + "@internationalized/string": ^3.2.7 + "@react-aria/focus": ^3.21.2 + "@react-aria/form": ^3.1.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/spinbutton": ^3.6.19 + "@react-aria/utils": ^3.31.0 + "@react-stately/datepicker": ^3.15.2 + "@react-stately/form": ^3.2.2 + "@react-types/button": ^3.14.1 + "@react-types/calendar": ^3.8.0 + "@react-types/datepicker": ^3.13.2 + "@react-types/dialog": ^3.5.22 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 35866acd23ceea0117112b3729ccdf19535a355f9957cb0b488709b98d3b7f10e2e92e26a630a07a77e3a1f29efb3ec9207d7125c6e4e4d446700643ab46defa + languageName: node + linkType: hard + +"@react-aria/dialog@npm:^3.5.31": + version: 3.5.31 + resolution: "@react-aria/dialog@npm:3.5.31" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/overlays": ^3.30.0 + "@react-aria/utils": ^3.31.0 + "@react-types/dialog": ^3.5.22 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 57981d20145855669889eec7d4221a6073cf00aa54c8eaa101ad6a2f31a5a23f4a410acfed66273bc77fcccbc1bf7a96ca85dc87d79078ff35492dd80d68eb60 + languageName: node + linkType: hard + +"@react-aria/disclosure@npm:^3.1.0": + version: 3.1.0 + resolution: "@react-aria/disclosure@npm:3.1.0" + dependencies: + "@react-aria/ssr": ^3.9.10 + "@react-aria/utils": ^3.31.0 + "@react-stately/disclosure": ^3.0.8 + "@react-types/button": ^3.14.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 4def8a67b0e12b4582ea53205f3b77b509bfd6655f8216ca26b4cca3c7a4144c796664101c31140610a8ae3aed76215c8175a024e89237817d7ce568682ed745 + languageName: node + linkType: hard + +"@react-aria/dnd@npm:^3.11.3": + version: 3.11.3 + resolution: "@react-aria/dnd@npm:3.11.3" + dependencies: + "@internationalized/string": ^3.2.7 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/live-announcer": ^3.4.4 + "@react-aria/overlays": ^3.30.0 + "@react-aria/utils": ^3.31.0 + "@react-stately/collections": ^3.12.8 + "@react-stately/dnd": ^3.7.1 + "@react-types/button": ^3.14.1 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 30f9c0e0db333859ec1ae764ff8f954008d669bf6b7beb84794d584252817e43a758872ac2d39cad19b2d9c0adb5acb5182ff154a2174546733efac0055d2cf2 + languageName: node + linkType: hard + +"@react-aria/focus@npm:^3.21.2": + version: 3.21.2 + resolution: "@react-aria/focus@npm:3.21.2" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/utils": ^3.31.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + clsx: ^2.0.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: c6a773f2add800cafabae654dcb4aee51a7d205911de0fc7b0c9417cab5644ca7c8358749d92abe0295be2aa199f864b06071547def4c975e79fbc0dc1aec9da + languageName: node + linkType: hard + +"@react-aria/form@npm:^3.1.2": + version: 3.1.2 + resolution: "@react-aria/form@npm:3.1.2" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/utils": ^3.31.0 + "@react-stately/form": ^3.2.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 6b3dea13de4b813b41367f5983d1b54ce4a5c0a621303bdcb30677025253f377ee298c576ffb1e43d5183e5bb2f3507d7d4b2ada0c22e09c91453224bb01777c + languageName: node + linkType: hard + +"@react-aria/grid@npm:^3.14.5": + version: 3.14.5 + resolution: "@react-aria/grid@npm:3.14.5" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/live-announcer": ^3.4.4 + "@react-aria/selection": ^3.26.0 + "@react-aria/utils": ^3.31.0 + "@react-stately/collections": ^3.12.8 + "@react-stately/grid": ^3.11.6 + "@react-stately/selection": ^3.20.6 + "@react-types/checkbox": ^3.10.2 + "@react-types/grid": ^3.3.6 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 4c654ed46f0d458112cfd6a4f9dc91369a1dbb3740de024805fda335599ef8ec56b1cb16855e652751f1ba9f7a44cb790d0cbcd07dceeb7e2989f945824bf970 + languageName: node + linkType: hard + +"@react-aria/gridlist@npm:^3.14.1": + version: 3.14.1 + resolution: "@react-aria/gridlist@npm:3.14.1" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/grid": ^3.14.5 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/selection": ^3.26.0 + "@react-aria/utils": ^3.31.0 + "@react-stately/list": ^3.13.1 + "@react-stately/tree": ^3.9.3 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 9723c1fa7b546bafdd33ccee9e777ab8157afff3d28e02914d0969a15ebff0ccb3cbcde4c42118c6cc93ebf573258371ad8a25ad98ee7f97f0feae01649295b8 + languageName: node + linkType: hard + +"@react-aria/i18n@npm:^3.12.13": + version: 3.12.13 + resolution: "@react-aria/i18n@npm:3.12.13" + dependencies: + "@internationalized/date": ^3.10.0 + "@internationalized/message": ^3.1.8 + "@internationalized/number": ^3.6.5 + "@internationalized/string": ^3.2.7 + "@react-aria/ssr": ^3.9.10 + "@react-aria/utils": ^3.31.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 4b0d8dd0f62702bc1e55793ef60825c6c1ad8d7fe33d6bd979ad50b47441ba98b2599565df997b5665092c3858d3e40a72e4dc74fb087a49b70593e72a7bf9e4 + languageName: node + linkType: hard + +"@react-aria/interactions@npm:^3.25.6": + version: 3.25.6 + resolution: "@react-aria/interactions@npm:3.25.6" + dependencies: + "@react-aria/ssr": ^3.9.10 + "@react-aria/utils": ^3.31.0 + "@react-stately/flags": ^3.1.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: e3965a550b6e2caf7b4e0c7375fe93ca75ffd836e1c69130cdc234376f40ed91da963381e5a28b815f1d1be5901edb63e6eb80c31c8af8a0b3239b243c65a9bf + languageName: node + linkType: hard + +"@react-aria/label@npm:^3.7.22": + version: 3.7.22 + resolution: "@react-aria/label@npm:3.7.22" + dependencies: + "@react-aria/utils": ^3.31.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: f29d28a3340297792bb928997c02f6b5c698c04ce90d7aa18f2d8d3c5c464d3c05e2aeeb6272dbcadd2ab42727bd66dfa3da1e29819c54512842ed75f6f1d888 + languageName: node + linkType: hard + +"@react-aria/landmark@npm:^3.0.7": + version: 3.0.7 + resolution: "@react-aria/landmark@npm:3.0.7" + dependencies: + "@react-aria/utils": ^3.31.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + use-sync-external-store: ^1.4.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: ee4fbde3d623374aa4be708ea8cb9d4d488a5fccda064fb0a92434596eb6a8433cc7e740adc118e9f67763716e3de9ce69974d9fd803fd9a982191b65a3e26e6 + languageName: node + linkType: hard + +"@react-aria/link@npm:^3.8.6": + version: 3.8.6 + resolution: "@react-aria/link@npm:3.8.6" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/utils": ^3.31.0 + "@react-types/link": ^3.6.5 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: cc844b836dfa9d02ebdcd6173a4d4685028232fb09199bdbd96c7f8f953c7652987c6fb094abbead244c17db4b567306fa1beeaf7b070c6350eb8fef6534d134 + languageName: node + linkType: hard + +"@react-aria/listbox@npm:^3.15.0": + version: 3.15.0 + resolution: "@react-aria/listbox@npm:3.15.0" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/selection": ^3.26.0 + "@react-aria/utils": ^3.31.0 + "@react-stately/collections": ^3.12.8 + "@react-stately/list": ^3.13.1 + "@react-types/listbox": ^3.7.4 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 4a3a1a43cce3d7a7fe512292d458d3d3ba259a3a7a9489fb51e877b9cec24d1078572defe7d41a89e8f6ba0d62422b8da51add76bdc726a3fc5351b5551dacc3 + languageName: node + linkType: hard + +"@react-aria/live-announcer@npm:^3.4.4": + version: 3.4.4 + resolution: "@react-aria/live-announcer@npm:3.4.4" + dependencies: + "@swc/helpers": ^0.5.0 + checksum: 5f773b7ed2725d1ba174b3a1ed234bcfcf0669f15b74cb9d0b2105df1d2945407bcd21a514c7647ca7f8aa6e352ad7733c48e2d7370c3ce556a91a9d8a8407aa + languageName: node + linkType: hard + +"@react-aria/menu@npm:^3.19.3": + version: 3.19.3 + resolution: "@react-aria/menu@npm:3.19.3" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/overlays": ^3.30.0 + "@react-aria/selection": ^3.26.0 + "@react-aria/utils": ^3.31.0 + "@react-stately/collections": ^3.12.8 + "@react-stately/menu": ^3.9.8 + "@react-stately/selection": ^3.20.6 + "@react-stately/tree": ^3.9.3 + "@react-types/button": ^3.14.1 + "@react-types/menu": ^3.10.5 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 6cc48fee752d4d31204ac81e53c8c9d612a9d6557d69c1ecd12663560dfb8cda8309d20fe5895388276c2c12ad1f0c969691856b8958caa3f68dceef8d6a54a5 + languageName: node + linkType: hard + +"@react-aria/meter@npm:^3.4.27": + version: 3.4.27 + resolution: "@react-aria/meter@npm:3.4.27" + dependencies: + "@react-aria/progress": ^3.4.27 + "@react-types/meter": ^3.4.13 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 1d63ae8c6c15ca40b88f524de22934627fcf4db2ead3cb5851bea4e3c29be4e094d013ee9942946bab6d8abcbe3dbe0328732236b7fdbfb1b406b626e5075610 + languageName: node + linkType: hard + +"@react-aria/numberfield@npm:^3.12.2": + version: 3.12.2 + resolution: "@react-aria/numberfield@npm:3.12.2" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/spinbutton": ^3.6.19 + "@react-aria/textfield": ^3.18.2 + "@react-aria/utils": ^3.31.0 + "@react-stately/form": ^3.2.2 + "@react-stately/numberfield": ^3.10.2 + "@react-types/button": ^3.14.1 + "@react-types/numberfield": ^3.8.15 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: e79cd8ad0f21a90d8e8c7d14c86b7b6f999740a02ae34c93a07de5869739e35517bc7cb0afac4e816edc4496596e2a747f2940dc50380fff2cd2deda6f02f4a9 + languageName: node + linkType: hard + +"@react-aria/overlays@npm:^3.26.1, @react-aria/overlays@npm:^3.30.0": + version: 3.30.0 + resolution: "@react-aria/overlays@npm:3.30.0" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/ssr": ^3.9.10 + "@react-aria/utils": ^3.31.0 + "@react-aria/visually-hidden": ^3.8.28 + "@react-stately/overlays": ^3.6.20 + "@react-types/button": ^3.14.1 + "@react-types/overlays": ^3.9.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 93d5eae156ba0b52ca4ff52283290fb4e9f56ca7f4afe9914e0bd1471a13aa3ebce3d74c8a357c04c72119100e3045ae9bfbb09ac9a7452901c055d66610028f + languageName: node + linkType: hard + +"@react-aria/progress@npm:^3.4.27": + version: 3.4.27 + resolution: "@react-aria/progress@npm:3.4.27" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/label": ^3.7.22 + "@react-aria/utils": ^3.31.0 + "@react-types/progress": ^3.5.16 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 37e3ef40fe8f6c31b856b725cce2329602c643db6aafa9c58a5f8816e5c0b2e22bc07f6574629d2a9260b67d8df039734eee307e29cea9984f4713d090c06e8f + languageName: node + linkType: hard + +"@react-aria/radio@npm:^3.12.2": + version: 3.12.2 + resolution: "@react-aria/radio@npm:3.12.2" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/form": ^3.1.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/utils": ^3.31.0 + "@react-stately/radio": ^3.11.2 + "@react-types/radio": ^3.9.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: e9a472993f8395a43fccda8129f2462816b95f72f4309a6124bb2b8c5766b0e8c98e2d3c0f2aa0757a6c3223ffea3ac9399144b2d85087e854eab9c6548e8210 + languageName: node + linkType: hard + +"@react-aria/searchfield@npm:^3.8.9": + version: 3.8.9 + resolution: "@react-aria/searchfield@npm:3.8.9" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/textfield": ^3.18.2 + "@react-aria/utils": ^3.31.0 + "@react-stately/searchfield": ^3.5.16 + "@react-types/button": ^3.14.1 + "@react-types/searchfield": ^3.6.6 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: c45a96ee8a5d28621e4b8e6b4110ea3e083465f6be15fdcca6a6c09537597651619ce40dfe32d7996a89ae526ccef6765da4dfd8c97e18daad3fe2f5df214bed + languageName: node + linkType: hard + +"@react-aria/select@npm:^3.17.0": + version: 3.17.0 + resolution: "@react-aria/select@npm:3.17.0" + dependencies: + "@react-aria/form": ^3.1.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/listbox": ^3.15.0 + "@react-aria/menu": ^3.19.3 + "@react-aria/selection": ^3.26.0 + "@react-aria/utils": ^3.31.0 + "@react-aria/visually-hidden": ^3.8.28 + "@react-stately/select": ^3.8.0 + "@react-types/button": ^3.14.1 + "@react-types/select": ^3.11.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: ce95a57e6127345a9b3b03c3d7df00066a6b0b7493e3c771f9aff3323745ef2cba3b624dd7eba6c1fde77b0195d77174abd456c61ff4a4248f73b8417469bc49 + languageName: node + linkType: hard + +"@react-aria/selection@npm:^3.26.0": + version: 3.26.0 + resolution: "@react-aria/selection@npm:3.26.0" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/utils": ^3.31.0 + "@react-stately/selection": ^3.20.6 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: ac4f276dd395aabff100841e1e6a0c3ce51f9d4ccc72142e0245d4ab19a071f72283baa26ff3f63fcc6a180ddfc39d41133b2a940670d5751e1f0d823f1964ef + languageName: node + linkType: hard + +"@react-aria/separator@npm:^3.4.13": + version: 3.4.13 + resolution: "@react-aria/separator@npm:3.4.13" + dependencies: + "@react-aria/utils": ^3.31.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: d83d4ab1c3ba8946f635adc24005f1408f3336c74120375ebd015fb923f27effd77255f1666a3abcc3502d447ed3c2a71658c3bba3907c5a535476e069be1658 + languageName: node + linkType: hard + +"@react-aria/slider@npm:^3.8.2": + version: 3.8.2 + resolution: "@react-aria/slider@npm:3.8.2" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/utils": ^3.31.0 + "@react-stately/slider": ^3.7.2 + "@react-types/shared": ^3.32.1 + "@react-types/slider": ^3.8.2 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 10ab4c8d6cb5a0c8a8c4a4e6fac2bd8178ba7f6768848441e52cd47d1ae08afeac15478cb42e920bf238972f9d99a09bc2aa1e3b2701bd75750fc7d6bfbff375 + languageName: node + linkType: hard + +"@react-aria/spinbutton@npm:^3.6.19": + version: 3.6.19 + resolution: "@react-aria/spinbutton@npm:3.6.19" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/live-announcer": ^3.4.4 + "@react-aria/utils": ^3.31.0 + "@react-types/button": ^3.14.1 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 09f859f56a2d65d3a5faec0be3b864cb5d3962ab522bd62c29c0fba010b94cb0f14b00e3766320663a6f0c0b4b5dd138b27dc5b3dcc757fe1068382be28d26af + languageName: node + linkType: hard + +"@react-aria/ssr@npm:^3.9.10": + version: 3.9.10 + resolution: "@react-aria/ssr@npm:3.9.10" + dependencies: + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 45307c53beee3a48f79f361ba07d4306250a051a0da5c258a545b47495983743975ad193e05542d28d15087e597049c74c850fe4fd920157a7d190d47f19dd52 + languageName: node + linkType: hard + +"@react-aria/switch@npm:^3.7.8": + version: 3.7.8 + resolution: "@react-aria/switch@npm:3.7.8" + dependencies: + "@react-aria/toggle": ^3.12.2 + "@react-stately/toggle": ^3.9.2 + "@react-types/shared": ^3.32.1 + "@react-types/switch": ^3.5.15 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 8bca9752b28651947567d77a45b0042d92dba7be8adb3a413d3d3f87b4f48b479398c3883b560a48fbb58ba60a1228d98c7c039f59c3d382c3e256b8a57a5bd2 + languageName: node + linkType: hard + +"@react-aria/table@npm:^3.17.8": + version: 3.17.8 + resolution: "@react-aria/table@npm:3.17.8" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/grid": ^3.14.5 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/live-announcer": ^3.4.4 + "@react-aria/utils": ^3.31.0 + "@react-aria/visually-hidden": ^3.8.28 + "@react-stately/collections": ^3.12.8 + "@react-stately/flags": ^3.1.2 + "@react-stately/table": ^3.15.1 + "@react-types/checkbox": ^3.10.2 + "@react-types/grid": ^3.3.6 + "@react-types/shared": ^3.32.1 + "@react-types/table": ^3.13.4 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: af715ebd0664ad1d8db1d2bd8925f40000fe996e9ac0485395ec53dce9370f5b8d82eba2450fa5d7be603b1e2aec7d904babd38ac5d9fc904f3a05d4e1159843 + languageName: node + linkType: hard + +"@react-aria/tabs@npm:^3.10.8": + version: 3.10.8 + resolution: "@react-aria/tabs@npm:3.10.8" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/selection": ^3.26.0 + "@react-aria/utils": ^3.31.0 + "@react-stately/tabs": ^3.8.6 + "@react-types/shared": ^3.32.1 + "@react-types/tabs": ^3.3.19 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 444802045637caaf9384e7c3ee66f1f69c596761dcc6516308b67d26c412cee053b8f141674d269842b6050f1329c815d209a4cac50a7ca22a4b02b102246d7b + languageName: node + linkType: hard + +"@react-aria/tag@npm:^3.7.2": + version: 3.7.2 + resolution: "@react-aria/tag@npm:3.7.2" + dependencies: + "@react-aria/gridlist": ^3.14.1 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/selection": ^3.26.0 + "@react-aria/utils": ^3.31.0 + "@react-stately/list": ^3.13.1 + "@react-types/button": ^3.14.1 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: efe63c2593af0c29d211bdaf1c3c5e4e0f4f977390c4df35f6c06e29a75b02af0fb9802bd25ec44f926948564b21c4e827647d87e6780ffd5e07365142e5f76a + languageName: node + linkType: hard + +"@react-aria/textfield@npm:^3.18.2": + version: 3.18.2 + resolution: "@react-aria/textfield@npm:3.18.2" + dependencies: + "@react-aria/form": ^3.1.2 + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/utils": ^3.31.0 + "@react-stately/form": ^3.2.2 + "@react-stately/utils": ^3.10.8 + "@react-types/shared": ^3.32.1 + "@react-types/textfield": ^3.12.6 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 366ed221df1ddbed9b331ff7d6a4b1abe7f62b3cb9aafd09d7df5c14725237e5d27e63aa4e1859bf79bfd555818315f62f33e2427f9c1921cfc39c684426393f + languageName: node + linkType: hard + +"@react-aria/toast@npm:^3.0.8": + version: 3.0.8 + resolution: "@react-aria/toast@npm:3.0.8" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/landmark": ^3.0.7 + "@react-aria/utils": ^3.31.0 + "@react-stately/toast": ^3.1.2 + "@react-types/button": ^3.14.1 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: b70015b61fbfebe514ba79d939015f1340f45bf7095b23b46d29f11e8ae2e1b114630431960f566c6f5305a3ebd12ed8c154011c2e5fecfbe7c9fbd68ca261f7 + languageName: node + linkType: hard + +"@react-aria/toggle@npm:^3.12.2": + version: 3.12.2 + resolution: "@react-aria/toggle@npm:3.12.2" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/utils": ^3.31.0 + "@react-stately/toggle": ^3.9.2 + "@react-types/checkbox": ^3.10.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 337fe8a49907338baca296c2489c36a0e3a3576d999d1dc59f5daf8b35bda67095c4860f64395b39a620c5cf85d93fca5fa20cd426fea2cb4f67124cb352fe0a + languageName: node + linkType: hard + +"@react-aria/toolbar@npm:3.0.0-beta.21": + version: 3.0.0-beta.21 + resolution: "@react-aria/toolbar@npm:3.0.0-beta.21" + dependencies: + "@react-aria/focus": ^3.21.2 + "@react-aria/i18n": ^3.12.13 + "@react-aria/utils": ^3.31.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 8600f0a6f88e583fad64f93deb7362644e49c15201a5223941b885511e4bf6c9b9e0ecce2c5b6c3f47fe35c13e681eb112d12e5f920b76b9a1985ccfd6914b10 + languageName: node + linkType: hard + +"@react-aria/tooltip@npm:^3.8.8": + version: 3.8.8 + resolution: "@react-aria/tooltip@npm:3.8.8" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/utils": ^3.31.0 + "@react-stately/tooltip": ^3.5.8 + "@react-types/shared": ^3.32.1 + "@react-types/tooltip": ^3.4.21 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 25c2ee58707041cb6b9feefe0f96ce581bddd0a3a952b6b1964299727dac2731abc5087fcae35712839610b3eb65bdbd8e53393dbd4d7b36e097495465d1df3a + languageName: node + linkType: hard + +"@react-aria/tree@npm:^3.1.4": + version: 3.1.4 + resolution: "@react-aria/tree@npm:3.1.4" + dependencies: + "@react-aria/gridlist": ^3.14.1 + "@react-aria/i18n": ^3.12.13 + "@react-aria/selection": ^3.26.0 + "@react-aria/utils": ^3.31.0 + "@react-stately/tree": ^3.9.3 + "@react-types/button": ^3.14.1 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 3562c56b7409b0be95aac40e495ad9c15c0bb6ec6b76cf1ea3b25e9930637673f42938aa66f2771ba852aa99698703b7557bc186e6a99a944090499d76086c47 + languageName: node + linkType: hard + +"@react-aria/utils@npm:^3.31.0": + version: 3.31.0 + resolution: "@react-aria/utils@npm:3.31.0" + dependencies: + "@react-aria/ssr": ^3.9.10 + "@react-stately/flags": ^3.1.2 + "@react-stately/utils": ^3.10.8 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + clsx: ^2.0.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 21cdda60eb60509f943302972cd573a88c2ac968447b2bf6508aa392abca1ad5a21e2c826e1d68b3c991e328b8456d6d8d87a75f6c22a539e47c1441ba0e4bbe + languageName: node + linkType: hard + +"@react-aria/virtualizer@npm:^4.1.10": + version: 4.1.10 + resolution: "@react-aria/virtualizer@npm:4.1.10" + dependencies: + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/utils": ^3.31.0 + "@react-stately/virtualizer": ^4.4.4 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 796d49c56e6dd32560889f545de061f50babcb8371d832a75f753b63d0d902cfed5716b0dbd7f9b02e46dbdeb848687d1062601c4257e5a98f9f9f9af14aceda + languageName: node + linkType: hard + +"@react-aria/visually-hidden@npm:^3.8.28": + version: 3.8.28 + resolution: "@react-aria/visually-hidden@npm:3.8.28" + dependencies: + "@react-aria/interactions": ^3.25.6 + "@react-aria/utils": ^3.31.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 053d1950a8eb75bc3fb1a4b3e11c3db8ecdb23888d1053dafe6fbacc390200cec47a966522786c24889eae9aa273f8ff6ecf317e7a67b13fb494384069fb75dd + languageName: node + linkType: hard + "@react-dnd/asap@npm:^5.0.1": version: 5.0.2 resolution: "@react-dnd/asap@npm:5.0.2" @@ -13659,17 +14153,778 @@ __metadata: languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-adoption-insights-backend@npm:0.2.2": - version: 0.2.2 - resolution: "@red-hat-developer-hub/backstage-plugin-adoption-insights-backend@npm:0.2.2" +"@react-stately/autocomplete@npm:3.0.0-beta.3": + version: 3.0.0-beta.3 + resolution: "@react-stately/autocomplete@npm:3.0.0-beta.3" + dependencies: + "@react-stately/utils": ^3.10.8 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 080b7f4ca5c400618dcda49f9b164bb04cc5b17067622119d40bdd87f0c1a62b500eab93fb5681b3782fcaecea68ee8f504a8b472f4d2bd8a4033b1468b48d75 + languageName: node + linkType: hard + +"@react-stately/calendar@npm:^3.9.0": + version: 3.9.0 + resolution: "@react-stately/calendar@npm:3.9.0" + dependencies: + "@internationalized/date": ^3.10.0 + "@react-stately/utils": ^3.10.8 + "@react-types/calendar": ^3.8.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: a8f43d921b196d79e9adf77af9651e9f631559317e2c5b50fa836e2ad382c03d85bd7bf8467ef0da56d7bf34fa8f6b1c805167c11364679ee9e608523d9042d4 + languageName: node + linkType: hard + +"@react-stately/checkbox@npm:^3.7.2": + version: 3.7.2 + resolution: "@react-stately/checkbox@npm:3.7.2" + dependencies: + "@react-stately/form": ^3.2.2 + "@react-stately/utils": ^3.10.8 + "@react-types/checkbox": ^3.10.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: fcaaa2c24f22157faa79c7b764836fa4aa788d13fab27d82f6d42fc4bea722736ce04a5a733f4448144df7e083f2f034a1c6cc97715e465c11a56a53f498b70d + languageName: node + linkType: hard + +"@react-stately/collections@npm:^3.12.8": + version: 3.12.8 + resolution: "@react-stately/collections@npm:3.12.8" + dependencies: + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: aafd6bde787c180ab660213cda60e21b020c1ae3f067579cdfe7286d8212ce02d823875a59685b4629596a1a4de48413271c0cf117dcdcd3671ccfeb569a2fbe + languageName: node + linkType: hard + +"@react-stately/color@npm:^3.9.2": + version: 3.9.2 + resolution: "@react-stately/color@npm:3.9.2" + dependencies: + "@internationalized/number": ^3.6.5 + "@internationalized/string": ^3.2.7 + "@react-stately/form": ^3.2.2 + "@react-stately/numberfield": ^3.10.2 + "@react-stately/slider": ^3.7.2 + "@react-stately/utils": ^3.10.8 + "@react-types/color": ^3.1.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 72159b268e8b897f92e7507dd37bc5eebe0442ff9263f9b44f0d001ef38c945173ea781351e222e5390da28f8ce22267aea0189a2d88e51fdabe2b0e37baa1f7 + languageName: node + linkType: hard + +"@react-stately/combobox@npm:^3.12.0": + version: 3.12.0 + resolution: "@react-stately/combobox@npm:3.12.0" + dependencies: + "@react-stately/collections": ^3.12.8 + "@react-stately/form": ^3.2.2 + "@react-stately/list": ^3.13.1 + "@react-stately/overlays": ^3.6.20 + "@react-stately/utils": ^3.10.8 + "@react-types/combobox": ^3.13.9 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 35133b5b754340bc17342a314de6bf31aa5674191ac18a4daafa2318ab158eba96f3d03fa6fb61954d051d28be740cd3823a79f3ec51b7f252f0bad3b575b501 + languageName: node + linkType: hard + +"@react-stately/data@npm:^3.14.1": + version: 3.14.1 + resolution: "@react-stately/data@npm:3.14.1" + dependencies: + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 3bfbfe670eb3b44326d41b785c9e380370640686070def56cdafd37c51635dddb8f9a94ebba9c5bcadb5d53910a5224abd5be8c8eb83d0ecab21955bd5b50bc6 + languageName: node + linkType: hard + +"@react-stately/datepicker@npm:^3.15.2": + version: 3.15.2 + resolution: "@react-stately/datepicker@npm:3.15.2" + dependencies: + "@internationalized/date": ^3.10.0 + "@internationalized/string": ^3.2.7 + "@react-stately/form": ^3.2.2 + "@react-stately/overlays": ^3.6.20 + "@react-stately/utils": ^3.10.8 + "@react-types/datepicker": ^3.13.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: a1c20762845b2b9e3a889a73c6713c421d5c67c6658ca921117ca7805d61247f312554f238009e99fd7fe9eba60f720cde2256c956356ad2dae99f126c8e4b30 + languageName: node + linkType: hard + +"@react-stately/disclosure@npm:^3.0.8": + version: 3.0.8 + resolution: "@react-stately/disclosure@npm:3.0.8" + dependencies: + "@react-stately/utils": ^3.10.8 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: c978ac9c34da517ab1373a27cab0b15e78545f560c7034c860650dacd6961254ed9da675478a5b923b389574b200740c4e72369fc21ac10fd6a358e6ef1c98fa + languageName: node + linkType: hard + +"@react-stately/dnd@npm:^3.7.1": + version: 3.7.1 + resolution: "@react-stately/dnd@npm:3.7.1" + dependencies: + "@react-stately/selection": ^3.20.6 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 877b0887230e0af5c59fb1cb3934abc6ca446798072b4c7692844f9ba7ac1d680fffaf01d7859ce7c720591cb0c3950f980e4565b11509bbc56f8de3a608d1d1 + languageName: node + linkType: hard + +"@react-stately/flags@npm:^3.1.2": + version: 3.1.2 + resolution: "@react-stately/flags@npm:3.1.2" + dependencies: + "@swc/helpers": ^0.5.0 + checksum: e203a3ef0c9d0faa4ed0bec9ade4b9157f8e52aa196cbe23abc1260025fba306739c9a829b2a9167b0eef27d2db31c72e017804e16dd480c8a523b0e4d225aec + languageName: node + linkType: hard + +"@react-stately/form@npm:^3.2.2": + version: 3.2.2 + resolution: "@react-stately/form@npm:3.2.2" + dependencies: + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 32aed9f29573a5ac692957c7ad19d0f5a661f542b3dfa556c10d9f94e4d9713dda2d223f354a127376299fa724ccdaaf58e938e10615a51a745d2b68f7fbcb7b + languageName: node + linkType: hard + +"@react-stately/grid@npm:^3.11.6": + version: 3.11.6 + resolution: "@react-stately/grid@npm:3.11.6" + dependencies: + "@react-stately/collections": ^3.12.8 + "@react-stately/selection": ^3.20.6 + "@react-types/grid": ^3.3.6 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 87f935a8faf4997ed95209e70a04ee8d4e1c0672d8145031fde11c76cd9a1251077d629426ff55ee752beacde34ef00c2e63945e7e7acfbe760150d8d51967de + languageName: node + linkType: hard + +"@react-stately/layout@npm:^4.5.1": + version: 4.5.1 + resolution: "@react-stately/layout@npm:4.5.1" dependencies: - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/core-plugin-api": ^1.10.7 + "@react-stately/collections": ^3.12.8 + "@react-stately/table": ^3.15.1 + "@react-stately/virtualizer": ^4.4.4 + "@react-types/grid": ^3.3.6 + "@react-types/shared": ^3.32.1 + "@react-types/table": ^3.13.4 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 3c8f051e4ebc33e626fb65906fc80da76867505d2b680f281a7306b2159f9b2aedbf8ec57d0f492f012382fda98e432b6d777ff21ed19de2d66cbfb47ab09071 + languageName: node + linkType: hard + +"@react-stately/list@npm:^3.13.1": + version: 3.13.1 + resolution: "@react-stately/list@npm:3.13.1" + dependencies: + "@react-stately/collections": ^3.12.8 + "@react-stately/selection": ^3.20.6 + "@react-stately/utils": ^3.10.8 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: cea0ac49012434a9ff04223a85eb2d8ed9df972ac8edcef8f0049bb4d96b5e7c5cdab5a4f802d202f9e3176c25ff7a963c22a5496bc8681f9a61c70243006ffd + languageName: node + linkType: hard + +"@react-stately/menu@npm:^3.9.8": + version: 3.9.8 + resolution: "@react-stately/menu@npm:3.9.8" + dependencies: + "@react-stately/overlays": ^3.6.20 + "@react-types/menu": ^3.10.5 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 57ab244ae78367a80f55bfdd052c88361f2389cc8f1f3f66925768f743826b99c1347b3964a10ea2c2ec1b3658ef1df012623d076d0ce8c593d7761a29f4e881 + languageName: node + linkType: hard + +"@react-stately/numberfield@npm:^3.10.2": + version: 3.10.2 + resolution: "@react-stately/numberfield@npm:3.10.2" + dependencies: + "@internationalized/number": ^3.6.5 + "@react-stately/form": ^3.2.2 + "@react-stately/utils": ^3.10.8 + "@react-types/numberfield": ^3.8.15 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 7ef222f2e3ddc9544de21ade915b28a21591bef2a7049e215f7cb24e56636bb555c1e948028d329e0c5ea678ae699ea36785802ae97576265e4d01790a03e67d + languageName: node + linkType: hard + +"@react-stately/overlays@npm:^3.6.20": + version: 3.6.20 + resolution: "@react-stately/overlays@npm:3.6.20" + dependencies: + "@react-stately/utils": ^3.10.8 + "@react-types/overlays": ^3.9.2 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 652a5d3207631e63acd4b9f1a093f7570cbdc33924a02bea4bea2ff3b5e3c3497e92b4b2a3a2fb52136fa06ddfb890db8580ec509387043e0243d801f5e911a8 + languageName: node + linkType: hard + +"@react-stately/radio@npm:^3.11.2": + version: 3.11.2 + resolution: "@react-stately/radio@npm:3.11.2" + dependencies: + "@react-stately/form": ^3.2.2 + "@react-stately/utils": ^3.10.8 + "@react-types/radio": ^3.9.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 4dc766594eaec730d8990605ebb8e834abc84130446cbeefdd4478042f33b8970ef1853848541c5f2125b48a8cf713bbcd4b4c88881ebaa0ef4983c6ee122503 + languageName: node + linkType: hard + +"@react-stately/searchfield@npm:^3.5.16": + version: 3.5.16 + resolution: "@react-stately/searchfield@npm:3.5.16" + dependencies: + "@react-stately/utils": ^3.10.8 + "@react-types/searchfield": ^3.6.6 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 3ec699234ea65739fcfc68fadd649f16ec6dba91b369422fb7d745f26338fa476239b8a1efc953af45d1787c5148242467e6fc8a2a54b1d3a92e8d373a93eba8 + languageName: node + linkType: hard + +"@react-stately/select@npm:^3.8.0": + version: 3.8.0 + resolution: "@react-stately/select@npm:3.8.0" + dependencies: + "@react-stately/form": ^3.2.2 + "@react-stately/list": ^3.13.1 + "@react-stately/overlays": ^3.6.20 + "@react-stately/utils": ^3.10.8 + "@react-types/select": ^3.11.0 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 2d9689d2370940a078d29f77e28bd9bfb822862fc5d87a063b8cc83eba0127ce515c4eb13dc5403510a94c1e1c24ecfcf15ce4fc788ea134348daac80f891ab2 + languageName: node + linkType: hard + +"@react-stately/selection@npm:^3.20.6": + version: 3.20.6 + resolution: "@react-stately/selection@npm:3.20.6" + dependencies: + "@react-stately/collections": ^3.12.8 + "@react-stately/utils": ^3.10.8 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 1a6c8dc0e02efa99f22b591cf6e8149ccc3d4692295ef87adcf081f3ca43d6ebb52c2cee386b3acba18bf8419ce33d140d7b9082e4eb47dc04143956d1d2fdcb + languageName: node + linkType: hard + +"@react-stately/slider@npm:^3.7.2": + version: 3.7.2 + resolution: "@react-stately/slider@npm:3.7.2" + dependencies: + "@react-stately/utils": ^3.10.8 + "@react-types/shared": ^3.32.1 + "@react-types/slider": ^3.8.2 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 2151e01f4e4a0729eb5c9724f521d116ddfaf7eca4a5ada774e99c4662576754f3577519e6f6a201d3c9da31576ce9fecb7e2659c0f9b68dade2f32e5224608a + languageName: node + linkType: hard + +"@react-stately/table@npm:^3.15.1": + version: 3.15.1 + resolution: "@react-stately/table@npm:3.15.1" + dependencies: + "@react-stately/collections": ^3.12.8 + "@react-stately/flags": ^3.1.2 + "@react-stately/grid": ^3.11.6 + "@react-stately/selection": ^3.20.6 + "@react-stately/utils": ^3.10.8 + "@react-types/grid": ^3.3.6 + "@react-types/shared": ^3.32.1 + "@react-types/table": ^3.13.4 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 3a1b9fefad5c32bd41f5721e3e623155063bc4e10b8d290cd4423599e0cec66575414c18d4c4d42cea72042f86e4b45d655b68b0dbde9d6104aea52ec5486278 + languageName: node + linkType: hard + +"@react-stately/tabs@npm:^3.8.6": + version: 3.8.6 + resolution: "@react-stately/tabs@npm:3.8.6" + dependencies: + "@react-stately/list": ^3.13.1 + "@react-types/shared": ^3.32.1 + "@react-types/tabs": ^3.3.19 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 6914d7ad516a3db4145fe7510532ed6424b27f63fc94be2f78f6ee655ced2664a71d780b4659823acaa8ab19bb4c6a1cf1215172fb6f2020394df42b6be83382 + languageName: node + linkType: hard + +"@react-stately/toast@npm:^3.1.2": + version: 3.1.2 + resolution: "@react-stately/toast@npm:3.1.2" + dependencies: + "@swc/helpers": ^0.5.0 + use-sync-external-store: ^1.4.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 3e6083f8a2c8fa957bcc40f02812fbefbe0b164a10004d1cfb3ba369049b306f77db953fdb500fde9b98c80f7d572595f206ef803d09313251e278916fc257a9 + languageName: node + linkType: hard + +"@react-stately/toggle@npm:^3.9.2": + version: 3.9.2 + resolution: "@react-stately/toggle@npm:3.9.2" + dependencies: + "@react-stately/utils": ^3.10.8 + "@react-types/checkbox": ^3.10.2 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 36538faf11ed6554759bec74f7e12a7c6db63e93450ceb8299feb3bc94318256187e4c7708c6048088964f703e48541b90d9abe5750ba90495a296723065872c + languageName: node + linkType: hard + +"@react-stately/tooltip@npm:^3.5.8": + version: 3.5.8 + resolution: "@react-stately/tooltip@npm:3.5.8" + dependencies: + "@react-stately/overlays": ^3.6.20 + "@react-types/tooltip": ^3.4.21 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 1c4019f212dc058279507f955cfa6cd91fd1e8fd611d6c68232e2211ada7fc00dfa58febb4bcf2ad5acbdf2b965c8c6e00f19b80e9ddbee8721d9ca44c822420 + languageName: node + linkType: hard + +"@react-stately/tree@npm:^3.9.3": + version: 3.9.3 + resolution: "@react-stately/tree@npm:3.9.3" + dependencies: + "@react-stately/collections": ^3.12.8 + "@react-stately/selection": ^3.20.6 + "@react-stately/utils": ^3.10.8 + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 2c3f45d06860bbc7875fe258d137d1c80df22c5ee9d834881f44b679cb784a82adf1e0a9854d2059b836b2902b813972c20028e8b3eca03f5179b6a957fa6472 + languageName: node + linkType: hard + +"@react-stately/utils@npm:^3.10.8": + version: 3.10.8 + resolution: "@react-stately/utils@npm:3.10.8" + dependencies: + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 3d0ed0c1a73c06e50775a7037a4f88f12505313f6caa431d87c8ef20cfec63fedb60be294e6986d1ef5f5d85e5e7b1e2794f5971988561dc1ae78fc40e432c5c + languageName: node + linkType: hard + +"@react-stately/virtualizer@npm:^4.4.4": + version: 4.4.4 + resolution: "@react-stately/virtualizer@npm:4.4.4" + dependencies: + "@react-types/shared": ^3.32.1 + "@swc/helpers": ^0.5.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: c22eff41614e39deb2bda7a57cc1aa139231a86f1954dd18435889043498afa8b4f37d695cf3a16e4a2942f856d8826a8fb346fecc21cb23c24ffa38076dfacf + languageName: node + linkType: hard + +"@react-types/autocomplete@npm:3.0.0-alpha.35": + version: 3.0.0-alpha.35 + resolution: "@react-types/autocomplete@npm:3.0.0-alpha.35" + dependencies: + "@react-types/combobox": ^3.13.9 + "@react-types/searchfield": ^3.6.6 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: ee6707c5a57eab196928ddbdd6c675dcc8a4099bc6540f78aad2c3d962a3195b02e31c54f3b657a1c562a91aa08b64048ae9d0cb07ed1d0e5e4ead989bec7fa7 + languageName: node + linkType: hard + +"@react-types/breadcrumbs@npm:^3.7.17": + version: 3.7.17 + resolution: "@react-types/breadcrumbs@npm:3.7.17" + dependencies: + "@react-types/link": ^3.6.5 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 4eec761c03c7297288595d1b28ced314d8580dbbb57707594ab59240dcd1bb36641ed102aad0c2f36a000a4104d036059c58252511dc90a3d00214f1eb030390 + languageName: node + linkType: hard + +"@react-types/button@npm:^3.14.1": + version: 3.14.1 + resolution: "@react-types/button@npm:3.14.1" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 0f4f296b9c1cd524b5e0d666044db446b08b760155aa30159387eedaa52a743190b48ef7f5a6770a3207db22b312e2f23e1443c6dad9b962d6284a0e9a725023 + languageName: node + linkType: hard + +"@react-types/calendar@npm:^3.8.0": + version: 3.8.0 + resolution: "@react-types/calendar@npm:3.8.0" + dependencies: + "@internationalized/date": ^3.10.0 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: fedc7867eb680593ff0d5d42925792ba27564c718b09538293213935741d5a93fec6fa5b9e85987c3112ff86f38aa2d80aaeb4dafb65c3ec730e55b8c4929c67 + languageName: node + linkType: hard + +"@react-types/checkbox@npm:^3.10.2": + version: 3.10.2 + resolution: "@react-types/checkbox@npm:3.10.2" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: f2170d063534aaa753010654d5906bc06fb8f783c6419787af4e6af2434b7251364e7c5d8e1f0a319fb03964334cc8776e311000b40bce06dc2842f5bfe14c65 + languageName: node + linkType: hard + +"@react-types/color@npm:^3.1.2": + version: 3.1.2 + resolution: "@react-types/color@npm:3.1.2" + dependencies: + "@react-types/shared": ^3.32.1 + "@react-types/slider": ^3.8.2 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: fe8da91bf4cd73e684c44e4e4dcc5d37bd4d01a92e8d9ea184c0535c2fd056d4eb7b3eb35da222f4ed152ae7cfe6ccbfca1fc0ad3d698bab17f05aca273d86d3 + languageName: node + linkType: hard + +"@react-types/combobox@npm:^3.13.9": + version: 3.13.9 + resolution: "@react-types/combobox@npm:3.13.9" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 41af2a7a7372b8727ba2f5f39108570d2b03acdb81c63e235e11e97b2d4ef852a70d902dd894f5c909bff242144bd7daf516aca9a402a869b7f8a5c0e9e6d8b9 + languageName: node + linkType: hard + +"@react-types/datepicker@npm:^3.13.2": + version: 3.13.2 + resolution: "@react-types/datepicker@npm:3.13.2" + dependencies: + "@internationalized/date": ^3.10.0 + "@react-types/calendar": ^3.8.0 + "@react-types/overlays": ^3.9.2 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 5300fdf033586b14fcc223aeb10d0c1df0bc733969952aedda44c5ba64abf7490d7aed1960c30e5094ba9da126a755a2835c38c5586ea75d0dc0bddf4a73ce35 + languageName: node + linkType: hard + +"@react-types/dialog@npm:^3.5.22": + version: 3.5.22 + resolution: "@react-types/dialog@npm:3.5.22" + dependencies: + "@react-types/overlays": ^3.9.2 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 9ca84b9dfaf19e74fca809a18dc587ce9932186c8929c8db3ceaf6ea29ee354a3961c637ea2eb93df874aa31ad6dc417d976e6a149c4af44f27d70b6f9bdfb28 + languageName: node + linkType: hard + +"@react-types/form@npm:^3.7.16": + version: 3.7.16 + resolution: "@react-types/form@npm:3.7.16" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 1ded7b147e644f5a26161d009883af0749c8ec8752f20983d5e0837aa8ec2078626546f081516ef532845e7b661e641c520bb3459c777d6f4d6a60510a1031d9 + languageName: node + linkType: hard + +"@react-types/grid@npm:^3.3.6": + version: 3.3.6 + resolution: "@react-types/grid@npm:3.3.6" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: c09fcb60a084b89b0cbf85dec0dd6a27fbb0b0dbf4fff5656456e6dd375c3cc4e5e969518503013ea696dfe818dd95e57d1a7fd180de525109ae967951c65b52 + languageName: node + linkType: hard + +"@react-types/link@npm:^3.6.5": + version: 3.6.5 + resolution: "@react-types/link@npm:3.6.5" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 77a5a5d53cbb0ec69373953d7ca34fe0eaea56f76c741cd706e5559b70d828d37a7955036562559eed83bfcda3413f20be68c1cc20a47089c0007f819aa38dbb + languageName: node + linkType: hard + +"@react-types/listbox@npm:^3.7.4": + version: 3.7.4 + resolution: "@react-types/listbox@npm:3.7.4" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: b42f1f02eeb0efdb72303ca4ba676eff5d425124c04a0ef5ef5fea7a6a6922f956c823c18e3b6889ee470d9c01747ed104265114f5505ed41a08763ee066e597 + languageName: node + linkType: hard + +"@react-types/menu@npm:^3.10.5": + version: 3.10.5 + resolution: "@react-types/menu@npm:3.10.5" + dependencies: + "@react-types/overlays": ^3.9.2 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 39675f5d94a7733ea483af835cf8934db729367bef6a72af0ee3c24b29bf3d74bcfe70b3efeddc131377b270c59f065bf7de79fae4a2d827e0acd5a16acf6d09 + languageName: node + linkType: hard + +"@react-types/meter@npm:^3.4.13": + version: 3.4.13 + resolution: "@react-types/meter@npm:3.4.13" + dependencies: + "@react-types/progress": ^3.5.16 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 490c195a2656ca9c1ac65fbd4ea51eed16a22e45a63b8ec1fa74f27be438b94080b3a73a4c629ef4debb343f7bd2e49d8b764e9d6c19d3dee0d63b48a2c99f85 + languageName: node + linkType: hard + +"@react-types/numberfield@npm:^3.8.15": + version: 3.8.15 + resolution: "@react-types/numberfield@npm:3.8.15" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 4ffa7e3a896a71d1f19297bc5c10a52b376641d7ba10c9f2375e536a3555aa350157eab38b2150478296606ebecf5bfcf6b4318ce27ca26309ac57d825df9565 + languageName: node + linkType: hard + +"@react-types/overlays@npm:^3.9.2": + version: 3.9.2 + resolution: "@react-types/overlays@npm:3.9.2" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 50b638da5c96d7a69deed05d1d014f49a10ec0b5906c67c946097ae1b7b8acc5ab0e3f4979c8e4ffa4d5e5240435e620c12164fe87f6d6e0a448a4f7e9c1aed9 + languageName: node + linkType: hard + +"@react-types/progress@npm:^3.5.16": + version: 3.5.16 + resolution: "@react-types/progress@npm:3.5.16" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: bf73947352017bcf5b33683485ada6b47cae3728caf1229f904aa2ab32da9b6d3bb61b1311518d883f2bfd5911a1a0ee923bdae5937d37cab94c99aaf56607d8 + languageName: node + linkType: hard + +"@react-types/radio@npm:^3.9.2": + version: 3.9.2 + resolution: "@react-types/radio@npm:3.9.2" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 9ca6179f745c7ff0a180eba8712dc3135f79c833cdae815e6bcb5962b4d33ad5862f45295c0f5d87e8bf8861e82934a757911f5e0f32cf8939e5c62d8c2fde76 + languageName: node + linkType: hard + +"@react-types/searchfield@npm:^3.6.6": + version: 3.6.6 + resolution: "@react-types/searchfield@npm:3.6.6" + dependencies: + "@react-types/shared": ^3.32.1 + "@react-types/textfield": ^3.12.6 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: a3ae8ce97178cc39b3aad079dc778020146d99fa95e66fc3d90e24ec4a4a524210d3e04b72e5923988cc599fd2697fb88c950f79b7dcabe7bb9a2c9a279c18b4 + languageName: node + linkType: hard + +"@react-types/select@npm:^3.11.0": + version: 3.11.0 + resolution: "@react-types/select@npm:3.11.0" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 6a08b49685edc79eb3326d836e1a3fa5b46db2ce9370808a578b24574b5282b49b83314d3ebf543e9af54fcc641a5f35a2d5abeeb3b4db4cfbe6468d7bdaf1b0 + languageName: node + linkType: hard + +"@react-types/shared@npm:^3.32.1": + version: 3.32.1 + resolution: "@react-types/shared@npm:3.32.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: d9dbe96ecde50f34061b803133b9eca22c21cc754c08db3748617a6a1f4304fab08afd2f8ed295f5c671632c1750ed2cfea7ee36005014cec50231f20cb60903 + languageName: node + linkType: hard + +"@react-types/slider@npm:^3.8.2": + version: 3.8.2 + resolution: "@react-types/slider@npm:3.8.2" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 5aef259fbd9fc238f6882c88769df53ca428677e2fec48ae19e880ed148df7d6f95ac7bbc0c23be16884e6e551ebba52a872740c114ca16316b317497e5e2398 + languageName: node + linkType: hard + +"@react-types/switch@npm:^3.5.15": + version: 3.5.15 + resolution: "@react-types/switch@npm:3.5.15" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 3fb7b5b671b41208af84ff4f029412f68558d76df3401b54542ab333779f2553455a7848c17aa0d19b1945e52e059677782f2831ebcf56476638d7dd3d827156 + languageName: node + linkType: hard + +"@react-types/table@npm:^3.13.4": + version: 3.13.4 + resolution: "@react-types/table@npm:3.13.4" + dependencies: + "@react-types/grid": ^3.3.6 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: b64bf6a21caa3449e45369f93177f50a7eceb91653d6ff18126fbb1ea9da2d896a48af74b4d70cd507dbe3e158a3d795d88e47ea4c7f78050025550944179cd2 + languageName: node + linkType: hard + +"@react-types/tabs@npm:^3.3.19": + version: 3.3.19 + resolution: "@react-types/tabs@npm:3.3.19" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: ce4209b21c591c5baee93db6a063dedfbb4794ddd99477601e09efd388dd9efe7fb1a05844c4131de3e1f091605fb247ca14dec31ac54ae2f5a6519098fe932e + languageName: node + linkType: hard + +"@react-types/textfield@npm:^3.12.6": + version: 3.12.6 + resolution: "@react-types/textfield@npm:3.12.6" + dependencies: + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 2187424d5939b949f3652775ad7f141c69549555ef047f8232191e8f104c3b88e628e686822f1b1e3892488edb4366bea95d18dd86fc6807763881ba87d2df07 + languageName: node + linkType: hard + +"@react-types/tooltip@npm:^3.4.21": + version: 3.4.21 + resolution: "@react-types/tooltip@npm:3.4.21" + dependencies: + "@react-types/overlays": ^3.9.2 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 8d92f10656292a302ddb75a7a2bf95eeb8368221ceff9d338ec3c8dcd73714bbb472ec6f1549f296e7f13fd8d4689d35a6d7a85ea5ffc394897c6e27a50784b8 + languageName: node + linkType: hard + +"@red-hat-developer-hub/backstage-plugin-adoption-insights-backend@npm:0.3.0": + version: 0.3.0 + resolution: "@red-hat-developer-hub/backstage-plugin-adoption-insights-backend@npm:0.3.0" + dependencies: + "@backstage/backend-defaults": ^0.12.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/core-plugin-api": ^1.10.9 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": ^0.3.0 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-permission-common": ^0.9.1 + "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": ^0.4.0 express: ^4.17.1 express-promise-router: ^4.1.0 json-2-csv: ^5.5.8 @@ -13677,116 +14932,121 @@ __metadata: luxon: ^3.5.0 uuid: ^11.1.0 zod: ^3.22.4 - checksum: 86a0d4b2279ceb671d50b9b715bf2115745dc235bb2156b4c46bad52fbc1c778f69ba6424bce131aa21c14d937dcb132d2e562b43d8161915a5cd9594d10d57a + checksum: 9f93ad9674f27ae44178893b27f536548fca425afd6678699e41af55535366d332ab1f7316e8102ec09968622a7c21cad2a84bc1b6c7679d0e202d08668a05a0 languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-adoption-insights-common@npm:0.3.0, @red-hat-developer-hub/backstage-plugin-adoption-insights-common@npm:^0.3.0": - version: 0.3.0 - resolution: "@red-hat-developer-hub/backstage-plugin-adoption-insights-common@npm:0.3.0" +"@red-hat-developer-hub/backstage-plugin-adoption-insights-common@npm:0.4.0, @red-hat-developer-hub/backstage-plugin-adoption-insights-common@npm:^0.4.0": + version: 0.4.0 + resolution: "@red-hat-developer-hub/backstage-plugin-adoption-insights-common@npm:0.4.0" peerDependencies: - "@backstage/plugin-permission-common": ^0.9.0 - checksum: aaed4249eca1798ead1feecf6f1cda23be1a1169aee136dfaae8ec506dc76c2d7565a7e677e9bf57399eb643667d0d0ef39d7af543b355549e13ce6353fddcbe + "@backstage/plugin-permission-common": ^0.9.1 + checksum: afb3712c3c691049945d7dfc82289e91932e3952a8088341b4a47de32490580d4fd1ed5c5e0d50f7f9cde5969280a3e8210a29b1439710208af5ff3aa0f9680f languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-adoption-insights@npm:0.2.1": - version: 0.2.1 - resolution: "@red-hat-developer-hub/backstage-plugin-adoption-insights@npm:0.2.1" - dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/theme": ^0.6.6 +"@red-hat-developer-hub/backstage-plugin-adoption-insights@npm:0.3.2": + version: 0.3.2 + resolution: "@red-hat-developer-hub/backstage-plugin-adoption-insights@npm:0.3.2" + dependencies: + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@mui/icons-material": 5.17.1 - "@mui/lab": 5.0.0-alpha.176 - "@mui/material": 5.17.1 + "@mui/icons-material": 5.18.0 + "@mui/lab": 5.0.0-alpha.177 + "@mui/material": 5.18.0 "@mui/x-date-pickers": 5.0.20 - "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": ^0.3.0 + "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": ^0.4.0 date-fns: 2.30.0 - date-fns-tz: 1.3.7 + date-fns-tz: 1.3.8 react-use: ^17.2.4 recharts: ^2.15.1 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: 6a180424d54ee087ad9359d3b3ce79fc0436c8ea855da71bc2cdcd89c407cca7ed005d16be8d2681ae211881e81c24f8f8b17d20fd5f83fa9809af443bf01ee8 + checksum: 2db29fba88e54d9c06940bcd4d1f9d63e6fd4420946d91a7d85e11c945c8caf69a529d43d9ffb80aff75534bc04296fbc10bf611ec54ea6add754fd8bad73d75 languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights@npm:0.2.0": - version: 0.2.0 - resolution: "@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights@npm:0.2.0" +"@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights@npm:0.3.0": + version: 0.3.0 + resolution: "@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights@npm:0.3.0" dependencies: - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/theme": ^0.6.6 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/theme": ^0.6.8 "@material-ui/core": ^4.9.13 "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.61 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: 4a6f7420543450e7375d82ae1d536c930521fb0b460a7731c5a96ac3432071d616f672e9dabebe972dc47bdeeb4f77bc3a0bb04de16ae58148182ecca6bf2fcd + checksum: 212f4bac791bbf23efc56ae46ca40991afb998b2a01c579942775d81e84c7bab57e8b2fdd914975a54551afb97d8cc8eda7496eee50c1f59d22e8d11d09730b5 languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-bulk-import-backend@npm:6.1.3": - version: 6.1.3 - resolution: "@red-hat-developer-hub/backstage-plugin-bulk-import-backend@npm:6.1.3" +"@red-hat-developer-hub/backstage-plugin-bulk-import-backend@npm:6.5.1": + version: 6.5.1 + resolution: "@red-hat-developer-hub/backstage-plugin-bulk-import-backend@npm:6.5.1" dependencies: - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 + "@backstage/backend-defaults": ^0.12.0 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-model": ^1.7.5 + "@backstage/config": ^1.3.3 "@backstage/errors": ^1.2.7 - "@backstage/integration": ^1.17.0 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.0 + "@backstage/integration": ^1.17.1 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.3 + "@gitbeaker/rest": ^43.4.0 + "@microsoft/fetch-event-source": ^2.0.1 "@octokit/auth-app": ^6.0.3 "@octokit/rest": ^20.0.2 - "@red-hat-developer-hub/backstage-plugin-bulk-import-common": ^1.7.1 + "@red-hat-developer-hub/backstage-plugin-bulk-import-common": ^1.10.0 ajv-formats: ^3.0.1 express: ^4.17.1 git-url-parse: ^14.0.0 js-yaml: ^4.1.0 just-kebab-case: 4.2.0 + knex: ^3.0.0 luxon: ^3.4.4 node-fetch: ^2.6.7 openapi-backend: ^5.10.6 peerDependencies: "@janus-idp/backstage-plugin-audit-log-node": ^1.7.0 - checksum: 12abe641518f3861ecad412b159ad8bf1ff0432d2792c287d1c4dc84f23786f8e3a7f175e6425e3349dd8c716022d5536494049e84054c4e1f5abe7f22c1251e + checksum: 25f9b52b3236571e6179b63be6b90a1f46ccc4b0a779639f563353d2ebab7c66febfb1335eb3fb6dfc64dc1e00ab36fec72554812a19380528bb168410ddbd3c languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-bulk-import-common@npm:^1.7.1": - version: 1.7.1 - resolution: "@red-hat-developer-hub/backstage-plugin-bulk-import-common@npm:1.7.1" +"@red-hat-developer-hub/backstage-plugin-bulk-import-common@npm:^1.10.0": + version: 1.10.0 + resolution: "@red-hat-developer-hub/backstage-plugin-bulk-import-common@npm:1.10.0" peerDependencies: - "@backstage/plugin-permission-common": ^0.9.0 - checksum: 90e435b09288744d12128eb5b5f0a181d983f014011dd0ac9079694b407d0556f3e394ca3cb3f4c5b089e1633667ea4f1f7b5f82cca0039b7713885bc6d06714 + "@backstage/plugin-permission-common": ^0.9.1 + checksum: fe62624b0cfa28c4e08210a0a95f0bf7eb8ae2829b965683a3d5d3b21a971494f0d2bfa2732690e235073f13831562bb2fcafec2524122839f9d345a8698106d languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-bulk-import@npm:1.13.3": - version: 1.13.3 - resolution: "@red-hat-developer-hub/backstage-plugin-bulk-import@npm:1.13.3" - dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-import": ^0.13.0 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/theme": ^0.6.6 +"@red-hat-developer-hub/backstage-plugin-bulk-import@npm:1.18.1": + version: 1.18.1 + resolution: "@red-hat-developer-hub/backstage-plugin-bulk-import@npm:1.18.1" + dependencies: + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-import": ^0.13.4 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 "@mui/icons-material": ^5.15.17 "@mui/material": ^5.12.2 - "@mui/styles": 5.17.1 - "@red-hat-developer-hub/backstage-plugin-bulk-import-common": ^1.7.1 + "@mui/styles": 5.18.0 + "@red-hat-developer-hub/backstage-plugin-bulk-import-common": ^1.10.0 "@tanstack/react-query": ^4.29.21 formik: ^2.4.5 js-yaml: ^4.1.0 @@ -13797,66 +15057,69 @@ __metadata: peerDependencies: react: 16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: 47de57ecab3948017253383c03f02d510a7aecb38eece2aec118d86c2adf4233de315ead20e49888251c39bbbae29f39f8629ed33eec2a26c4bcec616ca85775 + checksum: e290eb2fc8bd20a0ba7215416caf81894dbaeb023939acea352d91083d141da0a4b8fec957eb800bb69e6fc7ad8f3998ca85fb787c7b717da0fe8a26972d1bfc languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace@npm:0.3.3": - version: 0.3.3 - resolution: "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace@npm:0.3.3" +"@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace@npm:0.7.1": + version: 0.7.1 + resolution: "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace@npm:0.7.1" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-model": ^1.7.4 - "@backstage/plugin-catalog-common": ^1.1.4 - "@backstage/plugin-catalog-node": ^1.17.0 + "@backstage/backend-dynamic-feature-service": ^0.7.3 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/cli-common": ^0.1.15 + "@backstage/plugin-catalog-common": ^1.1.5 + "@backstage/plugin-catalog-node": ^1.18.0 "@backstage/types": ^1.2.1 - "@red-hat-developer-hub/backstage-plugin-marketplace-common": ^0.6.0 + "@red-hat-developer-hub/backstage-plugin-marketplace-common": ^0.10.1 find-root: ^1.1.0 glob: ^8.1.0 js-yaml: ^4.1.0 semver: ^7.6.3 - checksum: 6297e845470fb967a3fbb07e07144c0178f2e51da10cc2df005678b63a08bbaf32125a253852508be49eea4f628032d5934f9afb5878845b3db9506d10583190 + checksum: 5d755b0d3c7cad9d3b8eff264170f89a4adf03cac267f1fcf1d96d3ecd4ded3b56d404a586aa42c1675fb276a02e373ab5eaee3129348aeafe014f83b1d9768e languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-dynamic-home-page@npm:1.5.0": - version: 1.5.0 - resolution: "@red-hat-developer-hub/backstage-plugin-dynamic-home-page@npm:1.5.0" - dependencies: - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-home": ^0.8.8 - "@backstage/plugin-home-react": ^0.1.26 - "@backstage/plugin-search-react": ^1.9.0 - "@backstage/plugin-user-settings": ^0.8.22 - "@backstage/theme": ^0.6.6 - "@mui/icons-material": 5.17.1 - "@mui/material": 5.17.1 - "@mui/styles": 5.17.1 +"@red-hat-developer-hub/backstage-plugin-dynamic-home-page@npm:1.9.2": + version: 1.9.2 + resolution: "@red-hat-developer-hub/backstage-plugin-dynamic-home-page@npm:1.9.2" + dependencies: + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-home": ^0.8.11 + "@backstage/plugin-home-react": ^0.1.29 + "@backstage/plugin-search-react": ^1.9.3 + "@backstage/plugin-user-settings": ^0.8.25 + "@backstage/theme": ^0.6.8 + "@mui/icons-material": 5.18.0 + "@mui/material": 5.18.0 + "@mui/styles": 5.18.0 "@scalprum/react-core": 0.9.5 - react-grid-layout: 1.5.1 + react-grid-layout: 1.5.2 react-use: 17.6.0 - tss-react: 4.9.18 + tss-react: 4.9.19 peerDependencies: react: 16.13.1 || ^17.0.0 || ^18.2.0 react-router-dom: 6.30.1 - checksum: 450cec97c8c1dc07181403144d1df79d4b6567b0a90d5d324353489af2366009e52c20b6ccbfbac1cdcaba69ede431fb8cc22ce41657faed5e4e7c29bcef885d + checksum: f3ddeb3ed84fc7e2a2c8662d94804a091b278ddccc9317e7d86998fe69b65d63c7149dffc9e0c6d87eae24aec60b31aab414657edd5c984d998514350fef6990 languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-global-floating-action-button@npm:1.2.1": - version: 1.2.1 - resolution: "@red-hat-developer-hub/backstage-plugin-global-floating-action-button@npm:1.2.1" +"@red-hat-developer-hub/backstage-plugin-global-floating-action-button@npm:1.5.0": + version: 1.5.0 + resolution: "@red-hat-developer-hub/backstage-plugin-global-floating-action-button@npm:1.5.0" dependencies: - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/theme": ^0.6.6 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/theme": ^0.6.8 "@mui/icons-material": ^5.15.17 "@mui/material": ^5.15.17 - "@mui/styles": 5.17.1 + "@mui/styles": 5.18.0 "@scalprum/react-core": 0.9.5 classnames: ^2.5.1 react-use: ^17.2.4 @@ -13864,140 +15127,143 @@ __metadata: react: 16.13.1 || ^17.0.0 || ^18.0.0 react-dom: 16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: 182109d8443cd7fafa30f2a0d78b7ee95fbc1045d140f07c318a5767e4530cb65b7c81dfb08f79fd864158e67d5483571304f0cb8d3732aacbf10e74c8d55af7 + checksum: c8cfe4cf37a2c96a70a017789fa92c9b2fbdd237077d6ced572947498d851a4237e13df4aec1904b8ad2a14010d9fbd81acd0dad9c60e66b75ea6440f4f95d1d languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-global-header@npm:1.14.0": - version: 1.14.0 - resolution: "@red-hat-developer-hub/backstage-plugin-global-header@npm:1.14.0" - dependencies: - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-notifications": ^0.5.5 - "@backstage/plugin-notifications-common": ^0.0.8 - "@backstage/plugin-search": ^1.4.26 - "@backstage/plugin-search-backend": ^2.0.2 - "@backstage/plugin-search-backend-module-catalog": ^0.3.4 - "@backstage/plugin-search-backend-module-pg": ^0.5.44 - "@backstage/plugin-search-backend-module-techdocs": ^0.4.2 - "@backstage/plugin-search-common": ^1.2.18 - "@backstage/plugin-search-react": ^1.9.0 - "@backstage/plugin-signals-react": ^0.0.13 - "@backstage/plugin-user-settings": ^0.8.22 - "@backstage/theme": ^0.6.6 - "@mui/icons-material": 5.17.1 - "@mui/material": 5.17.1 - "@mui/styled-engine": 5.16.14 +"@red-hat-developer-hub/backstage-plugin-global-header@npm:1.18.1": + version: 1.18.1 + resolution: "@red-hat-developer-hub/backstage-plugin-global-header@npm:1.18.1" + dependencies: + "@backstage/catalog-model": ^1.7.5 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-notifications": ^0.5.8 + "@backstage/plugin-notifications-common": ^0.1.0 + "@backstage/plugin-search": ^1.4.29 + "@backstage/plugin-search-backend": ^2.0.5 + "@backstage/plugin-search-backend-module-catalog": ^0.3.7 + "@backstage/plugin-search-backend-module-pg": ^0.5.47 + "@backstage/plugin-search-backend-module-techdocs": ^0.4.5 + "@backstage/plugin-search-common": ^1.2.19 + "@backstage/plugin-search-react": ^1.9.3 + "@backstage/plugin-signals-react": ^0.0.15 + "@backstage/plugin-user-settings": ^0.8.25 + "@backstage/theme": ^0.6.8 + "@mui/icons-material": 5.18.0 + "@mui/material": 5.18.0 + "@mui/styled-engine": 5.18.0 "@scalprum/react-core": 0.9.5 react-use: ^17.5.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: ^6.0.0 - checksum: 1878cbd5931824ab00e0688ee16840474e00b62a2f7b20a645133a08cf7ec7af8e8ed96805878cfd6f7af04b8ddcd29973d60607e0c5c2ac907b3c2f30156650 + checksum: 35708a424c980de29e8f666511ade1cc059615d25e0deff9543beeba440110ccf07ce9d85709512c5b03b227df9fc7b96f150096e71db20248a8bc270c7330c9 languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-marketplace-backend@npm:0.6.0": - version: 0.6.0 - resolution: "@red-hat-developer-hub/backstage-plugin-marketplace-backend@npm:0.6.0" +"@red-hat-developer-hub/backstage-plugin-marketplace-backend@npm:0.11.0": + version: 0.11.0 + resolution: "@red-hat-developer-hub/backstage-plugin-marketplace-backend@npm:0.11.0" dependencies: - "@backstage/backend-defaults": ^0.10.0 - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 + "@backstage/backend-defaults": ^0.12.0 + "@backstage/backend-dynamic-feature-service": ^0.7.3 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 "@backstage/errors": ^1.2.7 - "@backstage/plugin-catalog-node": ^1.17.0 - "@backstage/plugin-permission-common": ^0.9.0 - "@backstage/plugin-permission-node": ^0.10.0 - "@red-hat-developer-hub/backstage-plugin-marketplace-common": ^0.6.0 + "@backstage/plugin-catalog-node": ^1.18.0 + "@backstage/plugin-permission-common": ^0.9.1 + "@backstage/plugin-permission-node": ^0.10.3 + "@red-hat-developer-hub/backstage-plugin-marketplace-common": ^0.10.1 express: ^4.17.1 express-promise-router: ^4.1.0 yaml: ^2.7.1 zod: ^3.22.4 - checksum: da05ffa5df0b1c0a06617647ef76b6509b540446ab86d0ee0ec8293e8bfe6b568561a4d9d8e76ad66e4bca0d85c377c7c1fb238523a21a0e4854769a3f9c13ca + checksum: 6ea817888c3cc18aed3a3fa6dfcab0f9d7d80bda0d02b4d94959237073db5c65e748fd7ee1d7c5327123259860b914a8ba7340ab5d9d8061755465409a6d9efc languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-marketplace-common@npm:0.6.0, @red-hat-developer-hub/backstage-plugin-marketplace-common@npm:^0.6.0": - version: 0.6.0 - resolution: "@red-hat-developer-hub/backstage-plugin-marketplace-common@npm:0.6.0" +"@red-hat-developer-hub/backstage-plugin-marketplace-common@npm:0.10.1, @red-hat-developer-hub/backstage-plugin-marketplace-common@npm:^0.10.1": + version: 0.10.1 + resolution: "@red-hat-developer-hub/backstage-plugin-marketplace-common@npm:0.10.1" dependencies: - "@backstage/backend-plugin-api": ^1.3.1 - "@backstage/catalog-client": ^1.10.0 - "@backstage/catalog-model": ^1.7.4 - "@backstage/core-plugin-api": ^1.10.8 + "@backstage/backend-plugin-api": ^1.4.2 + "@backstage/catalog-client": ^1.11.0 + "@backstage/catalog-model": ^1.7.5 "@backstage/errors": ^1.2.7 - "@backstage/plugin-permission-common": ^0.9.0 + "@backstage/plugin-permission-common": ^0.9.1 peerDependencies: - "@backstage/backend-plugin-api": ^1.3.1 + "@backstage/backend-plugin-api": ^1.4.2 "@backstage/types": ^1.2.1 - checksum: 2a805fede964c182acb452060f86d27fedb3f7ead6b05780bd7b1930bf5395186d509b8226e5da2cb533972691c7c09110f43811b4331b5a3235c2d29180d8f0 + checksum: c9daeb03b47592946bc73439d451138627eb8bd4b3011af4e80525685d73910bc5bfd7185f8688c1176a9f99512803c41956db87bb8efd7587c02e5a399e7499 languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-marketplace@npm:0.7.0": - version: 0.7.0 - resolution: "@red-hat-developer-hub/backstage-plugin-marketplace@npm:0.7.0" - dependencies: - "@backstage/catalog-client": ^1.10.0 - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/plugin-catalog-react": ^1.18.0 - "@backstage/plugin-permission-react": ^0.4.34 - "@backstage/theme": ^0.6.6 +"@red-hat-developer-hub/backstage-plugin-marketplace@npm:0.11.4": + version: 0.11.4 + resolution: "@red-hat-developer-hub/backstage-plugin-marketplace@npm:0.11.4" + dependencies: + "@backstage/catalog-client": ^1.11.0 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-catalog-react": ^1.20.1 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 "@backstage/types": ^1.2.1 + "@material-table/core": ^6.4.4 "@material-ui/core": ^4.12.2 "@monaco-editor/react": ^4.7.0 "@mui/icons-material": ^5.16.7 "@mui/material": ^5.12.2 - "@mui/styles": 5.17.1 - "@red-hat-developer-hub/backstage-plugin-marketplace-common": ^0.6.0 + "@mui/styles": 5.18.0 + "@red-hat-developer-hub/backstage-plugin-marketplace-common": ^0.10.1 "@scalprum/react-core": 0.9.5 "@tanstack/react-query": ^5.60.5 - monaco-editor: ^0.52.2 + monaco-editor: ^0.53.0 react-use: ^17.6.0 yaml: ^2.7.0 peerDependencies: react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 react-router-dom: ^6.3.0 - checksum: 266b9566d2de51c515d34f17a3ab296f2938aecac1eb63da2c21a57861ed7e43aa68b9f6d90a41846a85850d98d4c7d98adaf9d977c96bc78818d78720ecf32f + checksum: 3b6ef4d3f08050fd6cc877915665bf4cbe4bdd160ffa6bef45c0cd8960d270553ef878aa7508fb9c61947549546edf4d5e10cdb0b687d8e93a3c2056b799b31d languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-quickstart@npm:1.1.0": - version: 1.1.0 - resolution: "@red-hat-developer-hub/backstage-plugin-quickstart@npm:1.1.0" +"@red-hat-developer-hub/backstage-plugin-quickstart@npm:1.6.2": + version: 1.6.2 + resolution: "@red-hat-developer-hub/backstage-plugin-quickstart@npm:1.6.2" dependencies: - "@backstage/core-components": ^0.17.2 - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/theme": ^0.6.6 - "@mui/icons-material": 5.17.1 - "@mui/material": 5.17.1 - "@red-hat-developer-hub/backstage-plugin-theme": ^0.9.0 - react-use: ^17.2.4 + "@backstage-community/plugin-rbac-common": ^1.19.0 + "@backstage/core-components": ^0.17.5 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/plugin-permission-react": ^0.4.36 + "@backstage/theme": ^0.6.8 + "@mui/icons-material": 5.18.0 + "@mui/material": 5.18.0 + "@red-hat-developer-hub/backstage-plugin-theme": ^0.10.0 + react-use: ^17.6.0 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: 4008f34771a43e64fdef3269736095daa07fc79d98ea4a7736f202739b66a0ad47424a85313f397b8b7a49b20a271792e4f291c55b8c7bea3c2a3f354240dcd6 + checksum: b27f76a05f6a8b63bdb3c29a128345295b25a25fd762e036680937f480f9928849be642b799f2bcb21f8286000aef3df6af087498163eed45c6ac418e2e78937 languageName: node linkType: hard -"@red-hat-developer-hub/backstage-plugin-theme@npm:^0.9.0": - version: 0.9.1 - resolution: "@red-hat-developer-hub/backstage-plugin-theme@npm:0.9.1" +"@red-hat-developer-hub/backstage-plugin-theme@npm:^0.10.0": + version: 0.10.1 + resolution: "@red-hat-developer-hub/backstage-plugin-theme@npm:0.10.1" dependencies: "@mui/icons-material": ^5.17.1 peerDependencies: - "@backstage/core-plugin-api": ^1.10.7 - "@backstage/theme": ^0.6.6 + "@backstage/core-plugin-api": ^1.10.9 + "@backstage/theme": ^0.6.8 "@material-ui/icons": ^4.11.3 "@mui/icons-material": ^5.17.1 "@mui/material": ^5.0.0 react: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: 876923b59c7f7bd6cf56218004770dd5b9c34873ca0a04f7ae9b6b9cbe33214de9f867d27702045785bd865cdc7dee23277cb58711447b5859bd1dae1d4a66db + checksum: 29a9aee8d29b1c96d38e771f07556885ba23cbe495f14a998b15ec0cf7b7f4adc8c8e86aaf0a6f52355dfe18998322a325376d35b9b1da6466a370dcdbe9fc7b languageName: node linkType: hard @@ -14057,6 +15323,15 @@ __metadata: languageName: node linkType: hard +"@remixicon/react@npm:^4.6.0": + version: 4.6.0 + resolution: "@remixicon/react@npm:4.6.0" + peerDependencies: + react: ">=18.2.0" + checksum: 81127617eff78fb97aff01dc392ebbafb69fbfe835270b4db8ee68844d02d8c47a42d312d72104708f7266d8ad005405ea1245a536e35b66305d00d56f20b9eb + languageName: node + linkType: hard + "@rjsf/core@npm:5.23.2, @rjsf/core@npm:^5.14.3, @rjsf/core@npm:^5.21.2": version: 5.23.2 resolution: "@rjsf/core@npm:5.23.2" @@ -14101,7 +15376,22 @@ __metadata: languageName: node linkType: hard -"@rjsf/utils@npm:=5.24.12": +"@rjsf/utils@npm:5.23.2": + version: 5.23.2 + resolution: "@rjsf/utils@npm:5.23.2" + dependencies: + json-schema-merge-allof: ^0.8.1 + jsonpointer: ^5.0.1 + lodash: ^4.17.21 + lodash-es: ^4.17.21 + react-is: ^18.2.0 + peerDependencies: + react: ^16.14.0 || >=17 + checksum: 16980013258bab7accaff961c533e4bb8e3326c37a84670a7667b2a10c1ca395451eb51a6cf819ccbafb1aa8838df325ff1f314b410bb186fef98856135e1a06 + languageName: node + linkType: hard + +"@rjsf/utils@npm:^5.21.2": version: 5.24.12 resolution: "@rjsf/utils@npm:5.24.12" dependencies: @@ -14130,30 +15420,30 @@ __metadata: languageName: node linkType: hard -"@roadiehq/backstage-plugin-argo-cd-backend@npm:4.3.1, @roadiehq/backstage-plugin-argo-cd-backend@npm:^4.0.1": - version: 4.3.1 - resolution: "@roadiehq/backstage-plugin-argo-cd-backend@npm:4.3.1" +"@roadiehq/backstage-plugin-argo-cd-backend@npm:4.4.2, @roadiehq/backstage-plugin-argo-cd-backend@npm:^4.4.0": + version: 4.4.2 + resolution: "@roadiehq/backstage-plugin-argo-cd-backend@npm:4.4.2" dependencies: - "@backstage/backend-plugin-api": ^1.0.2 - "@backstage/config": ^1.3.0 + "@backstage/backend-plugin-api": ^1.4.0 + "@backstage/config": ^1.3.2 "@types/express": ^4.17.6 cross-fetch: ^3.1.4 express: ^4.17.1 express-promise-router: ^4.1.0 - checksum: d2116d05cb468da700717f2fe75ba0a36b927e71f32fa6befd0c7c0bc15a80256cd04c4fe0f6b71d32ba3263a379dfb196e7bd715a1dd8aa0494283bfdef1d29 + checksum: d7246ca647343aa6f6e90cb7de979e848f89747451e48e1ed9600642696e7cce2853c88bdd7c6e16c38b2328776c4ac97f8ca9d97c4b6ebfcb7cdbf9de96d066 languageName: node linkType: hard -"@roadiehq/backstage-plugin-datadog@npm:2.4.3": - version: 2.4.3 - resolution: "@roadiehq/backstage-plugin-datadog@npm:2.4.3" - dependencies: - "@backstage/catalog-model": ^1.7.1 - "@backstage/core-compat-api": ^0.3.3 - "@backstage/core-components": ^0.16.1 - "@backstage/core-plugin-api": ^1.10.1 - "@backstage/frontend-plugin-api": ^0.9.2 - "@backstage/plugin-catalog-react": ^1.14.2 +"@roadiehq/backstage-plugin-datadog@npm:2.5.0": + version: 2.5.0 + resolution: "@roadiehq/backstage-plugin-datadog@npm:2.5.0" + dependencies: + "@backstage/catalog-model": ^1.7.4 + "@backstage/core-compat-api": ^0.4.3 + "@backstage/core-components": ^0.17.3 + "@backstage/core-plugin-api": ^1.10.8 + "@backstage/frontend-plugin-api": ^0.10.3 + "@backstage/plugin-catalog-react": ^1.19.0 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 @@ -14164,27 +15454,27 @@ __metadata: react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 442e5a452cd7d4f03e5d709b123cce882d04939eacf3aab59ecd2957403d49a5e8d265f05e24a244befdb930a2b346dfd75be0129c2291f81f590b08bf21142c + checksum: d3d4cbcefb24793c6a213a994bc1573a764ab53ed65291bde52f721c196b4b47d87f3b254e01a22172f2aae0b5a9b130b93c31313a52c06cdc87dad9f0112c96 languageName: node linkType: hard -"@roadiehq/backstage-plugin-github-insights@npm:3.1.4": - version: 3.1.4 - resolution: "@roadiehq/backstage-plugin-github-insights@npm:3.1.4" +"@roadiehq/backstage-plugin-github-insights@npm:3.2.0": + version: 3.2.0 + resolution: "@roadiehq/backstage-plugin-github-insights@npm:3.2.0" dependencies: - "@backstage/catalog-model": ^1.7.1 - "@backstage/core-components": ^0.16.1 - "@backstage/core-plugin-api": ^1.10.1 - "@backstage/integration": ^1.16.1 - "@backstage/integration-react": ^1.2.1 - "@backstage/plugin-catalog-react": ^1.14.2 - "@backstage/theme": ^0.6.2 + "@backstage/catalog-model": ^1.7.4 + "@backstage/core-components": ^0.17.3 + "@backstage/core-plugin-api": ^1.10.8 + "@backstage/integration": ^1.17.0 + "@backstage/integration-react": ^1.2.8 + "@backstage/plugin-catalog-react": ^1.19.0 + "@backstage/theme": ^0.6.6 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.45 "@octokit/rest": ^19.0.3 "@octokit/types": ^9.0.0 - "@roadiehq/github-auth-utils-react": ^1.0.2 + "@roadiehq/github-auth-utils-react": ^1.1.0 git-url-parse: ^14.0.0 immer: 9.0.7 react-use: ^17.2.4 @@ -14193,27 +15483,27 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: 0b30a6681d12cb602168e1c1afe8b63f0170fc8648dea653dda38aa8011b0f2eacd22cee4d87d5b3a77c426ade52c36400c9e5bc79953b9b006e36ff69b227d5 + checksum: 3362897a58e0b2f801738c68a6cfed199c0c1bea58759592f2c82e740e197237ce19fcac86f808c235c8bfb00f14ea8a1214b75df6028399d57b4b6ad28be789 languageName: node linkType: hard -"@roadiehq/backstage-plugin-github-pull-requests@npm:3.4.2": - version: 3.4.2 - resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:3.4.2" +"@roadiehq/backstage-plugin-github-pull-requests@npm:3.5.2": + version: 3.5.2 + resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:3.5.2" dependencies: - "@backstage/catalog-model": ^1.7.1 - "@backstage/core-components": ^0.16.1 - "@backstage/core-plugin-api": ^1.10.1 - "@backstage/integration": ^1.16.1 - "@backstage/integration-react": ^1.2.1 - "@backstage/plugin-catalog-react": ^1.14.2 - "@backstage/plugin-home-react": ^0.1.20 + "@backstage/catalog-model": ^1.7.4 + "@backstage/core-components": ^0.17.3 + "@backstage/core-plugin-api": ^1.10.8 + "@backstage/integration": ^1.17.0 + "@backstage/integration-react": ^1.2.8 + "@backstage/plugin-catalog-react": ^1.19.0 + "@backstage/plugin-home-react": ^0.1.27 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.60 "@octokit/rest": ^19.0.3 "@octokit/types": ^9.0.0 - "@roadiehq/github-auth-utils-react": ^1.0.2 + "@roadiehq/github-auth-utils-react": ^1.1.0 git-url-parse: ^14.0.0 lodash: ^4.17.21 luxon: ^3.0.0 @@ -14223,24 +15513,24 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: 9124bea93ae7f5528bfec59a1135c1072b3a17a052d71405ca9163f72ab455766aba448e4de0e85ca179573e8c89967efec0da219bd3ae788f58a40a561d81b4 + checksum: 77a6762ab780d4f969991095031d4d4ca4d1c89e8db16ac5cbdbc14ab78de4ed8cdc26598913be73f72cbee59b9d5cf29e009d150074836030c954d3c7583f66 languageName: node linkType: hard -"@roadiehq/backstage-plugin-jira@npm:2.9.0": - version: 2.9.0 - resolution: "@roadiehq/backstage-plugin-jira@npm:2.9.0" +"@roadiehq/backstage-plugin-jira@npm:2.13.1": + version: 2.13.1 + resolution: "@roadiehq/backstage-plugin-jira@npm:2.13.1" dependencies: - "@backstage/catalog-model": ^1.7.1 - "@backstage/config": ^1.3.0 - "@backstage/core-components": ^0.16.1 - "@backstage/core-plugin-api": ^1.10.1 - "@backstage/plugin-catalog-react": ^1.14.2 - "@backstage/plugin-home-react": ^0.1.20 + "@backstage/catalog-model": ^1.7.4 + "@backstage/config": ^1.3.2 + "@backstage/core-components": ^0.17.3 + "@backstage/core-plugin-api": ^1.10.8 + "@backstage/plugin-catalog-react": ^1.19.0 + "@backstage/plugin-home-react": ^0.1.27 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 - axios: ^1.0.0 + "@types/lodash": ^4.17.16 cross-fetch: ^3.1.5 html-react-parser: ^0.14.1 lodash: ^4.17.21 @@ -14254,25 +15544,25 @@ __metadata: peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - checksum: 7e798eb3b5703a820e96c6a6cdc2e6b29cb2a245d736519329283cf1ee2c13a992bc035f1613dc1babaf95368d6b3fcb5aefcd0655d995be78c6224fc8e95f2d + checksum: 3062e9069607b30403752a90c916f5963e5733ffea3232e0595e8262864837577caea588363a8808abe1b66b319b383f914255313865d4500283eafc2479aac2 languageName: node linkType: hard -"@roadiehq/backstage-plugin-security-insights@npm:3.1.3": - version: 3.1.3 - resolution: "@roadiehq/backstage-plugin-security-insights@npm:3.1.3" +"@roadiehq/backstage-plugin-security-insights@npm:3.2.0": + version: 3.2.0 + resolution: "@roadiehq/backstage-plugin-security-insights@npm:3.2.0" dependencies: - "@backstage/catalog-model": ^1.7.1 - "@backstage/core-components": ^0.16.1 - "@backstage/core-plugin-api": ^1.10.1 - "@backstage/integration-react": ^1.2.1 - "@backstage/plugin-catalog-react": ^1.14.2 + "@backstage/catalog-model": ^1.7.4 + "@backstage/core-components": ^0.17.3 + "@backstage/core-plugin-api": ^1.10.8 + "@backstage/integration-react": ^1.2.8 + "@backstage/plugin-catalog-react": ^1.19.0 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": ^4.0.0-alpha.45 "@octokit/graphql": ^5.0.0 "@octokit/rest": ^19.0.3 - "@roadiehq/github-auth-utils-react": ^1.0.2 + "@roadiehq/github-auth-utils-react": ^1.1.0 cross-fetch: ^3.1.4 git-url-parse: ^16.0.0 luxon: ^3.0.0 @@ -14281,61 +15571,61 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: 58e9c61afd305b7f223e09132a5f39a37c9213d57f0285f0e2f44294cdc4ab8d50ce051d56487bf4a345051d0d83a655d48c41bd093a4dc27b3e59575ed2f2f5 + checksum: 337eae7b90534a9f6f1069d86d1d03196a34466d19f9b1a0690fe5c357a8bf4fcd94519528c4daa8dcb24573c0bf8f8ec43947e69bc511b28248bab187cb9d3b languageName: node linkType: hard -"@roadiehq/github-auth-utils-react@npm:^1.0.2": - version: 1.0.2 - resolution: "@roadiehq/github-auth-utils-react@npm:1.0.2" +"@roadiehq/github-auth-utils-react@npm:^1.1.0": + version: 1.1.0 + resolution: "@roadiehq/github-auth-utils-react@npm:1.1.0" dependencies: - "@backstage/core-components": ^0.16.1 - "@backstage/core-plugin-api": ^1.10.1 - "@backstage/integration-react": ^1.2.1 + "@backstage/core-components": ^0.17.3 + "@backstage/core-plugin-api": ^1.10.8 + "@backstage/integration-react": ^1.2.8 "@material-ui/core": ^4.12.2 zustand: ^4.5.6 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: 852513affd3bc245dd76bdc49df68a7b7710320cafef329d0d89ed27b5880f5f7edc87f74e76ddd411b044cd387144e2748650f47223656242bc2f6a55ac5880 + checksum: 08e44efe4ba73ead003a3a1e634d16f516a00f68c59e55d0a130928c176912ecac9a440322fcc45a0a936ff83cebddfe5f7e4a5667cedbfc8cb9c31ed243c912 languageName: node linkType: hard -"@roadiehq/scaffolder-backend-argocd@npm:1.6.0": - version: 1.6.0 - resolution: "@roadiehq/scaffolder-backend-argocd@npm:1.6.0" +"@roadiehq/scaffolder-backend-argocd@npm:1.7.1": + version: 1.7.1 + resolution: "@roadiehq/scaffolder-backend-argocd@npm:1.7.1" dependencies: "@backstage/backend-common": ^0.25.0 - "@backstage/backend-plugin-api": ^1.0.2 - "@backstage/config": ^1.3.0 - "@backstage/plugin-scaffolder-node": ^0.6.2 - "@roadiehq/backstage-plugin-argo-cd-backend": ^4.0.1 + "@backstage/backend-plugin-api": ^1.4.0 + "@backstage/config": ^1.3.2 + "@backstage/plugin-scaffolder-node": ^0.9.0 + "@roadiehq/backstage-plugin-argo-cd-backend": ^4.4.0 winston: ^3.2.1 - checksum: 7fa73382a9ba91ca53849654fee3471c35034e4f6e3baf46c28f79fb1d209a33a69cba948704a298ba91486aef7647efe88bca2451cc797941183315f6cb34ed + checksum: 089ecffd9c2ac0986d9d393bc320ca29e28ecd6817992d73ed22fd951b0c9e8639fef72bdc3813356fb97147b2874620954e9d565fc6b0515a1c899751602a24 languageName: node linkType: hard -"@roadiehq/scaffolder-backend-module-http-request@npm:5.3.3": - version: 5.3.3 - resolution: "@roadiehq/scaffolder-backend-module-http-request@npm:5.3.3" +"@roadiehq/scaffolder-backend-module-http-request@npm:5.4.2": + version: 5.4.2 + resolution: "@roadiehq/scaffolder-backend-module-http-request@npm:5.4.2" dependencies: - "@backstage/backend-plugin-api": ^1.0.2 - "@backstage/core-plugin-api": ^1.10.1 - "@backstage/plugin-scaffolder-node": ^0.6.2 + "@backstage/backend-plugin-api": ^1.4.0 + "@backstage/core-plugin-api": ^1.10.8 + "@backstage/plugin-scaffolder-node": ^0.9.0 cross-fetch: ^4.0.0 - checksum: d8928487c0fa2eb6e524cb7320c386220ced9fd0266809955c4318276c9e79155779db04c3a8e5dfb3f0c0770577f687424fa7f4d37c945a27f0f8a983bb0e1e + checksum: 1d4cb5e9f9dfc357a439e59d52b357035b654a2ad2687f1f34b816ed22eeb03f1d787c38dd8e338098093520bea041c8c2f0bf492f4f98daede2b38fb0f2c02f languageName: node linkType: hard -"@roadiehq/scaffolder-backend-module-utils@npm:3.5.0": - version: 3.5.0 - resolution: "@roadiehq/scaffolder-backend-module-utils@npm:3.5.0" +"@roadiehq/scaffolder-backend-module-utils@npm:4.0.3": + version: 4.0.3 + resolution: "@roadiehq/scaffolder-backend-module-utils@npm:4.0.3" dependencies: - "@backstage/backend-plugin-api": ^1.0.2 - "@backstage/config": ^1.3.0 - "@backstage/errors": ^1.2.5 - "@backstage/plugin-scaffolder-node": ^0.6.2 + "@backstage/backend-plugin-api": ^1.4.0 + "@backstage/config": ^1.3.2 + "@backstage/errors": ^1.2.7 + "@backstage/plugin-scaffolder-node": ^0.9.0 adm-zip: ^0.5.9 detect-indent: ^6.1.0 fast-glob: ^3.3.3 @@ -14344,7 +15634,8 @@ __metadata: lodash: ^4.17.21 yaml: ^2.6.1 yawn-yaml: ^2.3.0 - checksum: 3a3900aad1bf911fe4a95ecd6af63e09b7fd8250cdd86b10e82e9650bab3a3e4dc6f23b95234c442b9b1b7cba2049345ca64c6d4a35de376049c472c6977f66d + zod: ^3.19.1 + checksum: ebd4a4499d32008d2ae546a79084073e4d5b91cb851a309810c2e8b4ebbc88377d790d341f3f2190e0872e5c44677bdc762eedbbd60962e5dd2136f712a79c67 languageName: node linkType: hard @@ -14594,6 +15885,171 @@ __metadata: languageName: node linkType: hard +"@rspack/binding-darwin-arm64@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-darwin-arm64@npm:1.5.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rspack/binding-darwin-x64@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-darwin-x64@npm:1.5.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rspack/binding-linux-arm64-gnu@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-linux-arm64-gnu@npm:1.5.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rspack/binding-linux-arm64-musl@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-linux-arm64-musl@npm:1.5.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rspack/binding-linux-x64-gnu@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-linux-x64-gnu@npm:1.5.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rspack/binding-linux-x64-musl@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-linux-x64-musl@npm:1.5.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rspack/binding-wasm32-wasi@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-wasm32-wasi@npm:1.5.0" + dependencies: + "@napi-rs/wasm-runtime": ^1.0.1 + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@rspack/binding-win32-arm64-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-win32-arm64-msvc@npm:1.5.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rspack/binding-win32-ia32-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-win32-ia32-msvc@npm:1.5.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rspack/binding-win32-x64-msvc@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding-win32-x64-msvc@npm:1.5.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rspack/binding@npm:1.5.0": + version: 1.5.0 + resolution: "@rspack/binding@npm:1.5.0" + dependencies: + "@rspack/binding-darwin-arm64": 1.5.0 + "@rspack/binding-darwin-x64": 1.5.0 + "@rspack/binding-linux-arm64-gnu": 1.5.0 + "@rspack/binding-linux-arm64-musl": 1.5.0 + "@rspack/binding-linux-x64-gnu": 1.5.0 + "@rspack/binding-linux-x64-musl": 1.5.0 + "@rspack/binding-wasm32-wasi": 1.5.0 + "@rspack/binding-win32-arm64-msvc": 1.5.0 + "@rspack/binding-win32-ia32-msvc": 1.5.0 + "@rspack/binding-win32-x64-msvc": 1.5.0 + dependenciesMeta: + "@rspack/binding-darwin-arm64": + optional: true + "@rspack/binding-darwin-x64": + optional: true + "@rspack/binding-linux-arm64-gnu": + optional: true + "@rspack/binding-linux-arm64-musl": + optional: true + "@rspack/binding-linux-x64-gnu": + optional: true + "@rspack/binding-linux-x64-musl": + optional: true + "@rspack/binding-wasm32-wasi": + optional: true + "@rspack/binding-win32-arm64-msvc": + optional: true + "@rspack/binding-win32-ia32-msvc": + optional: true + "@rspack/binding-win32-x64-msvc": + optional: true + checksum: eca6db571b6faaf0feaf8b88ecd1e4f8418bbc5889626719e79f6ea2b05e66a61feb7c758f9381bc22e8544dd3237eeea4d3d1b1474398796ab8932519a85ee0 + languageName: node + linkType: hard + +"@rspack/core@npm:^1.4.11": + version: 1.5.0 + resolution: "@rspack/core@npm:1.5.0" + dependencies: + "@module-federation/runtime-tools": 0.18.0 + "@rspack/binding": 1.5.0 + "@rspack/lite-tapable": 1.0.1 + peerDependencies: + "@swc/helpers": ">=0.5.1" + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: a9b8e78e07f25217b68ccbf98bdf8a703580dea8130ce321e53c6c233d4a40109f305d7b6b908669f68d16cc17f3f1cde5033d27e79eb5caf9ce581fdfc0dcfc + languageName: node + linkType: hard + +"@rspack/dev-server@npm:^1.1.4": + version: 1.1.4 + resolution: "@rspack/dev-server@npm:1.1.4" + dependencies: + chokidar: ^3.6.0 + http-proxy-middleware: ^2.0.9 + p-retry: ^6.2.0 + webpack-dev-server: 5.2.2 + ws: ^8.18.0 + peerDependencies: + "@rspack/core": "*" + checksum: 28e1ee041a88d432df2a29b30d022e78ce32ede5f2b0ce5347b35e6a57fa0351f4f9a17c8e49e3e44c26972e9478157541d1b77cfce0ec81759ebcf31e4d2ad0 + languageName: node + linkType: hard + +"@rspack/lite-tapable@npm:1.0.1, @rspack/lite-tapable@npm:^1.0.1": + version: 1.0.1 + resolution: "@rspack/lite-tapable@npm:1.0.1" + checksum: a490aa7868178e7277573293a2b81191513d451c72f4118173f080b5c65a19618e1d37083cffa049b563433a3f772ab2f4424c0a920b04b1347ddb12fe3bcbf8 + languageName: node + linkType: hard + +"@rspack/plugin-react-refresh@npm:^1.4.3": + version: 1.4.3 + resolution: "@rspack/plugin-react-refresh@npm:1.4.3" + dependencies: + error-stack-parser: ^2.1.4 + html-entities: ^2.6.0 + peerDependencies: + react-refresh: ">=0.10.0 <1.0.0" + webpack-hot-middleware: 2.x + peerDependenciesMeta: + webpack-hot-middleware: + optional: true + checksum: d8fda18c9a55ab9f32a182fbf8ebabf85c329a3a33be226cb1149b97ecaf45795d30ef67ce190532e2dd966a25efde9a86541eaa724c39611d4ed74320e727cc + languageName: node + linkType: hard + "@rtsao/scc@npm:^1.1.0": version: 1.1.0 resolution: "@rtsao/scc@npm:1.1.0" @@ -15822,13 +17278,6 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:5.62.16": - version: 5.62.16 - resolution: "@tanstack/query-core@npm:5.62.16" - checksum: 96e712dba70b9234884108ecac2fa05ae588f7a1758377d80aa30d4e830f00cbef95309d2806828ca224d1db51e3c8364857a6f3581edb989f2f16cb98ad0f26 - languageName: node - linkType: hard - "@tanstack/query-core@npm:5.80.10": version: 5.80.10 resolution: "@tanstack/query-core@npm:5.80.10" @@ -15855,18 +17304,7 @@ __metadata: languageName: node linkType: hard -"@tanstack/react-query@npm:^5.40.1, @tanstack/react-query@npm:^5.60.5": - version: 5.62.16 - resolution: "@tanstack/react-query@npm:5.62.16" - dependencies: - "@tanstack/query-core": 5.62.16 - peerDependencies: - react: ^18 || ^19 - checksum: dbf9cf549799d96ecefea237617e15234d9fa446460efe5286e128840b1bcfff5d7ff8a9eb9208aefe469800b50fa2ad31d93e631be3e0a58baac61a3094fb33 - languageName: node - linkType: hard - -"@tanstack/react-query@npm:^5.62.7": +"@tanstack/react-query@npm:^5.40.1, @tanstack/react-query@npm:^5.60.5, @tanstack/react-query@npm:^5.62.7": version: 5.80.10 resolution: "@tanstack/react-query@npm:5.80.10" dependencies: @@ -15889,6 +17327,18 @@ __metadata: languageName: node linkType: hard +"@tanstack/react-table@npm:^8.21.3": + version: 8.21.3 + resolution: "@tanstack/react-table@npm:8.21.3" + dependencies: + "@tanstack/table-core": 8.21.3 + peerDependencies: + react: ">=16.8" + react-dom: ">=16.8" + checksum: 1452e7bd1dd0febbfc37e656c61c2c426dc243136333a8688bfadfccfec233e87c9bbe83011d742b0e86ae52c9b3d436bdc5618be4ac675ab921f52317317780 + languageName: node + linkType: hard + "@tanstack/react-virtual@npm:3.3.0": version: 3.3.0 resolution: "@tanstack/react-virtual@npm:3.3.0" @@ -15908,6 +17358,13 @@ __metadata: languageName: node linkType: hard +"@tanstack/table-core@npm:8.21.3": + version: 8.21.3 + resolution: "@tanstack/table-core@npm:8.21.3" + checksum: ce260ab981f334ba999240cf68ae942a524a28980f6853275da90d1864a8b56fa59b952bfd2266570f36ae11f66476d1c96dacc640ba5fd9d6d4e2a78cf05187 + languageName: node + linkType: hard + "@tanstack/virtual-core@npm:3.3.0": version: 3.3.0 resolution: "@tanstack/virtual-core@npm:3.3.0" @@ -16014,6 +17471,15 @@ __metadata: languageName: node linkType: hard +"@tybys/wasm-util@npm:^0.10.0": + version: 0.10.0 + resolution: "@tybys/wasm-util@npm:0.10.0" + dependencies: + tslib: ^2.4.0 + checksum: c3034e0535b91f28dc74c72fc538f353cda0fa9107bb313e8b89f101402b7dc8e400442d07560775cdd7cb63d33549867ed776372fbaa41dc68bcd108e5cff8a + languageName: node + linkType: hard + "@types/aws-lambda@npm:^8.10.83": version: 8.10.147 resolution: "@types/aws-lambda@npm:8.10.147" @@ -16495,15 +17961,15 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33, @types/express-serve-static-core@npm:^4.17.5": - version: 4.17.43 - resolution: "@types/express-serve-static-core@npm:4.17.43" +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.21, @types/express-serve-static-core@npm:^4.17.33, @types/express-serve-static-core@npm:^4.17.5": + version: 4.19.6 + resolution: "@types/express-serve-static-core@npm:4.19.6" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: 08e940cae52eb1388a7b5f61d65f028e783add77d1854243ae920a6a2dfb5febb6acaafbcf38be9d678b0411253b9bc325893c463a93302405f24135664ab1e4 + checksum: b0576eddc2d25ccdf10e68ba09598b87a4d7b2ad04a81dc847cb39fe56beb0b6a5cc017b1e00aa0060cb3b38e700384ce96d291a116a0f1e54895564a104aae9 languageName: node linkType: hard @@ -16705,10 +18171,10 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:^4.14.175": - version: 4.14.202 - resolution: "@types/lodash@npm:4.14.202" - checksum: a91acf3564a568c6f199912f3eb2c76c99c5a0d7e219394294213b3f2d54f672619f0fde4da22b29dc5d4c31457cd799acc2e5cb6bd90f9af04a1578483b6ff7 +"@types/lodash@npm:^4.14.175, @types/lodash@npm:^4.17.16": + version: 4.17.20 + resolution: "@types/lodash@npm:4.17.20" + checksum: dc7bb4653514dd91117a4c4cec2c37e2b5a163d7643445e4757d76a360fabe064422ec7a42dde7450c5e7e0e7e678d5e6eae6d2a919abcddf581d81e63e63839 languageName: node linkType: hard @@ -16864,10 +18330,10 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.12, @types/prop-types@npm:^15.7.14, @types/prop-types@npm:^15.7.3": - version: 15.7.14 - resolution: "@types/prop-types@npm:15.7.14" - checksum: d0c5407b9ccc3dd5fae0ccf9b1007e7622ba5e6f1c18399b4f24dff33619d469da4b9fa918a374f19dc0d9fe6a013362aab0b844b606cfc10676efba3f5f736d +"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.12, @types/prop-types@npm:^15.7.14, @types/prop-types@npm:^15.7.15, @types/prop-types@npm:^15.7.3": + version: 15.7.15 + resolution: "@types/prop-types@npm:15.7.15" + checksum: 31aa2f59b28f24da6fb4f1d70807dae2aedfce090ec63eaf9ea01727a9533ef6eaf017de5bff99fbccad7d1c9e644f52c6c2ba30869465dd22b1a7221c29f356 languageName: node linkType: hard @@ -16915,16 +18381,7 @@ __metadata: languageName: node linkType: hard -"@types/react-transition-group@npm:^4.2.0, @types/react-transition-group@npm:^4.4.10": - version: 4.4.10 - resolution: "@types/react-transition-group@npm:4.4.10" - dependencies: - "@types/react": "*" - checksum: fe2ea11f70251e9f79f368e198c18fd469b1d4f1e1d44e4365845b44e15974b0ec925100036f449b023b0ca3480a82725c5f0a73040e282ad32ec7b0def9b57c - languageName: node - linkType: hard - -"@types/react-transition-group@npm:^4.4.5": +"@types/react-transition-group@npm:^4.2.0, @types/react-transition-group@npm:^4.4.10, @types/react-transition-group@npm:^4.4.12, @types/react-transition-group@npm:^4.4.5, @types/react-transition-group@npm:^4.4.8": version: 4.4.12 resolution: "@types/react-transition-group@npm:4.4.12" peerDependencies: @@ -17089,6 +18546,13 @@ __metadata: languageName: node linkType: hard +"@types/trusted-types@npm:^1.0.6": + version: 1.0.6 + resolution: "@types/trusted-types@npm:1.0.6" + checksum: 22b8efcb6116ab80d07542047135618ee282f2060c481e472126604d838c09e7dad33c9462d88c130aef2c3133aece516f00d6af7ff814f0612f7d19db720e6d + languageName: node + linkType: hard + "@types/trusted-types@npm:^2.0.7": version: 2.0.7 resolution: "@types/trusted-types@npm:2.0.7" @@ -17126,6 +18590,13 @@ __metadata: languageName: node linkType: hard +"@types/use-sync-external-store@npm:^0.0.3": + version: 0.0.3 + resolution: "@types/use-sync-external-store@npm:0.0.3" + checksum: 161ddb8eec5dbe7279ac971531217e9af6b99f7783213566d2b502e2e2378ea19cf5e5ea4595039d730aa79d3d35c6567d48599f69773a02ffcff1776ec2a44e + languageName: node + linkType: hard + "@types/webpack-env@npm:^1.15.2": version: 1.18.4 resolution: "@types/webpack-env@npm:1.18.4" @@ -18553,13 +20024,13 @@ __metadata: linkType: hard "axios@npm:^1.0.0, axios@npm:^1.6.7, axios@npm:^1.7.4": - version: 1.8.4 - resolution: "axios@npm:1.8.4" + version: 1.12.2 + resolution: "axios@npm:1.12.2" dependencies: follow-redirects: ^1.15.6 - form-data: ^4.0.0 + form-data: ^4.0.4 proxy-from-env: ^1.1.0 - checksum: e901dc1730bdcd769839b3d93ae6d6457a53d79b19a0eb623ebfea333441259ab51e63ca118baa47a5156567401466ac739f31087b4ee5e6770ab2e227484538 + checksum: f0331594fe053a4bbff04104edb073973a3aabfad2e56b0aa18de82428aa63f6f0839ca3d837258ec739cb4528014121793b1649a21e5115ffb2bf8237eadca3 languageName: node linkType: hard @@ -18761,10 +20232,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-3scale-backend@workspace:wrappers/backstage-community-plugin-3scale-backend-dynamic" dependencies: - "@backstage-community/plugin-3scale-backend": 3.6.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-3scale-backend": 3.8.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18772,13 +20243,13 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-acr@workspace:wrappers/backstage-community-plugin-acr" dependencies: - "@backstage-community/plugin-acr": 1.15.1 - "@backstage/cli": 0.30.0 - "@backstage/core-plugin-api": 1.10.7 + "@backstage-community/plugin-acr": 1.17.0 + "@backstage/cli": ^0.34.1 + "@backstage/core-plugin-api": 1.10.9 "@janus-idp/cli": 3.6.1 "@mui/icons-material": 5.18.0 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18786,10 +20257,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-analytics-provider-segment@workspace:wrappers/backstage-community-plugin-analytics-provider-segment" dependencies: - "@backstage-community/plugin-analytics-provider-segment": 1.16.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-analytics-provider-segment": 1.18.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18797,10 +20268,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-azure-devops-backend@workspace:wrappers/backstage-community-plugin-azure-devops-backend-dynamic" dependencies: - "@backstage-community/plugin-azure-devops-backend": 0.17.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-azure-devops-backend": 0.19.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18808,10 +20279,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-azure-devops@workspace:wrappers/backstage-community-plugin-azure-devops" dependencies: - "@backstage-community/plugin-azure-devops": 0.16.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-azure-devops": 0.18.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18819,10 +20290,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-catalog-backend-module-keycloak@workspace:wrappers/backstage-community-plugin-catalog-backend-module-keycloak-dynamic" dependencies: - "@backstage-community/plugin-catalog-backend-module-keycloak": 3.12.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-catalog-backend-module-keycloak": 3.14.2 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18830,10 +20301,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-catalog-backend-module-pingidentity@workspace:wrappers/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic" dependencies: - "@backstage-community/plugin-catalog-backend-module-pingidentity": 0.5.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-catalog-backend-module-pingidentity": 0.7.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18841,10 +20312,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor@workspace:wrappers/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic" dependencies: - "@backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor": 2.5.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-catalog-backend-module-scaffolder-relation-processor": 2.8.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18852,10 +20323,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-dynatrace@workspace:wrappers/backstage-community-plugin-dynatrace" dependencies: - "@backstage-community/plugin-dynatrace": 10.6.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-dynatrace": 10.8.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18863,10 +20334,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-github-actions@workspace:wrappers/backstage-community-plugin-github-actions" dependencies: - "@backstage-community/plugin-github-actions": 0.11.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-github-actions": 0.14.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18874,10 +20345,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-github-issues@workspace:wrappers/backstage-community-plugin-github-issues" dependencies: - "@backstage-community/plugin-github-issues": 0.10.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-github-issues": 0.13.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18885,10 +20356,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-jenkins-backend@workspace:wrappers/backstage-community-plugin-jenkins-backend-dynamic" dependencies: - "@backstage-community/plugin-jenkins-backend": 0.15.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-jenkins-backend": 0.17.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18896,10 +20367,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-jenkins@workspace:wrappers/backstage-community-plugin-jenkins" dependencies: - "@backstage-community/plugin-jenkins": 0.20.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-jenkins": 0.22.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18907,11 +20378,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-jfrog-artifactory@workspace:wrappers/backstage-community-plugin-jfrog-artifactory" dependencies: - "@backstage-community/plugin-jfrog-artifactory": 1.15.3 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-jfrog-artifactory": 1.18.2 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18919,11 +20390,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-lighthouse@workspace:wrappers/backstage-community-plugin-lighthouse" dependencies: - "@backstage-community/plugin-lighthouse": 0.10.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-lighthouse": 0.12.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/icons-material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18931,11 +20402,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-nexus-repository-manager@workspace:wrappers/backstage-community-plugin-nexus-repository-manager" dependencies: - "@backstage-community/plugin-nexus-repository-manager": 1.14.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-nexus-repository-manager": 1.16.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18943,10 +20414,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-ocm-backend@workspace:wrappers/backstage-community-plugin-ocm-backend-dynamic" dependencies: - "@backstage-community/plugin-ocm-backend": 5.7.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-ocm-backend": 5.9.1 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18954,11 +20425,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-ocm@workspace:wrappers/backstage-community-plugin-ocm" dependencies: - "@backstage-community/plugin-ocm": 5.6.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-ocm": 5.8.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18966,11 +20437,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-quay@workspace:wrappers/backstage-community-plugin-quay" dependencies: - "@backstage-community/plugin-quay": 1.21.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-quay": 1.24.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18978,11 +20449,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-rbac@workspace:wrappers/backstage-community-plugin-rbac" dependencies: - "@backstage-community/plugin-rbac": 1.42.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-rbac": 1.45.1 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -18990,11 +20461,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-redhat-argocd@workspace:wrappers/backstage-community-plugin-redhat-argocd" dependencies: - "@backstage-community/plugin-redhat-argocd": 1.21.2 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-redhat-argocd": 2.0.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19002,10 +20473,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-scaffolder-backend-module-kubernetes@workspace:wrappers/backstage-community-plugin-scaffolder-backend-module-kubernetes-dynamic" dependencies: - "@backstage-community/plugin-scaffolder-backend-module-kubernetes": 2.8.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-scaffolder-backend-module-kubernetes": 2.10.1 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19013,10 +20484,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-scaffolder-backend-module-quay@workspace:wrappers/backstage-community-plugin-scaffolder-backend-module-quay-dynamic" dependencies: - "@backstage-community/plugin-scaffolder-backend-module-quay": 2.9.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-scaffolder-backend-module-quay": 2.11.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19024,10 +20495,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-scaffolder-backend-module-regex@workspace:wrappers/backstage-community-plugin-scaffolder-backend-module-regex-dynamic" dependencies: - "@backstage-community/plugin-scaffolder-backend-module-regex": 2.7.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-scaffolder-backend-module-regex": 2.8.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19035,10 +20506,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-scaffolder-backend-module-servicenow@workspace:wrappers/backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic" dependencies: - "@backstage-community/plugin-scaffolder-backend-module-servicenow": 2.7.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-scaffolder-backend-module-servicenow": 2.8.1 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19046,10 +20517,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-scaffolder-backend-module-sonarqube@workspace:wrappers/backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic" dependencies: - "@backstage-community/plugin-scaffolder-backend-module-sonarqube": 2.7.1 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-scaffolder-backend-module-sonarqube": 2.8.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19057,10 +20528,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-sonarqube-backend@workspace:wrappers/backstage-community-plugin-sonarqube-backend-dynamic" dependencies: - "@backstage-community/plugin-sonarqube-backend": 0.9.2 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-sonarqube-backend": 0.12.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19068,10 +20539,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-sonarqube@workspace:wrappers/backstage-community-plugin-sonarqube" dependencies: - "@backstage-community/plugin-sonarqube": 0.13.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-sonarqube": 0.18.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19079,10 +20550,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-tech-radar-backend@workspace:wrappers/backstage-community-plugin-tech-radar-backend-dynamic" dependencies: - "@backstage-community/plugin-tech-radar-backend": 1.6.0 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-tech-radar-backend": 1.9.1 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19090,13 +20561,13 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-tech-radar@workspace:wrappers/backstage-community-plugin-tech-radar" dependencies: - "@backstage-community/plugin-tech-radar": 1.7.0 - "@backstage-community/plugin-tech-radar-common": 1.6.0 - "@backstage/cli": 0.30.0 - "@backstage/core-plugin-api": 1.10.7 + "@backstage-community/plugin-tech-radar": 1.11.0 + "@backstage-community/plugin-tech-radar-common": 1.10.0 + "@backstage/cli": ^0.34.1 + "@backstage/core-plugin-api": 1.10.9 "@janus-idp/cli": 3.6.1 "@mui/icons-material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19104,11 +20575,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-tekton@workspace:wrappers/backstage-community-plugin-tekton" dependencies: - "@backstage-community/plugin-tekton": 3.26.2 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-tekton": 3.29.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19116,11 +20587,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-community-plugin-topology@workspace:wrappers/backstage-community-plugin-topology" dependencies: - "@backstage-community/plugin-topology": 2.2.2 - "@backstage/cli": 0.30.0 + "@backstage-community/plugin-topology": 2.7.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19128,10 +20599,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-catalog-backend-module-bitbucket-cloud@workspace:wrappers/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": 0.4.8 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": 0.5.2 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19139,10 +20610,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-catalog-backend-module-bitbucket-server@workspace:wrappers/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-catalog-backend-module-bitbucket-server": 0.4.1 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-catalog-backend-module-bitbucket-server": 0.5.2 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19150,11 +20621,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-catalog-backend-module-github-org@workspace:wrappers/backstage-plugin-catalog-backend-module-github-org-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-catalog-backend-module-github": 0.9.0 - "@backstage/plugin-catalog-backend-module-github-org": 0.3.10 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-catalog-backend-module-github": 0.10.2 + "@backstage/plugin-catalog-backend-module-github-org": 0.3.13 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19162,10 +20633,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-catalog-backend-module-github@workspace:wrappers/backstage-plugin-catalog-backend-module-github-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-catalog-backend-module-github": 0.9.0 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-catalog-backend-module-github": 0.10.2 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19173,11 +20644,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-catalog-backend-module-gitlab-org@workspace:wrappers/backstage-plugin-catalog-backend-module-gitlab-org-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-catalog-backend-module-gitlab": 0.6.6 - "@backstage/plugin-catalog-backend-module-gitlab-org": 0.2.9 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-catalog-backend-module-gitlab": 0.7.2 + "@backstage/plugin-catalog-backend-module-gitlab-org": 0.2.12 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19185,10 +20656,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-catalog-backend-module-gitlab@workspace:wrappers/backstage-plugin-catalog-backend-module-gitlab-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-catalog-backend-module-gitlab": 0.6.6 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-catalog-backend-module-gitlab": 0.7.2 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19196,10 +20667,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-catalog-backend-module-ldap@workspace:wrappers/backstage-plugin-catalog-backend-module-ldap-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-catalog-backend-module-ldap": 0.11.5 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-catalog-backend-module-ldap": 0.11.8 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19207,10 +20678,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-catalog-backend-module-msgraph@workspace:wrappers/backstage-plugin-catalog-backend-module-msgraph-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-catalog-backend-module-msgraph": 0.7.0 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-catalog-backend-module-msgraph": 0.7.3 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19218,10 +20689,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-kubernetes-backend@workspace:wrappers/backstage-plugin-kubernetes-backend-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-kubernetes-backend": 0.19.6 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-kubernetes-backend": 0.20.1 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19229,11 +20700,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-kubernetes@workspace:wrappers/backstage-plugin-kubernetes" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/core-plugin-api": 1.10.7 - "@backstage/plugin-kubernetes": 0.12.7 + "@backstage/cli": ^0.34.1 + "@backstage/core-plugin-api": 1.10.9 + "@backstage/plugin-kubernetes": 0.12.10 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19241,10 +20712,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-notifications-backend-module-email@workspace:wrappers/backstage-plugin-notifications-backend-module-email-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-notifications-backend-module-email": 0.3.9 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-notifications-backend-module-email": 0.3.12 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19252,11 +20723,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-notifications-backend@workspace:wrappers/backstage-plugin-notifications-backend-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-notifications-backend": 0.5.6 - "@backstage/plugin-signals-node": 0.1.20 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-notifications-backend": 0.5.9 + "@backstage/plugin-signals-node": 0.1.23 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19264,11 +20735,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-notifications@workspace:wrappers/backstage-plugin-notifications" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-notifications": 0.5.5 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-notifications": 0.5.9 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19276,10 +20747,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-scaffolder-backend-module-azure@workspace:wrappers/backstage-plugin-scaffolder-backend-module-azure-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-scaffolder-backend-module-azure": 0.2.9 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-scaffolder-backend-module-azure": 0.2.12 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19287,10 +20758,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-scaffolder-backend-module-bitbucket-cloud@workspace:wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": 0.2.9 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": 0.2.12 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19298,10 +20769,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-scaffolder-backend-module-bitbucket-server@workspace:wrappers/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-scaffolder-backend-module-bitbucket-server": 0.2.9 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-scaffolder-backend-module-bitbucket-server": 0.2.12 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19309,10 +20780,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-scaffolder-backend-module-gerrit@workspace:wrappers/backstage-plugin-scaffolder-backend-module-gerrit-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-scaffolder-backend-module-gerrit": 0.2.9 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-scaffolder-backend-module-gerrit": 0.2.12 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19320,10 +20791,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-scaffolder-backend-module-github@workspace:wrappers/backstage-plugin-scaffolder-backend-module-github-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-scaffolder-backend-module-github": 0.7.1 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-scaffolder-backend-module-github": 0.8.2 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19331,10 +20802,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-scaffolder-backend-module-gitlab@workspace:wrappers/backstage-plugin-scaffolder-backend-module-gitlab-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-scaffolder-backend-module-gitlab": 0.9.1 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-scaffolder-backend-module-gitlab": 0.9.4 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19342,10 +20813,10 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-signals-backend@workspace:wrappers/backstage-plugin-signals-backend-dynamic" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-signals-backend": 0.3.4 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-signals-backend": 0.3.7 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19353,11 +20824,11 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-signals@workspace:wrappers/backstage-plugin-signals" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-signals": 0.0.19 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-signals": 0.0.22 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19365,12 +20836,12 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-techdocs-backend@workspace:wrappers/backstage-plugin-techdocs-backend-dynamic" dependencies: - "@backstage/backend-plugin-api": 1.3.1 - "@backstage/cli": 0.30.0 - "@backstage/plugin-search-backend-module-techdocs": 0.4.2 - "@backstage/plugin-techdocs-backend": 2.0.2 + "@backstage/backend-plugin-api": 1.4.2 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-search-backend-module-techdocs": 0.4.5 + "@backstage/plugin-techdocs-backend": 2.0.5 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -19378,14 +20849,14 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-techdocs-module-addons-contrib@workspace:wrappers/backstage-plugin-techdocs-module-addons-contrib" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/plugin-techdocs-module-addons-contrib": 1.1.24 - "@backstage/plugin-techdocs-react": 1.2.17 + "@backstage/cli": ^0.34.1 + "@backstage/plugin-techdocs-module-addons-contrib": 1.1.27 + "@backstage/plugin-techdocs-react": 1.3.2 "@janus-idp/cli": 3.6.1 "@material-ui/core": 4.12.4 jss: 10.10.0 react: 18.3.1 - typescript: 5.8.3 + typescript: 5.9.3 peerDependencies: react: 16.13.1 || ^17.0.0 || ^18.0.0 languageName: unknown @@ -19395,15 +20866,15 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-plugin-techdocs@workspace:wrappers/backstage-plugin-techdocs" dependencies: - "@backstage/cli": 0.30.0 - "@backstage/core-plugin-api": 1.10.7 - "@backstage/plugin-catalog-react": 1.18.0 - "@backstage/plugin-search-react": 1.9.0 - "@backstage/plugin-techdocs": 1.12.6 - "@backstage/plugin-techdocs-react": 1.2.17 + "@backstage/cli": ^0.34.1 + "@backstage/core-plugin-api": 1.10.9 + "@backstage/plugin-catalog-react": 1.20.1 + "@backstage/plugin-search-react": 1.9.3 + "@backstage/plugin-techdocs": 1.14.1 + "@backstage/plugin-techdocs-react": 1.3.2 "@janus-idp/cli": 3.6.1 react: 18.3.1 - typescript: 5.8.3 + typescript: 5.9.3 peerDependencies: react: 16.13.1 || ^17.0.0 || ^18.0.0 languageName: unknown @@ -19508,6 +20979,17 @@ __metadata: languageName: node linkType: hard +"better-sqlite3@npm:^12.0.0": + version: 12.2.0 + resolution: "better-sqlite3@npm:12.2.0" + dependencies: + bindings: ^1.5.0 + node-gyp: latest + prebuild-install: ^7.1.1 + checksum: b752119ea306c5a70d5bacdf5607fd69b39142b7c8c30d72f530047fedad0b651195b37e8a8067f106d3c56d6913dc0077f1d658916f07bcdad6841384d2bb1b + languageName: node + linkType: hard + "bfj@npm:^8.0.0": version: 8.0.0 resolution: "bfj@npm:8.0.0" @@ -19589,14 +21071,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": - version: 4.12.0 - resolution: "bn.js@npm:4.12.0" - checksum: 39afb4f15f4ea537b55eaf1446c896af28ac948fdcf47171961475724d1bb65118cca49fa6e3d67706e4790955ec0e74de584e45c8f1ef89f46c812bee5b5a12 - languageName: node - linkType: hard - -"bn.js@npm:^4.11.8": +"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.8, bn.js@npm:^4.11.9": version: 4.12.2 resolution: "bn.js@npm:4.12.2" checksum: dd224afda6f5a7d15f2fe5154e1a1c245576a725584ea1852c8c42f9748dfe847bc63a48b2885360023389a24cfebb3653ca97f4c69742f3c22bc63da6565030 @@ -19874,6 +21349,15 @@ __metadata: languageName: node linkType: hard +"buffer-xor@npm:^2.0.2": + version: 2.0.2 + resolution: "buffer-xor@npm:2.0.2" + dependencies: + safe-buffer: ^5.1.1 + checksum: 78226fcae9f4a0b4adec69dffc049f26f6bab240dfdd1b3f6fe07c4eb6b90da202ea5c363f98af676156ee39450a06405fddd9e8965f68a5327edcc89dcbe5d0 + languageName: node + linkType: hard + "buffer@npm:5.6.0": version: 5.6.0 resolution: "buffer@npm:5.6.0" @@ -20294,12 +21778,12 @@ __metadata: linkType: hard "cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": - version: 1.0.4 - resolution: "cipher-base@npm:1.0.4" + version: 1.0.6 + resolution: "cipher-base@npm:1.0.6" dependencies: - inherits: ^2.0.1 - safe-buffer: ^5.0.1 - checksum: 47d3568dbc17431a339bad1fe7dff83ac0891be8206911ace3d3b818fc695f376df809bea406e759cdea07fff4b454fa25f1013e648851bec790c1d75763032e + inherits: ^2.0.4 + safe-buffer: ^5.2.1 + checksum: 64a1738a8583163cf096bc85321a69ef3075bb0873f34cf89dc705e62b9eee058dd6b2e5c672f774ede0b6bdbe56fe7b710e0d38c4f08a2f355d8ab828f05c6f languageName: node linkType: hard @@ -21199,7 +22683,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -21230,7 +22714,7 @@ __metadata: languageName: node linkType: hard -"css-box-model@npm:^1.2.0": +"css-box-model@npm:^1.2.0, css-box-model@npm:^1.2.1": version: 1.2.1 resolution: "css-box-model@npm:1.2.1" dependencies: @@ -21900,12 +23384,12 @@ __metadata: languageName: node linkType: hard -"date-fns-tz@npm:1.3.7": - version: 1.3.7 - resolution: "date-fns-tz@npm:1.3.7" +"date-fns-tz@npm:1.3.8": + version: 1.3.8 + resolution: "date-fns-tz@npm:1.3.8" peerDependencies: date-fns: ">=2.0.0" - checksum: b749613669223056d5e6d715114c94bec57234b676d0cea0c72ca710626c81e9ea04df6441852a5fec74b42c5f27b2f076e13697ec43da360b67806a3042a10e + checksum: dbf17cb88de7c7b71a9f86b815ac62ebdbf725c030e78d2421309456b5001a85284a5b6763f4af0ba660183f12e876c165e725a0723f642edb7846407db03133 languageName: node linkType: hard @@ -21918,6 +23402,13 @@ __metadata: languageName: node linkType: hard +"date-fns@npm:^3.2.0": + version: 3.6.0 + resolution: "date-fns@npm:3.6.0" + checksum: 0daa1e9a436cf99f9f2ae9232b55e11f3dd46132bee10987164f3eebd29f245b2e066d7d7db40782627411ecf18551d8f4c9fcdf2226e48bb66545407d448ab7 + languageName: node + linkType: hard + "date-format@npm:^4.0.14": version: 4.0.14 resolution: "date-format@npm:4.0.14" @@ -21939,7 +23430,7 @@ __metadata: languageName: node linkType: hard -"debounce@npm:^1.2.0": +"debounce@npm:^1.2.0, debounce@npm:^1.2.1": version: 1.2.1 resolution: "debounce@npm:1.2.1" checksum: 682a89506d9e54fb109526f4da255c5546102fbb8e3ae75eef3b04effaf5d4853756aee97475cd4650641869794e44f410eeb20ace2b18ea592287ab2038519e @@ -22048,6 +23539,15 @@ __metadata: languageName: node linkType: hard +"deep-eql@npm:^4.1.1": + version: 4.1.4 + resolution: "deep-eql@npm:4.1.4" + dependencies: + type-detect: ^4.0.0 + checksum: 01c3ca78ff40d79003621b157054871411f94228ceb9b2cab78da913c606631c46e8aa79efc4aa0faf3ace3092acd5221255aab3ef0e8e7b438834f0ca9a16c7 + languageName: node + linkType: hard + "deep-equal@npm:~1.0.1": version: 1.0.1 resolution: "deep-equal@npm:1.0.1" @@ -22109,6 +23609,15 @@ __metadata: languageName: node linkType: hard +"default-user-agent@npm:^1.0.0": + version: 1.0.0 + resolution: "default-user-agent@npm:1.0.0" + dependencies: + os-name: ~1.0.3 + checksum: b1ef07c8e7de846a66e1e120d7ba11969faa36c8db4af2317f9b64d30e7507d129e3f721c7cc3f531a1719c1ab463d830bf426fbcda87b11defe23689f4d2b60 + languageName: node + linkType: hard + "defaults@npm:^1.0.3": version: 1.0.4 resolution: "defaults@npm:1.0.4" @@ -22361,6 +23870,13 @@ __metadata: languageName: node linkType: hard +"digest-header@npm:^1.0.0": + version: 1.1.0 + resolution: "digest-header@npm:1.1.0" + checksum: fadbdda75e1cc650e460c8fe2064f74c43cc005d0eab66cc390dd1ae2678cfb41f69f151323fbd3e059e28c941f1b9adc6ea4dbd9c918cb246f34a5eb8e103f0 + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -22671,7 +24187,8 @@ __metadata: version: 0.0.0-use.local resolution: "dynamic-plugins-root@workspace:." dependencies: - turbo: 2.5.4 + "@backstage/cli": ^0.34.1 + turbo: 2.5.8 languageName: unknown linkType: soft @@ -22679,9 +24196,9 @@ __metadata: version: 0.0.0-use.local resolution: "dynamic-plugins-utils@workspace:_utils" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 glob: 11.0.3 - yaml: 2.8.0 + yaml: 2.8.1 languageName: unknown linkType: soft @@ -22875,7 +24392,7 @@ __metadata: languageName: node linkType: hard -"error-stack-parser@npm:^2.0.6": +"error-stack-parser@npm:^2.0.6, error-stack-parser@npm:^2.1.4": version: 2.1.4 resolution: "error-stack-parser@npm:2.1.4" dependencies: @@ -23393,34 +24910,36 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.24.0": - version: 0.24.0 - resolution: "esbuild@npm:0.24.0" - dependencies: - "@esbuild/aix-ppc64": 0.24.0 - "@esbuild/android-arm": 0.24.0 - "@esbuild/android-arm64": 0.24.0 - "@esbuild/android-x64": 0.24.0 - "@esbuild/darwin-arm64": 0.24.0 - "@esbuild/darwin-x64": 0.24.0 - "@esbuild/freebsd-arm64": 0.24.0 - "@esbuild/freebsd-x64": 0.24.0 - "@esbuild/linux-arm": 0.24.0 - "@esbuild/linux-arm64": 0.24.0 - "@esbuild/linux-ia32": 0.24.0 - "@esbuild/linux-loong64": 0.24.0 - "@esbuild/linux-mips64el": 0.24.0 - "@esbuild/linux-ppc64": 0.24.0 - "@esbuild/linux-riscv64": 0.24.0 - "@esbuild/linux-s390x": 0.24.0 - "@esbuild/linux-x64": 0.24.0 - "@esbuild/netbsd-x64": 0.24.0 - "@esbuild/openbsd-arm64": 0.24.0 - "@esbuild/openbsd-x64": 0.24.0 - "@esbuild/sunos-x64": 0.24.0 - "@esbuild/win32-arm64": 0.24.0 - "@esbuild/win32-ia32": 0.24.0 - "@esbuild/win32-x64": 0.24.0 +"esbuild@npm:^0.25.0": + version: 0.25.9 + resolution: "esbuild@npm:0.25.9" + dependencies: + "@esbuild/aix-ppc64": 0.25.9 + "@esbuild/android-arm": 0.25.9 + "@esbuild/android-arm64": 0.25.9 + "@esbuild/android-x64": 0.25.9 + "@esbuild/darwin-arm64": 0.25.9 + "@esbuild/darwin-x64": 0.25.9 + "@esbuild/freebsd-arm64": 0.25.9 + "@esbuild/freebsd-x64": 0.25.9 + "@esbuild/linux-arm": 0.25.9 + "@esbuild/linux-arm64": 0.25.9 + "@esbuild/linux-ia32": 0.25.9 + "@esbuild/linux-loong64": 0.25.9 + "@esbuild/linux-mips64el": 0.25.9 + "@esbuild/linux-ppc64": 0.25.9 + "@esbuild/linux-riscv64": 0.25.9 + "@esbuild/linux-s390x": 0.25.9 + "@esbuild/linux-x64": 0.25.9 + "@esbuild/netbsd-arm64": 0.25.9 + "@esbuild/netbsd-x64": 0.25.9 + "@esbuild/openbsd-arm64": 0.25.9 + "@esbuild/openbsd-x64": 0.25.9 + "@esbuild/openharmony-arm64": 0.25.9 + "@esbuild/sunos-x64": 0.25.9 + "@esbuild/win32-arm64": 0.25.9 + "@esbuild/win32-ia32": 0.25.9 + "@esbuild/win32-x64": 0.25.9 dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -23456,12 +24975,16 @@ __metadata: optional: true "@esbuild/linux-x64": optional: true + "@esbuild/netbsd-arm64": + optional: true "@esbuild/netbsd-x64": optional: true "@esbuild/openbsd-arm64": optional: true "@esbuild/openbsd-x64": optional: true + "@esbuild/openharmony-arm64": + optional: true "@esbuild/sunos-x64": optional: true "@esbuild/win32-arm64": @@ -23472,7 +24995,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: dd386d92a05c7eb03078480522cdd8b40c434777b5f08487c27971d30933ecaae3f08bd221958dd8f9c66214915cdc85f844283ca9bdbf8ee703d889ae526edd + checksum: 718bc15016266da5b4675c2226923cadfe014b119e5c7a9240a6fe826c01ec2e7d5492af052e1c8a03b511778187f234cef2e994e6195287945ce0a824b79974 languageName: node linkType: hard @@ -23812,6 +25335,21 @@ __metadata: languageName: node linkType: hard +"eslint-rspack-plugin@npm:^4.2.1": + version: 4.2.1 + resolution: "eslint-rspack-plugin@npm:4.2.1" + dependencies: + "@types/eslint": ^8.56.10 + jest-worker: ^29.7.0 + micromatch: ^4.0.8 + normalize-path: ^3.0.0 + schema-utils: ^4.2.0 + peerDependencies: + eslint: ^8.0.0 || ^9.0.0 + checksum: f7b4d6c0b46bf26474100efb88debc799487052e16222ff9d72515392df852b8c690f38161177d866b2b39c944402b22e5df93183cc88f47f0df08f98f06cc9e + languageName: node + linkType: hard + "eslint-rule-composer@npm:^0.3.0": version: 0.3.0 resolution: "eslint-rule-composer@npm:0.3.0" @@ -23869,7 +25407,7 @@ __metadata: languageName: node linkType: hard -"eslint-webpack-plugin@npm:^4.0.0, eslint-webpack-plugin@npm:^4.2.0": +"eslint-webpack-plugin@npm:^4.0.0": version: 4.2.0 resolution: "eslint-webpack-plugin@npm:4.2.0" dependencies: @@ -24137,11 +25675,11 @@ __metadata: languageName: node linkType: hard -"express-openapi-validator@npm:^5.0.4": - version: 5.5.3 - resolution: "express-openapi-validator@npm:5.5.3" +"express-openapi-validator@npm:^5.5.8": + version: 5.5.8 + resolution: "express-openapi-validator@npm:5.5.8" dependencies: - "@apidevtools/json-schema-ref-parser": ^12.0.1 + "@apidevtools/json-schema-ref-parser": ^14.0.3 "@types/multer": ^1.4.12 ajv: ^8.17.1 ajv-draft-04: ^1.0.0 @@ -24151,13 +25689,13 @@ __metadata: lodash.clonedeep: ^4.5.0 lodash.get: ^4.4.2 media-typer: ^1.1.0 - multer: ^2.0.0 + multer: ^2.0.2 ono: ^7.1.3 path-to-regexp: ^8.2.0 qs: ^6.14.0 peerDependencies: express: "*" - checksum: 7ce12da259aea91caa221dc62896b4df62c0e720120592270a4e3dfc549db0626e140f80e14914aeae4281f0dfeb27eef855903ba6fc154af97df6d63a3ebe6f + checksum: f76ef56748a28c4ed338ec509eb359bcf992505a565a1a59c0c6ef02c369b03f7d306a94d51b5de4a1d1c69618529e5a7a3aa3c5e3c1dfc0437e6f789a4ab381 languageName: node linkType: hard @@ -24187,7 +25725,7 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2, express@npm:^4.20.0": +"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2, express@npm:^4.20.0, express@npm:^4.21.2": version: 4.21.2 resolution: "express@npm:4.21.2" dependencies: @@ -24286,20 +25824,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": - version: 3.3.2 - resolution: "fast-glob@npm:3.3.2" - dependencies: - "@nodelib/fs.stat": ^2.0.2 - "@nodelib/fs.walk": ^1.2.3 - glob-parent: ^5.1.2 - merge2: ^1.3.0 - micromatch: ^4.0.4 - checksum: 900e4979f4dbc3313840078419245621259f349950411ca2fa445a2f9a1a6d98c3b5e7e0660c5ccd563aa61abe133a21765c6c0dec8e57da1ba71d8000b05ec1 - languageName: node - linkType: hard - -"fast-glob@npm:^3.3.3": +"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2, fast-glob@npm:^3.3.3": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" dependencies: @@ -24676,17 +26201,7 @@ __metadata: languageName: node linkType: hard -"foreground-child@npm:^3.1.0": - version: 3.1.1 - resolution: "foreground-child@npm:3.1.1" - dependencies: - cross-spawn: ^7.0.0 - signal-exit: ^4.0.1 - checksum: 139d270bc82dc9e6f8bc045fe2aae4001dc2472157044fdfad376d0a3457f77857fa883c1c8b21b491c6caade9a926a4bed3d3d2e8d3c9202b151a4cbbd0bcd5 - languageName: node - linkType: hard - -"foreground-child@npm:^3.3.1": +"foreground-child@npm:^3.1.0, foreground-child@npm:^3.3.1": version: 3.3.1 resolution: "foreground-child@npm:3.3.1" dependencies: @@ -24784,25 +26299,37 @@ __metadata: languageName: node linkType: hard +"form-data-encoder@npm:^1.7.2": + version: 1.9.0 + resolution: "form-data-encoder@npm:1.9.0" + checksum: a73f617976f91b594dbd777ec5147abdb0c52d707475130f8cefc8ae9102ccf51be154b929f7c18323729c2763ac25b16055f5034bc188834e9febeb0d971d7f + languageName: node + linkType: hard + "form-data@npm:^2.5.0": - version: 2.5.1 - resolution: "form-data@npm:2.5.1" + version: 2.5.5 + resolution: "form-data@npm:2.5.5" dependencies: asynckit: ^0.4.0 - combined-stream: ^1.0.6 - mime-types: ^2.1.12 - checksum: 5134ada56cc246b293a1ac7678dba6830000603a3979cf83ff7b2f21f2e3725202237cfb89e32bcb38a1d35727efbd3c3a22e65b42321e8ade8eec01ce755d08 + combined-stream: ^1.0.8 + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 + mime-types: ^2.1.35 + safe-buffer: ^5.2.1 + checksum: ba6d8467f959c9bf36a52e423256c1e8055a8e650416760f54fa5db261529c3de698a4ce8378dd4fdb71b44be190906d6b73446556cc74e58de8bda01d09e9e7 languageName: node linkType: hard -"form-data@npm:^4.0.0": - version: 4.0.1 - resolution: "form-data@npm:4.0.1" +"form-data@npm:^4.0.0, form-data@npm:^4.0.4": + version: 4.0.4 + resolution: "form-data@npm:4.0.4" dependencies: asynckit: ^0.4.0 combined-stream: ^1.0.8 + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 mime-types: ^2.1.12 - checksum: ccee458cd5baf234d6b57f349fe9cc5f9a2ea8fd1af5ecda501a18fd1572a6dd3bf08a49f00568afd995b6a65af34cb8dec083cf9d582c4e621836499498dd84 + checksum: 9b7788836df9fa5a6999e0c02515b001946b2a868cfe53f026c69e2c537a2ff9fbfb8e9d2b678744628f3dc7a2d6e14e4e45dfaf68aa6239727f0bdb8ce0abf2 languageName: node linkType: hard @@ -24824,6 +26351,16 @@ __metadata: languageName: node linkType: hard +"formdata-node@npm:^4.3.3": + version: 4.4.1 + resolution: "formdata-node@npm:4.4.1" + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 4.0.0-beta.3 + checksum: d91d4f667cfed74827fc281594102c0dabddd03c9f8b426fc97123eedbf73f5060ee43205d89284d6854e2fc5827e030cd352ef68b93beda8decc2d72128c576 + languageName: node + linkType: hard + "formik@npm:^2.4.5": version: 2.4.6 resolution: "formik@npm:2.4.6" @@ -24842,6 +26379,18 @@ __metadata: languageName: node linkType: hard +"formstream@npm:^1.1.1": + version: 1.5.2 + resolution: "formstream@npm:1.5.2" + dependencies: + destroy: ^1.0.4 + mime: ^2.5.2 + node-hex: ^1.0.1 + pause-stream: ~0.0.11 + checksum: ed04f7ee02633608237a5ed9000d8a7c19d7ed2a69254f5d47cf81d799ffbbecf52bf2440ffa940cb1150f9f80b7b83bf17aac914be11c0fb14bd480226424e7 + languageName: node + linkType: hard + "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" @@ -24856,6 +26405,28 @@ __metadata: languageName: node linkType: hard +"framer-motion@npm:^12.23.24": + version: 12.23.24 + resolution: "framer-motion@npm:12.23.24" + dependencies: + motion-dom: ^12.23.23 + motion-utils: ^12.23.6 + tslib: ^2.4.0 + peerDependencies: + "@emotion/is-prop-valid": "*" + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/is-prop-valid": + optional: true + react: + optional: true + react-dom: + optional: true + checksum: 8f1496ef846e3519c0f8aeaa2994ea5cb12264548e3e97aa33b7de95a4a2227e3e8d79fab17f36f722eafcbbe7cf1e020edd9d3288eda95b4c8d1b05126a8da3 + languageName: node + linkType: hard + "fresh@npm:0.5.2, fresh@npm:~0.5.2": version: 0.5.2 resolution: "fresh@npm:0.5.2" @@ -24954,6 +26525,13 @@ __metadata: languageName: node linkType: hard +"fscreen@npm:^1.0.2": + version: 1.2.0 + resolution: "fscreen@npm:1.2.0" + checksum: ac50f9ac52a157b8fe6aaecdf9efa7c1cfa90b42a76c3bc6b85372fab05c5a9cd72c1b7f4c2e273eba1a0e630e381fd72ae135fcc57acd05a0943d5d0c21b451 + languageName: node + linkType: hard + "fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -25270,6 +26848,15 @@ __metadata: languageName: node linkType: hard +"glob-to-regex.js@npm:^1.0.1": + version: 1.0.1 + resolution: "glob-to-regex.js@npm:1.0.1" + peerDependencies: + tslib: 2 + checksum: c08f748acdb493265e725e44b706eb262b9cc201b7fc13eb4f227dab1471cd522810fa46afa52df54756fe13906819dd7de0cd92b0060ef46ba86441a0b69d6a + languageName: node + linkType: hard + "glob-to-regexp@npm:^0.4.1": version: 0.4.1 resolution: "glob-to-regexp@npm:0.4.1" @@ -25911,10 +27498,10 @@ __metadata: languageName: node linkType: hard -"html-entities@npm:^2.1.0, html-entities@npm:^2.3.2, html-entities@npm:^2.4.0": - version: 2.5.2 - resolution: "html-entities@npm:2.5.2" - checksum: b23f4a07d33d49ade1994069af4e13d31650e3fb62621e92ae10ecdf01d1a98065c78fd20fdc92b4c7881612210b37c275f2c9fba9777650ab0d6f2ceb3b99b6 +"html-entities@npm:^2.1.0, html-entities@npm:^2.3.2, html-entities@npm:^2.6.0": + version: 2.6.0 + resolution: "html-entities@npm:2.6.0" + checksum: 720643f7954019c80911430a7df2728524c07080edfe812610bfc5d8191cd772b470bee0ee151bf7426679314ae53cf28a1c845d702123714e625a8565b26567 languageName: node linkType: hard @@ -26137,7 +27724,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-middleware@npm:^2.0.0, http-proxy-middleware@npm:^2.0.3, http-proxy-middleware@npm:^2.0.6": +"http-proxy-middleware@npm:^2.0.0, http-proxy-middleware@npm:^2.0.3, http-proxy-middleware@npm:^2.0.6, http-proxy-middleware@npm:^2.0.9": version: 2.0.9 resolution: "http-proxy-middleware@npm:2.0.9" dependencies: @@ -26358,11 +27945,11 @@ __metadata: version: 0.0.0-use.local resolution: "immobiliarelabs-backstage-plugin-gitlab-backend@workspace:wrappers/immobiliarelabs-backstage-plugin-gitlab-backend-dynamic" dependencies: - "@backstage/backend-plugin-api": 1.3.0 - "@backstage/cli": 0.30.0 - "@immobiliarelabs/backstage-plugin-gitlab-backend": 6.12.0 + "@backstage/backend-plugin-api": 1.4.2 + "@backstage/cli": ^0.34.1 + "@immobiliarelabs/backstage-plugin-gitlab-backend": 6.13.0 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -26370,10 +27957,10 @@ __metadata: version: 0.0.0-use.local resolution: "immobiliarelabs-backstage-plugin-gitlab@workspace:wrappers/immobiliarelabs-backstage-plugin-gitlab" dependencies: - "@backstage/cli": 0.30.0 - "@immobiliarelabs/backstage-plugin-gitlab": 6.12.0 + "@backstage/cli": ^0.34.1 + "@immobiliarelabs/backstage-plugin-gitlab": 6.13.0 "@janus-idp/cli": 3.6.1 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -26431,6 +28018,19 @@ __metadata: languageName: node linkType: hard +"infinispan@npm:^0.12.0": + version: 0.12.0 + resolution: "infinispan@npm:0.12.0" + dependencies: + buffer-xor: ^2.0.2 + log4js: ^6.4.6 + protobufjs: ^7.0.0 + underscore: ^1.13.3 + urllib: ^3.23.0 + checksum: 28e490dcadd2325677bd231c9e4637a90bb54ce9056cdde9e592041ba6303cbde143b7724e32c9a6e44725e52bac546727e4ff49cdd5a565fba03090863b7137 + languageName: node + linkType: hard + "inflight@npm:^1.0.4": version: 1.0.6 resolution: "inflight@npm:1.0.6" @@ -26533,6 +28133,18 @@ __metadata: languageName: node linkType: hard +"intl-messageformat@npm:^10.1.0": + version: 10.7.18 + resolution: "intl-messageformat@npm:10.7.18" + dependencies: + "@formatjs/ecma402-abstract": 2.3.6 + "@formatjs/fast-memoize": 2.2.7 + "@formatjs/icu-messageformat-parser": 2.11.4 + tslib: ^2.8.0 + checksum: 007ecdada7942465b347a68bb0a107ece945c52783b2565a016fe8ab8612311edfb27419e4ab6cc0eaa14cddd643a661128b1b5494b692ed9e492740d20f7673 + languageName: node + linkType: hard + "ioredis@npm:^5.3.2": version: 5.6.1 resolution: "ioredis@npm:5.6.1" @@ -27240,13 +28852,6 @@ __metadata: languageName: node linkType: hard -"isomorphic-rslog@npm:0.0.7": - version: 0.0.7 - resolution: "isomorphic-rslog@npm:0.0.7" - checksum: 2215fc494a5ec0e26044c4ce315e11effb00c16874cb7b24f3dfcd258257cb53584bb9cd1f8fc2c23b8dcc5c0f2ab85be8c12a87a2af773fce9187bc0ec9d756 - languageName: node - linkType: hard - "isomorphic-textencoder@npm:^1.0.1": version: 1.0.1 resolution: "isomorphic-textencoder@npm:1.0.1" @@ -28263,14 +29868,7 @@ __metadata: languageName: node linkType: hard -"jsonschema@npm:^1.2.6": - version: 1.4.1 - resolution: "jsonschema@npm:1.4.1" - checksum: 1ef02a6cd9bc32241ec86bbf1300bdbc3b5f2d8df6eb795517cf7d1cd9909e7beba1e54fdf73990fd66be98a182bda9add9607296b0cb00b1348212988e424b2 - languageName: node - linkType: hard - -"jsonschema@npm:^1.5.0": +"jsonschema@npm:^1.2.6, jsonschema@npm:^1.5.0": version: 1.5.0 resolution: "jsonschema@npm:1.5.0" checksum: 170b9c375967bc135f4d029fedc31f5686f2c3bb07e7472cebddbb907b5369bf75a1a50287d6af9c31f61c76fe0b7786e78044c188aaddd329b77d856475e6db @@ -28616,9 +30214,9 @@ __metadata: languageName: node linkType: hard -"koa@npm:2.15.3": - version: 2.15.3 - resolution: "koa@npm:2.15.3" +"koa@npm:2.15.4": + version: 2.15.4 + resolution: "koa@npm:2.15.4" dependencies: accepts: ^1.3.5 cache-content-type: ^1.0.0 @@ -28643,7 +30241,7 @@ __metadata: statuses: ^1.5.0 type-is: ^1.6.16 vary: ^1.1.2 - checksum: 7c3537443b1a588cf5c3e5554b914ff2bad510323d22b41861d5e0c97d47e9c5997965f303ede8be8bd83d309a4eea1f82cd45d35d6838bc21bb1bb6a90d5d25 + checksum: cd2bf396fa5f575504d4c1b9e23ba64b9c58cbfa8276dbc4d99ce527ae4f238c38eafb811c22986c2f0f475a61734d05a8f9f5873b22432d78344b4517d83a69 languageName: node linkType: hard @@ -28800,6 +30398,16 @@ __metadata: languageName: node linkType: hard +"linkify-react@npm:4.3.2": + version: 4.3.2 + resolution: "linkify-react@npm:4.3.2" + peerDependencies: + linkifyjs: ^4.0.0 + react: ">= 15.0.0" + checksum: 42b52fc6e7b88a11bf367130551da284bb1f819afa4bad9fa22270f5183cf113cb150d9749615ed7eca92056939934f4d5f95e0a09870f12bff36bbfe85594b8 + languageName: node + linkType: hard + "linkifyjs@npm:4.1.3": version: 4.1.3 resolution: "linkifyjs@npm:4.1.3" @@ -28807,6 +30415,13 @@ __metadata: languageName: node linkType: hard +"linkifyjs@npm:4.3.2": + version: 4.3.2 + resolution: "linkifyjs@npm:4.3.2" + checksum: 9fb57de4b6758f24f399a42a29e0c0e90285105f1f6860cb1bb0be05fc2bf291251d0dfefb08ee4e1e89154d39230aed54b5e91358f040ffa46c31a804413952 + languageName: node + linkType: hard + "loader-runner@npm:^4.2.0": version: 4.3.0 resolution: "loader-runner@npm:4.3.0" @@ -29059,7 +30674,7 @@ __metadata: languageName: node linkType: hard -"log4js@npm:6.9.1": +"log4js@npm:6.9.1, log4js@npm:^6.4.6": version: 6.9.1 resolution: "log4js@npm:6.9.1" dependencies: @@ -29197,10 +30812,10 @@ __metadata: languageName: node linkType: hard -"luxon@npm:^3.0.0, luxon@npm:^3.2.1, luxon@npm:^3.4.1, luxon@npm:^3.4.3, luxon@npm:^3.4.4, luxon@npm:^3.5.0": - version: 3.6.1 - resolution: "luxon@npm:3.6.1" - checksum: bc6c24dde90f4263f548cc5a4ea3328e9c9511bee0b2255bd319639712862f1eb14a39c1b2dcbff8a8bf6686996d28f45b8fc902994a72dd05a29cef1269a6a4 +"luxon@npm:^3.0.0, luxon@npm:^3.2.1, luxon@npm:^3.4.1, luxon@npm:^3.4.3, luxon@npm:^3.4.4, luxon@npm:^3.5.0, luxon@npm:^3.6.1": + version: 3.7.2 + resolution: "luxon@npm:3.7.2" + checksum: fc115fd6a7acc2adb7df3476d20c672beb2985d2a034294282f2c31de8c07f29a15460f5a2b7dd0107797be0dab545ddbc64862662b059fb18c1931a726064f4 languageName: node linkType: hard @@ -29336,6 +30951,25 @@ __metadata: languageName: node linkType: hard +"material-ui-popup-state@npm:^5.3.6": + version: 5.3.6 + resolution: "material-ui-popup-state@npm:5.3.6" + dependencies: + "@babel/runtime": ^7.26.0 + "@types/prop-types": ^15.7.3 + classnames: ^2.2.6 + prop-types: ^15.7.2 + peerDependencies: + "@mui/material": ^5.0.0 || ^6.0.0 || ^7.0.0 + "@types/react": ^16.8.0 || ^17 || ^18 || ^19 + react: ^16.8.0 || ^17 || ^18 || ^19 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 0702d46595538d7e27fa8e0a2bc2156a069e6386949044435c542b1ba4d2662355e8141affa3c0a5353fc88de091ea5de2b51c00e68c6c83bf48b0c1e2ef7fb6 + languageName: node + linkType: hard + "math-intrinsics@npm:^1.1.0": version: 1.1.0 resolution: "math-intrinsics@npm:1.1.0" @@ -29792,15 +31426,17 @@ __metadata: languageName: node linkType: hard -"memfs@npm:^4.6.0": - version: 4.9.2 - resolution: "memfs@npm:4.9.2" +"memfs@npm:^4.28.0, memfs@npm:^4.6.0": + version: 4.38.2 + resolution: "memfs@npm:4.38.2" dependencies: - "@jsonjoy.com/json-pack": ^1.0.3 - "@jsonjoy.com/util": ^1.1.2 - sonic-forest: ^1.0.0 + "@jsonjoy.com/json-pack": ^1.11.0 + "@jsonjoy.com/util": ^1.9.0 + glob-to-regex.js: ^1.0.1 + thingies: ^2.5.0 + tree-dump: ^1.0.3 tslib: ^2.0.0 - checksum: 72850691d37b4e67fb78fceced7294e381caf7a614b22b81fa643c03ac6c13270d52e2ac96d8ed95edab715fd0fba2db1bf604a815cbd6d53ecb3f56c038a583 + checksum: d0546b41444c30c47c293802d06a66e89126c9d7f17079acf667d6520d09b921e32f25a43595db60b1d836dc5d420ec8f0b051666728c066736b9a627fbd1325 languageName: node linkType: hard @@ -29818,6 +31454,13 @@ __metadata: languageName: node linkType: hard +"memoize-one@npm:^6.0.0": + version: 6.0.0 + resolution: "memoize-one@npm:6.0.0" + checksum: f185ea69f7cceae5d1cb596266dcffccf545e8e7b4106ec6aa93b71ab9d16460dd118ac8b12982c55f6d6322fcc1485de139df07eacffaae94888b9b3ad7675f + languageName: node + linkType: hard + "merge-descriptors@npm:1.0.3": version: 1.0.3 resolution: "merge-descriptors@npm:1.0.3" @@ -30533,7 +32176,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.0.8, mime-types@npm:^2.1.12, mime-types@npm:^2.1.18, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.0.8, mime-types@npm:^2.1.12, mime-types@npm:^2.1.18, mime-types@npm:^2.1.27, mime-types@npm:^2.1.31, mime-types@npm:^2.1.35, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -30551,6 +32194,15 @@ __metadata: languageName: node linkType: hard +"mime@npm:^2.5.2": + version: 2.6.0 + resolution: "mime@npm:2.6.0" + bin: + mime: cli.js + checksum: 1497ba7b9f6960694268a557eae24b743fd2923da46ec392b042469f4b901721ba0adcf8b0d3c2677839d0e243b209d76e5edcbd09cfdeffa2dfb6bb4df4b862 + languageName: node + linkType: hard + "mime@npm:^3.0.0": version: 3.0.0 resolution: "mime@npm:3.0.0" @@ -30636,7 +32288,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.0, minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.0, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.5 resolution: "minimatch@npm:9.0.5" dependencies: @@ -30645,7 +32297,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6": +"minimist@npm:^1.1.0, minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -30905,10 +32557,12 @@ __metadata: languageName: node linkType: hard -"monaco-editor@npm:^0.52.2": - version: 0.52.2 - resolution: "monaco-editor@npm:0.52.2" - checksum: d5ff7b7a469afee25ac708d9ace0dcc5ef24ed328dfc526a52944a497f0d826cfb0685a778ff4b7becc0a8f7843f260c17ea6de3f6719481d53501d79ebb1260 +"monaco-editor@npm:^0.53.0": + version: 0.53.0 + resolution: "monaco-editor@npm:0.53.0" + dependencies: + "@types/trusted-types": ^1.0.6 + checksum: 353eca219334b62bdf825f4602aa2b98570c60e7059d257b0567da63fbb79b8eee8bea8448a597e297d0c96c9da3be9eb5153c1e8f279e5450d31c83f02125aa languageName: node linkType: hard @@ -30932,6 +32586,43 @@ __metadata: languageName: node linkType: hard +"motion-dom@npm:^12.23.23": + version: 12.23.23 + resolution: "motion-dom@npm:12.23.23" + dependencies: + motion-utils: ^12.23.6 + checksum: c065c85eae9424c3e44a76da975784b17e2eb0554dc155452dc6622b62df5b7fffa8a963f4a049a4095f209a68016d3f24b011a3d51417bb23db14398fe208eb + languageName: node + linkType: hard + +"motion-utils@npm:^12.23.6": + version: 12.23.6 + resolution: "motion-utils@npm:12.23.6" + checksum: e7c0b1d7a893c5979eab529f2bd269031f71f8d23cbf8be2ec8785558544ee45b9ba7b23390f9a46f2f0a493903b6adc0666229de3b05e977a0bfc3c5fb13d8b + languageName: node + linkType: hard + +"motion@npm:^12.20.1": + version: 12.23.24 + resolution: "motion@npm:12.23.24" + dependencies: + framer-motion: ^12.23.24 + tslib: ^2.4.0 + peerDependencies: + "@emotion/is-prop-valid": "*" + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/is-prop-valid": + optional: true + react: + optional: true + react-dom: + optional: true + checksum: 4e7046f312b85adf96f64f91d67f6f6880bab2ff6e9cdd62cd3e888da8c2f52e14202eb4c095e246cf760a2080fef449115174f8f4f24b1618520501b53b8485 + languageName: node + linkType: hard + "mri@npm:1.1.4": version: 1.1.4 resolution: "mri@npm:1.1.4" @@ -31001,9 +32692,9 @@ __metadata: languageName: node linkType: hard -"multer@npm:^2.0.0": - version: 2.0.1 - resolution: "multer@npm:2.0.1" +"multer@npm:^2.0.2": + version: 2.0.2 + resolution: "multer@npm:2.0.2" dependencies: append-field: ^1.0.0 busboy: ^1.6.0 @@ -31012,7 +32703,7 @@ __metadata: object-assign: ^4.1.1 type-is: ^1.6.18 xtend: ^4.0.2 - checksum: bcbc523108c337cdb0a3f2610fd743a8ad0b7ce773f1970c69e9a338ba3d4389ce3a6339a6bf66b80b96a7aa82442ae505121a2eaa07f3e843b342b84ce8bc2f + checksum: 187f3539b3d5b7f80a289288fc21d3e4116ab9ed21ac9b9ceb25272c7344d215e9572f7e7ed01edb876afddf24661b06578f2c0fc67f36655ebb51a13ccf83dc languageName: node linkType: hard @@ -31225,6 +32916,13 @@ __metadata: languageName: node linkType: hard +"node-domexception@npm:1.0.0": + version: 1.0.0 + resolution: "node-domexception@npm:1.0.0" + checksum: ee1d37dd2a4eb26a8a92cd6b64dfc29caec72bff5e1ed9aba80c294f57a31ba4895a60fd48347cf17dd6e766da0ae87d75657dfd1f384ebfa60462c2283f5c7f + languageName: node + linkType: hard + "node-fetch-h2@npm:^2.3.0": version: 2.3.0 resolution: "node-fetch-h2@npm:2.3.0" @@ -31275,6 +32973,13 @@ __metadata: languageName: node linkType: hard +"node-hex@npm:^1.0.1": + version: 1.0.1 + resolution: "node-hex@npm:1.0.1" + checksum: 9053d532859ee7e9653972af77ac7b73edc4f13b9b53d0b96e4045e3ac78ac4460571d4b72ad31e9095be5f7d01e6fd71f268f02ad6029091f8cabae1d4ce4df + languageName: node + linkType: hard + "node-int64@npm:^0.4.0": version: 0.4.0 resolution: "node-int64@npm:0.4.0" @@ -31940,6 +33645,18 @@ __metadata: languageName: node linkType: hard +"os-name@npm:~1.0.3": + version: 1.0.3 + resolution: "os-name@npm:1.0.3" + dependencies: + osx-release: ^1.0.0 + win-release: ^1.0.0 + bin: + os-name: cli.js + checksum: 2fc86cc199f8b4992bb00041401c5ab0407e3069e05981f3aa3e5a44cee9b7f22c2b0f5db2c0c1d55656c519884272b5e1e55517358c2e5f728b37dd38f5af78 + languageName: node + linkType: hard + "os-tmpdir@npm:~1.0.2": version: 1.0.2 resolution: "os-tmpdir@npm:1.0.2" @@ -31947,6 +33664,17 @@ __metadata: languageName: node linkType: hard +"osx-release@npm:^1.0.0": + version: 1.1.0 + resolution: "osx-release@npm:1.1.0" + dependencies: + minimist: ^1.1.0 + bin: + osx-release: cli.js + checksum: abd437ef21dbfb04f098acc90112cc92ef10c17213e3fd75f8eba45931bd85f6d564ecade0642fac51acff2015597194a76a11773009a90baeb35a03b1c36b06 + languageName: node + linkType: hard + "outvariant@npm:^1.2.1, outvariant@npm:^1.4.0": version: 1.4.3 resolution: "outvariant@npm:1.4.3" @@ -32158,10 +33886,10 @@ __metadata: version: 0.0.0-use.local resolution: "pagerduty-backstage-plugin-backend@workspace:wrappers/pagerduty-backstage-plugin-backend-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@pagerduty/backstage-plugin-backend": 0.9.6 - typescript: 5.8.3 + "@pagerduty/backstage-plugin-backend": 0.9.11 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -32169,10 +33897,10 @@ __metadata: version: 0.0.0-use.local resolution: "pagerduty-backstage-plugin@workspace:wrappers/pagerduty-backstage-plugin" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@pagerduty/backstage-plugin": 0.15.5 - typescript: 5.8.3 + "@pagerduty/backstage-plugin": 0.16.0 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -32213,10 +33941,10 @@ __metadata: version: 0.0.0-use.local resolution: "parfuemerie-douglas-scaffolder-backend-module-azure-repositories@workspace:wrappers/parfuemerie-douglas-scaffolder-backend-module-azure-repositories-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@parfuemerie-douglas/scaffolder-backend-module-azure-repositories": 0.3.0 - typescript: 5.8.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -32473,6 +34201,15 @@ __metadata: languageName: node linkType: hard +"pause-stream@npm:~0.0.11": + version: 0.0.11 + resolution: "pause-stream@npm:0.0.11" + dependencies: + through: ~2.3 + checksum: 3c4a14052a638b92e0c96eb00c0d7977df7f79ea28395250c525d197f1fc02d34ce1165d5362e2e6ebbb251524b94a76f3f0d4abc39ab8b016d97449fe15583c + languageName: node + linkType: hard + "pause@npm:0.0.1": version: 0.0.1 resolution: "pause@npm:0.0.1" @@ -33432,9 +35169,9 @@ __metadata: languageName: node linkType: hard -"protobufjs@npm:^7.2.5, protobufjs@npm:^7.3.2": - version: 7.4.0 - resolution: "protobufjs@npm:7.4.0" +"protobufjs@npm:^7.0.0, protobufjs@npm:^7.2.5, protobufjs@npm:^7.3.2": + version: 7.5.4 + resolution: "protobufjs@npm:7.5.4" dependencies: "@protobufjs/aspromise": ^1.1.2 "@protobufjs/base64": ^1.1.2 @@ -33448,7 +35185,7 @@ __metadata: "@protobufjs/utf8": ^1.1.0 "@types/node": ">=13.7.0" long: ^5.0.0 - checksum: ba0e6b60541bbf818bb148e90f5eb68bd99004e29a6034ad9895a381cbd352be8dce5376e47ae21b2e05559f2505b4a5f4a3c8fa62402822c6ab4dcdfb89ffb3 + checksum: 53bf83b9a726b05d43da35bb990dba7536759787dccea9a67b8f31be9df470ba17f1f1b982ca19956cfc7726f3ec7e0e883ca4ad93b5ec753cc025a637fc704f languageName: node linkType: hard @@ -33588,7 +35325,7 @@ __metadata: languageName: node linkType: hard -"raf-schd@npm:^4.0.2": +"raf-schd@npm:^4.0.2, raf-schd@npm:^4.0.3": version: 4.0.3 resolution: "raf-schd@npm:4.0.3" checksum: 45514041c5ad31fa96aef3bb3c572a843b92da2f2cd1cb4a47c9ad58e48761d3a4126e18daa32b2bfa0bc2551a42d8f324a0e40e536cb656969929602b4e8b58 @@ -33661,6 +35398,13 @@ __metadata: languageName: node linkType: hard +"rate-limiter-flexible@npm:^7.2.0": + version: 7.4.0 + resolution: "rate-limiter-flexible@npm:7.4.0" + checksum: a701432e869a570c8230b727654596de6ae9de6234538dd136c9ec7ce3fe0b228f99158b5dd2b2c85a5bd77a2c5f9cc3abc2871c87a2d18f09de478f3820f70e + languageName: node + linkType: hard + "raw-body@npm:2.5.2, raw-body@npm:^2.4.1": version: 2.5.2 resolution: "raw-body@npm:2.5.2" @@ -33757,6 +35501,99 @@ __metadata: languageName: node linkType: hard +"react-aria-components@npm:^1.10.1": + version: 1.13.0 + resolution: "react-aria-components@npm:1.13.0" + dependencies: + "@internationalized/date": ^3.10.0 + "@internationalized/string": ^3.2.7 + "@react-aria/autocomplete": 3.0.0-rc.3 + "@react-aria/collections": ^3.0.0 + "@react-aria/dnd": ^3.11.3 + "@react-aria/focus": ^3.21.2 + "@react-aria/interactions": ^3.25.6 + "@react-aria/live-announcer": ^3.4.4 + "@react-aria/overlays": ^3.30.0 + "@react-aria/ssr": ^3.9.10 + "@react-aria/textfield": ^3.18.2 + "@react-aria/toolbar": 3.0.0-beta.21 + "@react-aria/utils": ^3.31.0 + "@react-aria/virtualizer": ^4.1.10 + "@react-stately/autocomplete": 3.0.0-beta.3 + "@react-stately/layout": ^4.5.1 + "@react-stately/selection": ^3.20.6 + "@react-stately/table": ^3.15.1 + "@react-stately/utils": ^3.10.8 + "@react-stately/virtualizer": ^4.4.4 + "@react-types/form": ^3.7.16 + "@react-types/grid": ^3.3.6 + "@react-types/shared": ^3.32.1 + "@react-types/table": ^3.13.4 + "@swc/helpers": ^0.5.0 + client-only: ^0.0.1 + react-aria: ^3.44.0 + react-stately: ^3.42.0 + use-sync-external-store: ^1.4.0 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: bf654ccefba31b8eeef65e6fc7d2f83c2a3fb995f915f00797c1a3863102b3239aed4e6ecb812f9d1b57eb468bb423ab76f027d16648616fbbf7d7638f1a8c53 + languageName: node + linkType: hard + +"react-aria@npm:^3.44.0": + version: 3.44.0 + resolution: "react-aria@npm:3.44.0" + dependencies: + "@internationalized/string": ^3.2.7 + "@react-aria/breadcrumbs": ^3.5.29 + "@react-aria/button": ^3.14.2 + "@react-aria/calendar": ^3.9.2 + "@react-aria/checkbox": ^3.16.2 + "@react-aria/color": ^3.1.2 + "@react-aria/combobox": ^3.14.0 + "@react-aria/datepicker": ^3.15.2 + "@react-aria/dialog": ^3.5.31 + "@react-aria/disclosure": ^3.1.0 + "@react-aria/dnd": ^3.11.3 + "@react-aria/focus": ^3.21.2 + "@react-aria/gridlist": ^3.14.1 + "@react-aria/i18n": ^3.12.13 + "@react-aria/interactions": ^3.25.6 + "@react-aria/label": ^3.7.22 + "@react-aria/landmark": ^3.0.7 + "@react-aria/link": ^3.8.6 + "@react-aria/listbox": ^3.15.0 + "@react-aria/menu": ^3.19.3 + "@react-aria/meter": ^3.4.27 + "@react-aria/numberfield": ^3.12.2 + "@react-aria/overlays": ^3.30.0 + "@react-aria/progress": ^3.4.27 + "@react-aria/radio": ^3.12.2 + "@react-aria/searchfield": ^3.8.9 + "@react-aria/select": ^3.17.0 + "@react-aria/selection": ^3.26.0 + "@react-aria/separator": ^3.4.13 + "@react-aria/slider": ^3.8.2 + "@react-aria/ssr": ^3.9.10 + "@react-aria/switch": ^3.7.8 + "@react-aria/table": ^3.17.8 + "@react-aria/tabs": ^3.10.8 + "@react-aria/tag": ^3.7.2 + "@react-aria/textfield": ^3.18.2 + "@react-aria/toast": ^3.0.8 + "@react-aria/tooltip": ^3.8.8 + "@react-aria/tree": ^3.1.4 + "@react-aria/utils": ^3.31.0 + "@react-aria/visually-hidden": ^3.8.28 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 4c22940af735552ce6097fe8c088ed1f02a75e905874bfdc65f0263fe6bf0336a1643ffa57171bb9e8922f6d34dde5401cbc733f12926241b4b2242b7a2a5c47 + languageName: node + linkType: hard + "react-beautiful-dnd@npm:^13.0.0": version: 13.1.1 resolution: "react-beautiful-dnd@npm:13.1.1" @@ -33850,16 +35687,16 @@ __metadata: languageName: node linkType: hard -"react-draggable@npm:^4.0.0, react-draggable@npm:^4.0.3, react-draggable@npm:^4.4.5": - version: 4.4.6 - resolution: "react-draggable@npm:4.4.6" +"react-draggable@npm:^4.0.0, react-draggable@npm:^4.0.3, react-draggable@npm:^4.4.6": + version: 4.5.0 + resolution: "react-draggable@npm:4.5.0" dependencies: - clsx: ^1.1.1 + clsx: ^2.1.1 prop-types: ^15.8.1 peerDependencies: react: ">= 16.3.0" react-dom: ">= 16.3.0" - checksum: 9b15aac59244873ac4561c5a2bead43a56e18d406e0a5f242bd4f9d151c074530c02b99387983104bf43417292f9cf8d063e554ed08d88792235e3fbc965f1b8 + checksum: a5563ed8142ab77e9e68af9b5a57484358462bae76368691362419d7fb4d9fba73300b5c5d1346db6551d88743c68746dc18bc035276db1539d0ad0aff6580cc languageName: node linkType: hard @@ -33897,6 +35734,17 @@ __metadata: languageName: node linkType: hard +"react-full-screen@npm:^1.1.1": + version: 1.1.1 + resolution: "react-full-screen@npm:1.1.1" + dependencies: + fscreen: ^1.0.2 + peerDependencies: + react: ">= 16.8.0" + checksum: 70ad927b9d6c485ac46b5bb4b1639ef9a860da28290b3a1c419c42b9c427d78b80e8dba403eb6451458af56838012c81d5e12ef05097395f154defc32fe06c34 + languageName: node + linkType: hard + "react-grid-layout@npm:1.3.4": version: 1.3.4 resolution: "react-grid-layout@npm:1.3.4" @@ -33913,20 +35761,20 @@ __metadata: languageName: node linkType: hard -"react-grid-layout@npm:1.5.1": - version: 1.5.1 - resolution: "react-grid-layout@npm:1.5.1" +"react-grid-layout@npm:1.5.2": + version: 1.5.2 + resolution: "react-grid-layout@npm:1.5.2" dependencies: - clsx: ^2.0.0 + clsx: ^2.1.1 fast-equals: ^4.0.3 prop-types: ^15.8.1 - react-draggable: ^4.4.5 + react-draggable: ^4.4.6 react-resizable: ^3.0.5 resize-observer-polyfill: ^1.5.1 peerDependencies: react: ">= 16.3.0" react-dom: ">= 16.3.0" - checksum: b0bf00ea99b25b815b421fc79e451b3929101b0d94cf12e902b9bbbdfe8adc2cfe4a4bd45a075e6bf9f4d7c58e32792ef94837d5ca80c96e1eb633f6897a4b83 + checksum: 8beb3a64218168fe25c3f33797f5db03e58a021b4ff863b3ba2186e824a09f0c5409814d248aad3844bc8679bb7492070e82d9d7e899ee5196f3151b9c4177e3 languageName: node linkType: hard @@ -33984,10 +35832,10 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^19.0.0": - version: 19.0.0 - resolution: "react-is@npm:19.0.0" - checksum: fbb3060bcb6b3e8e525b17f0872d1cf62a40b73fa7c5de02419069e2edd3e01cf1e8e86c8888f0733cff006175ee76ae927b40b6f0c4332bdda21020505ac90b +"react-is@npm:^19.0.0, react-is@npm:^19.1.1": + version: 19.1.1 + resolution: "react-is@npm:19.1.1" + checksum: e60ed01c27fe4d22b08f8a31f18831d144a801d08a909ca31fb1d02721b4f4cde0759148d6341f660a4d6ce54a78e22b8b39520b67e2e76254e583885868ab43 languageName: node linkType: hard @@ -34038,7 +35886,7 @@ __metadata: languageName: node linkType: hard -"react-measure@npm:^2.3.0, react-measure@npm:^2.5.2": +"react-measure@npm:^2.3.0": version: 2.5.2 resolution: "react-measure@npm:2.5.2" dependencies: @@ -34081,6 +35929,38 @@ __metadata: languageName: node linkType: hard +"react-redux@npm:^8.1.3": + version: 8.1.3 + resolution: "react-redux@npm:8.1.3" + dependencies: + "@babel/runtime": ^7.12.1 + "@types/hoist-non-react-statics": ^3.3.1 + "@types/use-sync-external-store": ^0.0.3 + hoist-non-react-statics: ^3.3.2 + react-is: ^18.0.0 + use-sync-external-store: ^1.0.0 + peerDependencies: + "@types/react": ^16.8 || ^17.0 || ^18.0 + "@types/react-dom": ^16.8 || ^17.0 || ^18.0 + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + react-native: ">=0.59" + redux: ^4 || ^5.0.0-beta.0 + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + react-dom: + optional: true + react-native: + optional: true + redux: + optional: true + checksum: 192ea6f6053148ec80a4148ec607bc259403b937e515f616a1104ca5ab357e97e98b8245ed505a17afee67a72341d4a559eaca9607968b4a422aa9b44ba7eb89 + languageName: node + linkType: hard + "react-refresh@npm:^0.14.0": version: 0.14.0 resolution: "react-refresh@npm:0.14.0" @@ -34088,6 +35968,13 @@ __metadata: languageName: node linkType: hard +"react-refresh@npm:^0.17.0": + version: 0.17.0 + resolution: "react-refresh@npm:0.17.0" + checksum: e9d23a70543edde879263976d7909cd30c6f698fa372a1240142cf7c8bf99e0396378b9c07c2d39c3a10261d7ba07dc49f990cd8f1ac7b88952e99040a0be5e9 + languageName: node + linkType: hard + "react-relative-time@npm:^0.0.9": version: 0.0.9 resolution: "react-relative-time@npm:0.0.9" @@ -34144,6 +36031,42 @@ __metadata: languageName: node linkType: hard +"react-stately@npm:^3.42.0": + version: 3.42.0 + resolution: "react-stately@npm:3.42.0" + dependencies: + "@react-stately/calendar": ^3.9.0 + "@react-stately/checkbox": ^3.7.2 + "@react-stately/collections": ^3.12.8 + "@react-stately/color": ^3.9.2 + "@react-stately/combobox": ^3.12.0 + "@react-stately/data": ^3.14.1 + "@react-stately/datepicker": ^3.15.2 + "@react-stately/disclosure": ^3.0.8 + "@react-stately/dnd": ^3.7.1 + "@react-stately/form": ^3.2.2 + "@react-stately/list": ^3.13.1 + "@react-stately/menu": ^3.9.8 + "@react-stately/numberfield": ^3.10.2 + "@react-stately/overlays": ^3.6.20 + "@react-stately/radio": ^3.11.2 + "@react-stately/searchfield": ^3.5.16 + "@react-stately/select": ^3.8.0 + "@react-stately/selection": ^3.20.6 + "@react-stately/slider": ^3.7.2 + "@react-stately/table": ^3.15.1 + "@react-stately/tabs": ^3.8.6 + "@react-stately/toast": ^3.1.2 + "@react-stately/toggle": ^3.9.2 + "@react-stately/tooltip": ^3.5.8 + "@react-stately/tree": ^3.9.3 + "@react-types/shared": ^3.32.1 + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + checksum: 7b7937fcb40fb96e674af32f9713da4a330108304413175517b8b5d6c3b6a29648225aebaba2a508fa59e85dd82acaf3daa45dd675b5fcc5913d2e86f8930529 + languageName: node + linkType: hard + "react-syntax-highlighter@npm:^15.4.5": version: 15.5.0 resolution: "react-syntax-highlighter@npm:15.5.0" @@ -34378,11 +36301,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-adoption-insights-backend@workspace:wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights-backend-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@red-hat-developer-hub/backstage-plugin-adoption-insights-backend": 0.2.2 - "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": 0.3.0 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-adoption-insights-backend": 0.3.0 + "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": 0.4.0 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34390,11 +36313,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-adoption-insights@workspace:wrappers/red-hat-developer-hub-backstage-plugin-adoption-insights" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - "@red-hat-developer-hub/backstage-plugin-adoption-insights": 0.2.1 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-adoption-insights": 0.3.2 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34402,11 +36325,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights@workspace:wrappers/red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": 0.3.0 - "@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights": 0.2.0 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-adoption-insights-common": 0.4.0 + "@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights": 0.3.0 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34414,10 +36337,10 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-bulk-import-backend@workspace:wrappers/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@red-hat-developer-hub/backstage-plugin-bulk-import-backend": 6.1.3 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-bulk-import-backend": 6.5.1 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34425,11 +36348,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-bulk-import@workspace:wrappers/red-hat-developer-hub-backstage-plugin-bulk-import" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - "@red-hat-developer-hub/backstage-plugin-bulk-import": 1.13.3 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-bulk-import": 1.18.1 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34437,10 +36360,10 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace@workspace:wrappers/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace": 0.3.3 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-catalog-backend-module-marketplace": 0.7.1 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34448,11 +36371,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-dynamic-home-page@workspace:wrappers/red-hat-developer-hub-backstage-plugin-dynamic-home-page" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - "@red-hat-developer-hub/backstage-plugin-dynamic-home-page": 1.5.0 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-dynamic-home-page": 1.9.2 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34460,11 +36383,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-global-floating-action-button@workspace:wrappers/red-hat-developer-hub-backstage-plugin-global-floating-action-button" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - "@red-hat-developer-hub/backstage-plugin-global-floating-action-button": 1.2.1 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-global-floating-action-button": 1.5.0 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34472,11 +36395,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-global-header@workspace:wrappers/red-hat-developer-hub-backstage-plugin-global-header" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - "@red-hat-developer-hub/backstage-plugin-global-header": 1.14.0 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-global-header": 1.18.1 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34484,11 +36407,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-marketplace-backend@workspace:wrappers/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@red-hat-developer-hub/backstage-plugin-marketplace-backend": 0.6.0 - "@red-hat-developer-hub/backstage-plugin-marketplace-common": 0.6.0 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-marketplace-backend": 0.11.0 + "@red-hat-developer-hub/backstage-plugin-marketplace-common": 0.10.1 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34496,11 +36419,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-marketplace@workspace:wrappers/red-hat-developer-hub-backstage-plugin-marketplace" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - "@red-hat-developer-hub/backstage-plugin-marketplace": 0.7.0 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-marketplace": 0.11.4 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34508,11 +36431,11 @@ __metadata: version: 0.0.0-use.local resolution: "red-hat-developer-hub-backstage-plugin-quickstart@workspace:wrappers/red-hat-developer-hub-backstage-plugin-quickstart" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 "@mui/material": 5.18.0 - "@red-hat-developer-hub/backstage-plugin-quickstart": 1.1.0 - typescript: 5.8.3 + "@red-hat-developer-hub/backstage-plugin-quickstart": 1.6.2 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -34546,7 +36469,7 @@ __metadata: languageName: node linkType: hard -"redux@npm:^4.0.0, redux@npm:^4.0.4, redux@npm:^4.2.0": +"redux@npm:^4.0.0, redux@npm:^4.0.4, redux@npm:^4.2.0, redux@npm:^4.2.1": version: 4.2.1 resolution: "redux@npm:4.2.1" dependencies: @@ -34619,13 +36542,6 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.14.0": - version: 0.14.1 - resolution: "regenerator-runtime@npm:0.14.1" - checksum: 9f57c93277b5585d3c83b0cf76be47b473ae8c6d9142a46ce8b0291a04bb2cf902059f0f8445dcabb3fb7378e5fe4bb4ea1e008876343d42e46d3b484534ce38 - languageName: node - linkType: hard - "regenerator-transform@npm:^0.15.2": version: 0.15.2 resolution: "regenerator-transform@npm:0.15.2" @@ -35154,10 +37070,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-backstage-plugin-argo-cd-backend@workspace:wrappers/roadiehq-backstage-plugin-argo-cd-backend-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/backstage-plugin-argo-cd-backend": 4.3.1 - typescript: 5.8.3 + "@roadiehq/backstage-plugin-argo-cd-backend": 4.4.2 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35165,10 +37081,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-backstage-plugin-datadog@workspace:wrappers/roadiehq-backstage-plugin-datadog" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/backstage-plugin-datadog": 2.4.3 - typescript: 5.8.3 + "@roadiehq/backstage-plugin-datadog": 2.5.0 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35176,10 +37092,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-backstage-plugin-github-insights@workspace:wrappers/roadiehq-backstage-plugin-github-insights" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/backstage-plugin-github-insights": 3.1.4 - typescript: 5.8.3 + "@roadiehq/backstage-plugin-github-insights": 3.2.0 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35187,10 +37103,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-backstage-plugin-github-pull-requests@workspace:wrappers/roadiehq-backstage-plugin-github-pull-requests" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/backstage-plugin-github-pull-requests": 3.4.2 - typescript: 5.8.3 + "@roadiehq/backstage-plugin-github-pull-requests": 3.5.2 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35198,10 +37114,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-backstage-plugin-jira@workspace:wrappers/roadiehq-backstage-plugin-jira" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/backstage-plugin-jira": 2.9.0 - typescript: 5.8.3 + "@roadiehq/backstage-plugin-jira": 2.13.1 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35209,10 +37125,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-backstage-plugin-security-insights@workspace:wrappers/roadiehq-backstage-plugin-security-insights" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/backstage-plugin-security-insights": 3.1.3 - typescript: 5.8.3 + "@roadiehq/backstage-plugin-security-insights": 3.2.0 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35220,10 +37136,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-scaffolder-backend-argocd@workspace:wrappers/roadiehq-scaffolder-backend-argocd-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/scaffolder-backend-argocd": 1.6.0 - typescript: 5.8.3 + "@roadiehq/scaffolder-backend-argocd": 1.7.1 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35231,10 +37147,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-scaffolder-backend-module-http-request@workspace:wrappers/roadiehq-scaffolder-backend-module-http-request-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/scaffolder-backend-module-http-request": 5.3.3 - typescript: 5.8.3 + "@roadiehq/scaffolder-backend-module-http-request": 5.4.2 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35242,10 +37158,10 @@ __metadata: version: 0.0.0-use.local resolution: "roadiehq-scaffolder-backend-module-utils@workspace:wrappers/roadiehq-scaffolder-backend-module-utils-dynamic" dependencies: - "@backstage/cli": 0.30.0 + "@backstage/cli": ^0.34.1 "@janus-idp/cli": 3.6.1 - "@roadiehq/scaffolder-backend-module-utils": 3.5.0 - typescript: 5.8.3 + "@roadiehq/scaffolder-backend-module-utils": 4.0.3 + typescript: 5.9.3 languageName: unknown linkType: soft @@ -35665,6 +37581,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^5.0.1": + version: 5.7.2 + resolution: "semver@npm:5.7.2" + bin: + semver: bin/semver + checksum: fb4ab5e0dd1c22ce0c937ea390b4a822147a9c53dbd2a9a0132f12fe382902beef4fbf12cf51bb955248d8d15874ce8cd89532569756384f994309825f10b686 + languageName: node + linkType: hard + "semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -35829,14 +37754,15 @@ __metadata: linkType: hard "sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8, sha.js@npm:^2.4.9": - version: 2.4.11 - resolution: "sha.js@npm:2.4.11" + version: 2.4.12 + resolution: "sha.js@npm:2.4.12" dependencies: - inherits: ^2.0.1 - safe-buffer: ^5.0.1 + inherits: ^2.0.4 + safe-buffer: ^5.2.1 + to-buffer: ^1.2.0 bin: - sha.js: ./bin.js - checksum: ebd3f59d4b799000699097dadb831c8e3da3eb579144fd7eb7a19484cbcbb7aca3c68ba2bb362242eb09e33217de3b4ea56e4678184c334323eca24a58e3ad07 + sha.js: bin.js + checksum: 9ec0fe39cc402acb33ffb18d261b52013485a2a9569a1873ff1861510a67b9ea2b3ccc78ab8aa09c34e1e85a5f06e18ab83637715509c6153ba8d537bbd2c29d languageName: node linkType: hard @@ -36091,17 +38017,6 @@ __metadata: languageName: node linkType: hard -"sonic-forest@npm:^1.0.0": - version: 1.0.3 - resolution: "sonic-forest@npm:1.0.3" - dependencies: - tree-dump: ^1.0.0 - peerDependencies: - tslib: 2 - checksum: d328735d527ad9e27b3ed9a1599abf33a1e2df139b3689c6515c3c1fa09f19d0a9ddccdc1a43759fa43462259a962308cb18214bed761c1b7ea75a7611e31b11 - languageName: node - linkType: hard - "sorted-array-functions@npm:^1.3.0": version: 1.3.0 resolution: "sorted-array-functions@npm:1.3.0" @@ -36980,7 +38895,7 @@ __metadata: languageName: node linkType: hard -"tabbable@npm:^6.2.0": +"tabbable@npm:^6.0.0, tabbable@npm:^6.2.0": version: 6.2.0 resolution: "tabbable@npm:6.2.0" checksum: f8440277d223949272c74bb627a3371be21735ca9ad34c2570f7e1752bd646ccfc23a9d8b1ee65d6561243f4134f5fbbf1ad6b39ac3c4b586554accaff4a1300 @@ -37002,14 +38917,14 @@ __metadata: linkType: hard "tar-fs@npm:^2.0.0, tar-fs@npm:~2.1.2": - version: 2.1.3 - resolution: "tar-fs@npm:2.1.3" + version: 2.1.4 + resolution: "tar-fs@npm:2.1.4" dependencies: chownr: ^1.1.1 mkdirp-classic: ^0.5.2 pump: ^3.0.0 tar-stream: ^2.1.4 - checksum: 8dd66c20779c1fe535df5cf2ab5132705c12aba3ab95283f225a798329c5aaa8bbe92144c8e21bc9404f46a0d3ce59fc4997f5c42bafc55b6a225d4ad15aa966 + checksum: a9e18e2e6114b8ac2568d7c2b42d006b1fe30d83957e4e75ba2361a889c2fc54e54236476782d06494e081358a393feacdf19311df12b3056c8a64dc1f7ed309 languageName: node linkType: hard @@ -37182,12 +39097,12 @@ __metadata: languageName: node linkType: hard -"thingies@npm:^1.20.0": - version: 1.21.0 - resolution: "thingies@npm:1.21.0" +"thingies@npm:^2.5.0": + version: 2.5.0 + resolution: "thingies@npm:2.5.0" peerDependencies: tslib: ^2 - checksum: 283a2785e513dc892822dd0bbadaa79e873a7fc90b84798164717bf7cf837553e0b4518d8027b2307d8f6fc6caab088fa717112cd9196c6222763cc3cc1b7e79 + checksum: e73e4bc96aefc41e4f1fdd1cf65eb988c9837f3b5fcd8a472ee30d91c2f7fa9b144562d6b4c5dade6ce70bc5865caf3e869f6d2975cce064b1d81dac3ece3508 languageName: node linkType: hard @@ -37207,7 +39122,7 @@ __metadata: languageName: node linkType: hard -"through@npm:^2.3.6": +"through@npm:^2.3.6, through@npm:~2.3": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd @@ -37410,12 +39325,12 @@ __metadata: languageName: node linkType: hard -"tree-dump@npm:^1.0.0": - version: 1.0.1 - resolution: "tree-dump@npm:1.0.1" +"tree-dump@npm:^1.0.3": + version: 1.0.3 + resolution: "tree-dump@npm:1.0.3" peerDependencies: tslib: 2 - checksum: 256f2e066ab8743672795822731410d9b9036ef449499f528df1a638ad99af45f345bfbddeaf1cc46b7b9279db3b5f83e1a4cb21bc086ef25ce6add975a3c490 + checksum: 0b545728ff6589c4026b618aa24b2af9b52ae59d5da71a4ea5a727e1b5585a9a1c7620caba6616c2540a6089fdc5d1e6e060efa4e288c6e78c899b462dbb2c90 languageName: node linkType: hard @@ -37481,6 +39396,27 @@ __metadata: languageName: node linkType: hard +"ts-checker-rspack-plugin@npm:^1.1.5": + version: 1.1.5 + resolution: "ts-checker-rspack-plugin@npm:1.1.5" + dependencies: + "@babel/code-frame": ^7.27.1 + "@rspack/lite-tapable": ^1.0.1 + chokidar: ^3.6.0 + is-glob: ^4.0.3 + memfs: ^4.28.0 + minimatch: ^9.0.5 + picocolors: ^1.1.1 + peerDependencies: + "@rspack/core": ^1.0.0 + typescript: ">=3.8.0" + peerDependenciesMeta: + "@rspack/core": + optional: true + checksum: 01997ed2a77e1e88b25cc60c3398ad7347056dbc044423af9252e7a1b731716d516c5c3f0c9bdfd29e8bb64389bcbc57a6be5d245f6003ec81d1aa03ae21f83f + languageName: node + linkType: hard + "ts-easing@npm:^0.2.0": version: 0.2.0 resolution: "ts-easing@npm:0.2.0" @@ -37569,16 +39505,16 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.5.0, tslib@npm:^2.6.2, tslib@npm:^2.7.0, tslib@npm:^2.8.1": +"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.5.0, tslib@npm:^2.6.2, tslib@npm:^2.7.0, tslib@npm:^2.8.0, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a languageName: node linkType: hard -"tss-react@npm:4.9.18": - version: 4.9.18 - resolution: "tss-react@npm:4.9.18" +"tss-react@npm:4.9.19": + version: 4.9.19 + resolution: "tss-react@npm:4.9.19" dependencies: "@emotion/cache": "*" "@emotion/serialize": "*" @@ -37594,7 +39530,7 @@ __metadata: optional: true "@mui/material": optional: true - checksum: 5330f06f29c19cc501afd635e888e88b393f44d57cc8e64c96b473cb728899e35fcb363aa5274ff0414fc49a2d46c73f4e8b1bd5f7ea267b5cfcf99074a689a7 + checksum: 1e29114220d26aa3a30c05f372f61bd876a0a4eb5482b8cd16a13c9783d1ad5c33bc15cf379d467965dc98ad7c528c9165c816c26958032761dea05296e78466 languageName: node linkType: hard @@ -37646,58 +39582,58 @@ __metadata: languageName: node linkType: hard -"turbo-darwin-64@npm:2.5.4": - version: 2.5.4 - resolution: "turbo-darwin-64@npm:2.5.4" +"turbo-darwin-64@npm:2.5.8": + version: 2.5.8 + resolution: "turbo-darwin-64@npm:2.5.8" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"turbo-darwin-arm64@npm:2.5.4": - version: 2.5.4 - resolution: "turbo-darwin-arm64@npm:2.5.4" +"turbo-darwin-arm64@npm:2.5.8": + version: 2.5.8 + resolution: "turbo-darwin-arm64@npm:2.5.8" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"turbo-linux-64@npm:2.5.4": - version: 2.5.4 - resolution: "turbo-linux-64@npm:2.5.4" +"turbo-linux-64@npm:2.5.8": + version: 2.5.8 + resolution: "turbo-linux-64@npm:2.5.8" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"turbo-linux-arm64@npm:2.5.4": - version: 2.5.4 - resolution: "turbo-linux-arm64@npm:2.5.4" +"turbo-linux-arm64@npm:2.5.8": + version: 2.5.8 + resolution: "turbo-linux-arm64@npm:2.5.8" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"turbo-windows-64@npm:2.5.4": - version: 2.5.4 - resolution: "turbo-windows-64@npm:2.5.4" +"turbo-windows-64@npm:2.5.8": + version: 2.5.8 + resolution: "turbo-windows-64@npm:2.5.8" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"turbo-windows-arm64@npm:2.5.4": - version: 2.5.4 - resolution: "turbo-windows-arm64@npm:2.5.4" +"turbo-windows-arm64@npm:2.5.8": + version: 2.5.8 + resolution: "turbo-windows-arm64@npm:2.5.8" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"turbo@npm:2.5.4": - version: 2.5.4 - resolution: "turbo@npm:2.5.4" - dependencies: - turbo-darwin-64: 2.5.4 - turbo-darwin-arm64: 2.5.4 - turbo-linux-64: 2.5.4 - turbo-linux-arm64: 2.5.4 - turbo-windows-64: 2.5.4 - turbo-windows-arm64: 2.5.4 +"turbo@npm:2.5.8": + version: 2.5.8 + resolution: "turbo@npm:2.5.8" + dependencies: + turbo-darwin-64: 2.5.8 + turbo-darwin-arm64: 2.5.8 + turbo-linux-64: 2.5.8 + turbo-linux-arm64: 2.5.8 + turbo-windows-64: 2.5.8 + turbo-windows-arm64: 2.5.8 dependenciesMeta: turbo-darwin-64: optional: true @@ -37713,7 +39649,7 @@ __metadata: optional: true bin: turbo: bin/turbo - checksum: b0b1b5a3ad8cece743c32dbbfaf48b3e16dad1ec238afbd2259447a1d2346955bc2d2da4b650b0114ee3c92b32179a56e47c640be027ddcf5a10e6724f0e8245 + checksum: f1d6d84e828f7f2d41ae7598507267c7ed8de22307507a304da8353ce4e47cf38c1c7c26e6249c1247ea7702eebd6c062b6fcf037c565b2a94417690956c8cb5 languageName: node linkType: hard @@ -37749,6 +39685,13 @@ __metadata: languageName: node linkType: hard +"type-detect@npm:^4.0.0": + version: 4.1.0 + resolution: "type-detect@npm:4.1.0" + checksum: 3b32f873cd02bc7001b00a61502b7ddc4b49278aabe68d652f732e1b5d768c072de0bc734b427abf59d0520a5f19a2e07309ab921ef02018fa1cb4af155cdb37 + languageName: node + linkType: hard + "type-fest@npm:^0.13.1": version: 0.13.1 resolution: "type-fest@npm:0.13.1" @@ -37777,6 +39720,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^4.3.1": + version: 4.41.0 + resolution: "type-fest@npm:4.41.0" + checksum: 7055c0e3eb188425d07403f1d5dc175ca4c4f093556f26871fe22041bc93d137d54bef5851afa320638ca1379106c594f5aa153caa654ac1a7f22c71588a4e80 + languageName: node + linkType: hard + "type-is@npm:^1.6.16, type-is@npm:^1.6.18, type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -37921,13 +39871,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.8.3": - version: 5.8.3 - resolution: "typescript@npm:5.8.3" +"typescript@npm:5.9.3": + version: 5.9.3 + resolution: "typescript@npm:5.9.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: cb1d081c889a288b962d3c8ae18d337ad6ee88a8e81ae0103fa1fecbe923737f3ba1dbdb3e6d8b776c72bc73bfa6d8d850c0306eed1a51377d2fccdfd75d92c4 + checksum: 0d0ffb84f2cd072c3e164c79a2e5a1a1f4f168e84cb2882ff8967b92afe1def6c2a91f6838fb58b168428f9458c57a2ba06a6737711fdd87a256bbe83e9a217f languageName: node linkType: hard @@ -37951,13 +39901,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@5.8.3#~builtin": - version: 5.8.3 - resolution: "typescript@patch:typescript@npm%3A5.8.3#~builtin::version=5.8.3&hash=5786d5" +"typescript@patch:typescript@5.9.3#~builtin": + version: 5.9.3 + resolution: "typescript@patch:typescript@npm%3A5.9.3#~builtin::version=5.9.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: f1743b6850976b3debf7cbd53d2bc0b67e75d47eb6410db564c8bb475e92a8a48f8a3fcd14d89cf93426835281c31a8f8a94dad90be4dc899279a898532ba97f + checksum: a5a6dc399d3761ded54192031f11d3ad5df8001c7febe3fbbc8098efcb552cdf8f2f402b3618c56dafcd04fef63dee005f4900f608e185404caedc46480539ed languageName: node linkType: hard @@ -38009,10 +39959,10 @@ __metadata: languageName: node linkType: hard -"underscore@npm:^1.12.1": - version: 1.13.6 - resolution: "underscore@npm:1.13.6" - checksum: d5cedd14a9d0d91dd38c1ce6169e4455bb931f0aaf354108e47bd46d3f2da7464d49b2171a5cf786d61963204a42d01ea1332a903b7342ad428deaafaf70ec36 +"underscore@npm:^1.12.1, underscore@npm:^1.13.3": + version: 1.13.7 + resolution: "underscore@npm:1.13.7" + checksum: 174b011af29e4fbe2c70eb2baa8bfab0d0336cf2f5654f364484967bc6264a86224d0134b9176e4235c8cceae00d11839f0fd4824268de04b11c78aca1241684 languageName: node linkType: hard @@ -38037,6 +39987,15 @@ __metadata: languageName: node linkType: hard +"undici@npm:^5.28.2": + version: 5.29.0 + resolution: "undici@npm:5.29.0" + dependencies: + "@fastify/busboy": ^2.0.0 + checksum: a25b5462c1b6ffb974f5ffc492ffd64146a9983aad0cbda6fde65e2b22f6f1acd43f09beacc66cc47624a113bd0c684ffc60366102b6a21b038fbfafb7d75195 + languageName: node + linkType: hard + "undici@npm:^7.2.3": version: 7.4.0 resolution: "undici@npm:7.4.0" @@ -38382,6 +40341,25 @@ __metadata: languageName: node linkType: hard +"urllib@npm:^3.23.0": + version: 3.27.3 + resolution: "urllib@npm:3.27.3" + dependencies: + default-user-agent: ^1.0.0 + digest-header: ^1.0.0 + form-data-encoder: ^1.7.2 + formdata-node: ^4.3.3 + formstream: ^1.1.1 + mime-types: ^2.1.35 + pump: ^3.0.0 + qs: ^6.11.2 + type-fest: ^4.3.1 + undici: ^5.28.2 + ylru: ^1.3.2 + checksum: b587fe23f9ec2b24a279a89dc4be0de7b81437edddc62d1e20c064d7c715f755af316ca6b22173e5fc2f4e76fe8c002734b087a725d90abd39e40a0730553299 + languageName: node + linkType: hard + "urlpattern-polyfill@npm:^8.0.0": version: 8.0.2 resolution: "urlpattern-polyfill@npm:8.0.2" @@ -38389,7 +40367,7 @@ __metadata: languageName: node linkType: hard -"use-memo-one@npm:^1.1.1": +"use-memo-one@npm:^1.1.1, use-memo-one@npm:^1.1.3": version: 1.1.3 resolution: "use-memo-one@npm:1.1.3" peerDependencies: @@ -38398,12 +40376,12 @@ __metadata: languageName: node linkType: hard -"use-sync-external-store@npm:^1.2.0, use-sync-external-store@npm:^1.2.2": - version: 1.4.0 - resolution: "use-sync-external-store@npm:1.4.0" +"use-sync-external-store@npm:^1.0.0, use-sync-external-store@npm:^1.2.0, use-sync-external-store@npm:^1.2.2, use-sync-external-store@npm:^1.4.0": + version: 1.6.0 + resolution: "use-sync-external-store@npm:1.6.0" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - checksum: dc3843a1b59ac8bd01417bd79498d4c688d5df8bf4801be50008ef4bfaacb349058c0b1605b5b43c828e0a2d62722d7e861573b3f31cea77a7f23e8b0fc2f7e3 + checksum: 61a62e910713adfaf91bdb72ff2cd30e5ba83687accaf3b6e75a903b45bf635f5722e3694af30d83a03e92cb533c0a5c699298d2fef639a03ffc86b469f4eee2 languageName: node linkType: hard @@ -38477,16 +40455,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^11.0.0, uuid@npm:^11.0.2": - version: 11.0.5 - resolution: "uuid@npm:11.0.5" - bin: - uuid: dist/esm/bin/uuid - checksum: 8a8ed824c77ccc9387eed3049e75268a862379f0d41222716020743c438f31e9acfbe6495bd4cb1a7727c91fcf5ae20be40b306826a62c96f9ff42db48e8ed93 - languageName: node - linkType: hard - -"uuid@npm:^11.1.0": +"uuid@npm:^11.0.0, uuid@npm:^11.0.2, uuid@npm:^11.1.0": version: 11.1.0 resolution: "uuid@npm:11.1.0" bin: @@ -38693,19 +40662,6 @@ __metadata: languageName: node linkType: hard -"victory-area@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-area@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - victory-vendor: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: dba169e980c595d1ba0a99ed1d4c60c8bc41feab51c15ab4549dde4ec1d0d090a584902c550b1799d6665dc88125b99962b948f8b6a7db21434faa1b45d222a7 - languageName: node - linkType: hard - "victory-axis@npm:37.3.6": version: 37.3.6 resolution: "victory-axis@npm:37.3.6" @@ -38718,18 +40674,6 @@ __metadata: languageName: node linkType: hard -"victory-axis@npm:^36.9.1, victory-axis@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-axis@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 6603a29023a2c8946ef7ef8875f8907eac80526b97c9ebfc63425e5c8b725d0c0aa2de516cd83cd497fe0c8a312fe57995294ae3342789bc45a28764d69f7cb0 - languageName: node - linkType: hard - "victory-bar@npm:37.3.6": version: 37.3.6 resolution: "victory-bar@npm:37.3.6" @@ -38743,19 +40687,6 @@ __metadata: languageName: node linkType: hard -"victory-bar@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-bar@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - victory-vendor: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 346924e20912845840fa1db6f86c0cadc142adcf697635d70e34665fe0ff2297a58e13ef429ad5999912f4c5c9fcdaffa5a33f536747598697b3cc598c4a0418 - languageName: node - linkType: hard - "victory-box-plot@npm:37.3.6": version: 37.3.6 resolution: "victory-box-plot@npm:37.3.6" @@ -38769,19 +40700,6 @@ __metadata: languageName: node linkType: hard -"victory-box-plot@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-box-plot@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - victory-vendor: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: f0e6d7a99d9d4209ad6f9340b0082d761857c9792e3d93e964682b5f516da7e2a5ef1399df8fdee0fe5e1f16ee4a79db1c0f4da5dbf9210c73a3373f3cd34d17 - languageName: node - linkType: hard - "victory-brush-container@npm:37.3.6": version: 37.3.6 resolution: "victory-brush-container@npm:37.3.6" @@ -38795,19 +40713,6 @@ __metadata: languageName: node linkType: hard -"victory-brush-container@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-brush-container@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - react-fast-compare: ^3.2.0 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: f2f0b260ef208f5ece274f814ca1f788979333690f69485065d2fa74f75cc4e1a37732ff2e00f055fec50a3195871890f3476dadc9760ce8bdeadf296212fa96 - languageName: node - linkType: hard - "victory-brush-line@npm:37.3.6": version: 37.3.6 resolution: "victory-brush-line@npm:37.3.6" @@ -38862,22 +40767,6 @@ __metadata: languageName: node linkType: hard -"victory-chart@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-chart@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - react-fast-compare: ^3.2.0 - victory-axis: ^36.9.2 - victory-core: ^36.9.2 - victory-polar-axis: ^36.9.2 - victory-shared-events: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 2ab2edd55035087ec4a3b039fe0a9d8ecc53cb3a8d667068574122a709e7d1fd85c2cdbb2306c1d326afd44ae423cb194c4b79e0dce8f07c89b7fa2fee12978a - languageName: node - linkType: hard - "victory-core@npm:37.3.6": version: 37.3.6 resolution: "victory-core@npm:37.3.6" @@ -38891,19 +40780,6 @@ __metadata: languageName: node linkType: hard -"victory-core@npm:^36.9.1, victory-core@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-core@npm:36.9.2" - dependencies: - lodash: ^4.17.21 - react-fast-compare: ^3.2.0 - victory-vendor: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: da17211f4b40a38b6dcb5fe7a32221bfaa870f2813f3cc95fcd7eb60bb357d4246ac69127fd7c90d40e1efaab05dffaed656fa1c14e0b7a444da8a2a3d401d4e - languageName: node - linkType: hard - "victory-create-container@npm:37.3.6": version: 37.3.6 resolution: "victory-create-container@npm:37.3.6" @@ -38921,23 +40797,6 @@ __metadata: languageName: node linkType: hard -"victory-create-container@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-create-container@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-brush-container: ^36.9.2 - victory-core: ^36.9.2 - victory-cursor-container: ^36.9.2 - victory-selection-container: ^36.9.2 - victory-voronoi-container: ^36.9.2 - victory-zoom-container: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 6bc4ac3eb2e85d715c56353beb4f8400fa39658e8af5e0fabed3f0f6015091c50598947b1b0909bab67d0592bb804394e7962f8732915160f55501341f37f224 - languageName: node - linkType: hard - "victory-cursor-container@npm:37.3.6": version: 37.3.6 resolution: "victory-cursor-container@npm:37.3.6" @@ -38950,18 +40809,6 @@ __metadata: languageName: node linkType: hard -"victory-cursor-container@npm:^36.9.1, victory-cursor-container@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-cursor-container@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: d93f8d7e09a02ce507d0bbccf1bd1ab0446ba8ff734e3242456cf97d69d12ce987945a273f26ba6e92c0e27b41e314b13805d25c3cdcfca66f38baba41d8f284 - languageName: node - linkType: hard - "victory-errorbar@npm:37.3.6": version: 37.3.6 resolution: "victory-errorbar@npm:37.3.6" @@ -38988,20 +40835,6 @@ __metadata: languageName: node linkType: hard -"victory-group@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-group@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - react-fast-compare: ^3.2.0 - victory-core: ^36.9.2 - victory-shared-events: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 8d7397a58d33bb78f827a76dbe1e2aa1faf163d3efe94259b8cc162ed161c731622af3717543bbc24a0f57ce75faf0bdc5cbe08a78a42a004b69754c88e71dca - languageName: node - linkType: hard - "victory-histogram@npm:37.3.6": version: 37.3.6 resolution: "victory-histogram@npm:37.3.6" @@ -39029,18 +40862,6 @@ __metadata: languageName: node linkType: hard -"victory-legend@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-legend@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 0ae0001ac030778af83b2a651fb54cb6ff4227892065251078a38dd84df289eabb1d0ae8c2ffc296bdc08066d45c99c7575794160dbc84b8f0712b20ccaeee2c - languageName: node - linkType: hard - "victory-line@npm:37.3.6": version: 37.3.6 resolution: "victory-line@npm:37.3.6" @@ -39054,19 +40875,6 @@ __metadata: languageName: node linkType: hard -"victory-line@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-line@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - victory-vendor: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: cfe9352ef7deedc57a95dd3f721a0392efeb84079e4ced6a562fe5d29e54d3c148ad8a0ea8823c69f28243f9c8a21cb89e2abc1a2f6faec56c88e82eb7606c55 - languageName: node - linkType: hard - "victory-pie@npm:37.3.6": version: 37.3.6 resolution: "victory-pie@npm:37.3.6" @@ -39080,19 +40888,6 @@ __metadata: languageName: node linkType: hard -"victory-pie@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-pie@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - victory-vendor: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: d566c018ef8c6656f00e7b1e57ea3b85cdc1a823e10f9c6255d2677e0774a6828941e6771657bf3570ad59e0f4b06efc209f6bf4f49e3ca95e4ac85f6ef421f3 - languageName: node - linkType: hard - "victory-polar-axis@npm:37.3.6": version: 37.3.6 resolution: "victory-polar-axis@npm:37.3.6" @@ -39105,18 +40900,6 @@ __metadata: languageName: node linkType: hard -"victory-polar-axis@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-polar-axis@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 4f75896f8769cf731f084c56f9eaa32cbd7d758d4a56efc8f1c17626c3a05dc626651b694310c50d9460169ad1ee491e6136f53b3316a6fd583836c6e8d41779 - languageName: node - linkType: hard - "victory-scatter@npm:37.3.6": version: 37.3.6 resolution: "victory-scatter@npm:37.3.6" @@ -39129,18 +40912,6 @@ __metadata: languageName: node linkType: hard -"victory-scatter@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-scatter@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 550be1b42b5b75ad273312999dc0d1b01580f4fadfb49cc699740d65ecff403564ac435667df705c7cb8924e380fa713a26e30c6b5a78876f2c3c47b6b08d78f - languageName: node - linkType: hard - "victory-selection-container@npm:37.3.6": version: 37.3.6 resolution: "victory-selection-container@npm:37.3.6" @@ -39153,18 +40924,6 @@ __metadata: languageName: node linkType: hard -"victory-selection-container@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-selection-container@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: d40b6839482d7c299417e6c85cca82b113196544ccee2a155e3e2e49feb4c06f8545f301bad2e01478fe810caa9cef3426c73adc1e9b6fe681548de9beeb814a - languageName: node - linkType: hard - "victory-shared-events@npm:37.3.6": version: 37.3.6 resolution: "victory-shared-events@npm:37.3.6" @@ -39179,20 +40938,6 @@ __metadata: languageName: node linkType: hard -"victory-shared-events@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-shared-events@npm:36.9.2" - dependencies: - json-stringify-safe: ^5.0.1 - lodash: ^4.17.19 - react-fast-compare: ^3.2.0 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 6f36bedc1644a657009ccc7c291152f89d3757623e99cee2714eb1262e79fb9fd85fa215709a52184080da0c0486926cc4493338608deef111e44f80704829ec - languageName: node - linkType: hard - "victory-stack@npm:37.3.6": version: 37.3.6 resolution: "victory-stack@npm:37.3.6" @@ -39207,20 +40952,6 @@ __metadata: languageName: node linkType: hard -"victory-stack@npm:^36.9.1": - version: 36.9.2 - resolution: "victory-stack@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - react-fast-compare: ^3.2.0 - victory-core: ^36.9.2 - victory-shared-events: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 6ecedec0d0a4c8a0e0697b530be190541772122a6ffb3de0dd13fa8d0985c0c11441ca302fc9b93495610b9f824207f9d318a450bf9d657c540c88bf5fc34c35 - languageName: node - linkType: hard - "victory-tooltip@npm:37.3.6": version: 37.3.6 resolution: "victory-tooltip@npm:37.3.6" @@ -39233,18 +40964,6 @@ __metadata: languageName: node linkType: hard -"victory-tooltip@npm:^36.9.1, victory-tooltip@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-tooltip@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: 43499f0dad993755b96baafd09bf7578b88cf598d09cc8d926cba1debcd4ba8645e0bb2d0692d6b97275830261b7749d2189deb2873495929db2103b0c23e2a6 - languageName: node - linkType: hard - "victory-vendor@npm:37.3.6": version: 37.3.6 resolution: "victory-vendor@npm:37.3.6" @@ -39267,7 +40986,7 @@ __metadata: languageName: node linkType: hard -"victory-vendor@npm:^36.6.8, victory-vendor@npm:^36.9.2": +"victory-vendor@npm:^36.6.8": version: 36.9.2 resolution: "victory-vendor@npm:36.9.2" dependencies: @@ -39304,21 +41023,6 @@ __metadata: languageName: node linkType: hard -"victory-voronoi-container@npm:^36.9.1, victory-voronoi-container@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-voronoi-container@npm:36.9.2" - dependencies: - delaunay-find: 0.0.6 - lodash: ^4.17.19 - react-fast-compare: ^3.2.0 - victory-core: ^36.9.2 - victory-tooltip: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: c59ba256f1479d69749c93b0c7aa25f1f99a705e40a5cc0cee474fb1f150012ddae8fb8e75bc79c14254efb5581fb946d24041b4af965d294a84106f843625f5 - languageName: node - linkType: hard - "victory-voronoi@npm:37.3.6": version: 37.3.6 resolution: "victory-voronoi@npm:37.3.6" @@ -39344,18 +41048,6 @@ __metadata: languageName: node linkType: hard -"victory-zoom-container@npm:^36.9.1, victory-zoom-container@npm:^36.9.2": - version: 36.9.2 - resolution: "victory-zoom-container@npm:36.9.2" - dependencies: - lodash: ^4.17.19 - victory-core: ^36.9.2 - peerDependencies: - react: ">=16.6.0" - checksum: dae761dd860a08c9451dbf2d237dced2bb08599b5bedf269b3c2cc75b137b599bba0c7721fb0e062d95bbf22312c2d30f909ad220ea7c0923d3799df311df76d - languageName: node - linkType: hard - "victory@npm:^37.3.6": version: 37.3.6 resolution: "victory@npm:37.3.6" @@ -39459,6 +41151,13 @@ __metadata: languageName: node linkType: hard +"web-streams-polyfill@npm:4.0.0-beta.3": + version: 4.0.0-beta.3 + resolution: "web-streams-polyfill@npm:4.0.0-beta.3" + checksum: dfec1fbf52b9140e4183a941e380487b6c3d5d3838dd1259be81506c1c9f2abfcf5aeb670aeeecfd9dff4271a6d8fef931b193c7bedfb42542a3b05ff36c0d16 + languageName: node + linkType: hard + "webcola@npm:3.4.0": version: 3.4.0 resolution: "webcola@npm:3.4.0" @@ -39500,9 +41199,9 @@ __metadata: languageName: node linkType: hard -"webpack-dev-middleware@npm:^7.1.0": - version: 7.2.1 - resolution: "webpack-dev-middleware@npm:7.2.1" +"webpack-dev-middleware@npm:^7.4.2": + version: 7.4.2 + resolution: "webpack-dev-middleware@npm:7.4.2" dependencies: colorette: ^2.0.10 memfs: ^4.6.0 @@ -39515,7 +41214,52 @@ __metadata: peerDependenciesMeta: webpack: optional: true - checksum: bb8c75f7ceabc13ee2c3bc9648190e05a0a8c6d40b940ef72b09ea858a63d16bcb434b49995f1025125a1c3a1c8d40274beb5d26ef2fb1458b19e7f6fe3a91fe + checksum: 39314ec5e4468d177dd61fb51af87ec097e920fe0f0dc101e1bf71796740a7e49fd4f7f939cf91e130232714d6d2fffd948d72dc65dec10f87ac30339929f018 + languageName: node + linkType: hard + +"webpack-dev-server@npm:5.2.2, webpack-dev-server@npm:^5.0.0": + version: 5.2.2 + resolution: "webpack-dev-server@npm:5.2.2" + dependencies: + "@types/bonjour": ^3.5.13 + "@types/connect-history-api-fallback": ^1.5.4 + "@types/express": ^4.17.21 + "@types/express-serve-static-core": ^4.17.21 + "@types/serve-index": ^1.9.4 + "@types/serve-static": ^1.15.5 + "@types/sockjs": ^0.3.36 + "@types/ws": ^8.5.10 + ansi-html-community: ^0.0.8 + bonjour-service: ^1.2.1 + chokidar: ^3.6.0 + colorette: ^2.0.10 + compression: ^1.7.4 + connect-history-api-fallback: ^2.0.0 + express: ^4.21.2 + graceful-fs: ^4.2.6 + http-proxy-middleware: ^2.0.9 + ipaddr.js: ^2.1.0 + launch-editor: ^2.6.1 + open: ^10.0.3 + p-retry: ^6.2.0 + schema-utils: ^4.2.0 + selfsigned: ^2.4.1 + serve-index: ^1.9.1 + sockjs: ^0.3.24 + spdy: ^4.0.2 + webpack-dev-middleware: ^7.4.2 + ws: ^8.18.0 + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + bin: + webpack-dev-server: bin/webpack-dev-server.js + checksum: 96994d684563cfee76dcb031c7c18a1fa10aee2df0520a0f327c8d72d4692c0dcdd7e455adeed4f8da9695f2e9f8f5481053c7e6e27d7e35085e45357fc9f697 languageName: node linkType: hard @@ -39566,53 +41310,6 @@ __metadata: languageName: node linkType: hard -"webpack-dev-server@npm:^5.0.0": - version: 5.0.4 - resolution: "webpack-dev-server@npm:5.0.4" - dependencies: - "@types/bonjour": ^3.5.13 - "@types/connect-history-api-fallback": ^1.5.4 - "@types/express": ^4.17.21 - "@types/serve-index": ^1.9.4 - "@types/serve-static": ^1.15.5 - "@types/sockjs": ^0.3.36 - "@types/ws": ^8.5.10 - ansi-html-community: ^0.0.8 - bonjour-service: ^1.2.1 - chokidar: ^3.6.0 - colorette: ^2.0.10 - compression: ^1.7.4 - connect-history-api-fallback: ^2.0.0 - default-gateway: ^6.0.3 - express: ^4.17.3 - graceful-fs: ^4.2.6 - html-entities: ^2.4.0 - http-proxy-middleware: ^2.0.3 - ipaddr.js: ^2.1.0 - launch-editor: ^2.6.1 - open: ^10.0.3 - p-retry: ^6.2.0 - rimraf: ^5.0.5 - schema-utils: ^4.2.0 - selfsigned: ^2.4.1 - serve-index: ^1.9.1 - sockjs: ^0.3.24 - spdy: ^4.0.2 - webpack-dev-middleware: ^7.1.0 - ws: ^8.16.0 - peerDependencies: - webpack: ^5.0.0 - peerDependenciesMeta: - webpack: - optional: true - webpack-cli: - optional: true - bin: - webpack-dev-server: bin/webpack-dev-server.js - checksum: b3535d01e8d895f4ce6d74b5f76e29398b712476216cd6d459365e5cc2f2fb1e49240aef6c23b2b943b04dbf768d7d18301af3eb064038bde4e11d03c241202d - languageName: node - linkType: hard - "webpack-node-externals@npm:^3.0.0": version: 3.0.0 resolution: "webpack-node-externals@npm:3.0.0" @@ -39637,7 +41334,7 @@ __metadata: languageName: node linkType: hard -"webpack@npm:^5.70.0, webpack@npm:^5.89.0, webpack@npm:^5.94.0": +"webpack@npm:^5.70.0, webpack@npm:^5.89.0": version: 5.95.0 resolution: "webpack@npm:5.95.0" dependencies: @@ -39820,6 +41517,15 @@ __metadata: languageName: node linkType: hard +"win-release@npm:^1.0.0": + version: 1.1.1 + resolution: "win-release@npm:1.1.1" + dependencies: + semver: ^5.0.1 + checksum: 8943898cc4badaf8598342d63093e49ae9a64c140cf190e81472d3a8890f3387b8408181412e1b58658fe7777ce5d1e3f02eee4beeaee49909d1d17a72d52fc1 + languageName: node + linkType: hard + "winston-transport@npm:^4.5.0, winston-transport@npm:^4.7.0": version: 4.7.0 resolution: "winston-transport@npm:4.7.0" @@ -39914,7 +41620,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:*, ws@npm:8.18.0, ws@npm:^8.11.0, ws@npm:^8.13.0, ws@npm:^8.16.0, ws@npm:^8.18.0, ws@npm:^8.8.0": +"ws@npm:*, ws@npm:8.18.0, ws@npm:^8.11.0, ws@npm:^8.13.0, ws@npm:^8.18.0, ws@npm:^8.8.0": version: 8.18.0 resolution: "ws@npm:8.18.0" peerDependencies: @@ -40000,31 +41706,6 @@ __metadata: languageName: node linkType: hard -"xterm-addon-attach@npm:^0.9.0": - version: 0.9.0 - resolution: "xterm-addon-attach@npm:0.9.0" - peerDependencies: - xterm: ^5.0.0 - checksum: 70e5d3ecf139c04fae13c644b79c33858ef1a6e28dfe78f91dad3e34f5a155579029b87e91d1d016575acaf17f74e6c59402bde4bcff03461595bea0870f1ec1 - languageName: node - linkType: hard - -"xterm-addon-fit@npm:^0.8.0": - version: 0.8.0 - resolution: "xterm-addon-fit@npm:0.8.0" - peerDependencies: - xterm: ^5.0.0 - checksum: 5af2041b442f7c804eda2e6f62e3b68b5159b0ae6bd96e2aa8d85b26441df57291cbfed653d1196d4af5d9b94bfc39993df8b409a25c35e0d36bdaf6f5cdfe5f - languageName: node - linkType: hard - -"xterm@npm:^5.2.1, xterm@npm:^5.3.0": - version: 5.3.0 - resolution: "xterm@npm:5.3.0" - checksum: 1bdfdfe4cae4412128376180d85e476b43fb021cdd1114b18acad821c9ea44b5b600e0d88febf2b3572f38fad7741e5161ce0178a44369617cf937222cc6e011 - languageName: node - linkType: hard - "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -40060,12 +41741,12 @@ __metadata: languageName: node linkType: hard -"yaml@npm:2.8.0, yaml@npm:^2.7.1": - version: 2.8.0 - resolution: "yaml@npm:2.8.0" +"yaml@npm:2.8.1, yaml@npm:^2.0.0, yaml@npm:^2.2.1, yaml@npm:^2.3.3, yaml@npm:^2.5.1, yaml@npm:^2.6.0, yaml@npm:^2.6.1, yaml@npm:^2.7.0, yaml@npm:^2.7.1": + version: 2.8.1 + resolution: "yaml@npm:2.8.1" bin: yaml: bin.mjs - checksum: 66f103ca5a2f02dac0526895cc7ae7626d91aa8c43aad6fdcff15edf68b1199be4012140b390063877913441aaa5288fdf57eca30e06268a8282dd741525e626 + checksum: 35b46150d48bc1da2fd5b1521a48a4fa36d68deaabe496f3c3fa9646d5796b6b974f3930a02c4b5aee6c85c860d7d7f79009416724465e835f40b87898c36de4 languageName: node linkType: hard @@ -40076,15 +41757,6 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.0.0, yaml@npm:^2.2.1, yaml@npm:^2.3.3, yaml@npm:^2.5.1, yaml@npm:^2.6.0, yaml@npm:^2.6.1, yaml@npm:^2.7.0": - version: 2.7.1 - resolution: "yaml@npm:2.7.1" - bin: - yaml: bin.mjs - checksum: 385f8115ddfafdf8e599813cca8b2bf4e3f6a01b919fff5ae7da277e164df684d7dfe558b4085172094792b5a04786d3c55fa8b74abb0ee029873f031150bb80 - languageName: node - linkType: hard - "yargs-parser@npm:^20.2.2": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" @@ -40150,7 +41822,7 @@ __metadata: languageName: node linkType: hard -"ylru@npm:^1.2.0": +"ylru@npm:^1.2.0, ylru@npm:^1.3.2": version: 1.4.0 resolution: "ylru@npm:1.4.0" checksum: e0bf797476487e3d57a6e8790cbb749cff2089e2afc87e46bc84ce7605c329d578ff422c8e8c2ddf167681ddd218af0f58e099733ae1044cba9e9472ebedc01d @@ -40276,10 +41948,10 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.20.0, zod@npm:^3.22.4": - version: 3.23.8 - resolution: "zod@npm:3.23.8" - checksum: 15949ff82118f59c893dacd9d3c766d02b6fa2e71cf474d5aa888570c469dbf5446ac5ad562bb035bf7ac9650da94f290655c194f4a6de3e766f43febd432c5c +"zod@npm:^3.19.1, zod@npm:^3.20.0, zod@npm:^3.22.4": + version: 3.25.76 + resolution: "zod@npm:3.25.76" + checksum: c9a403a62b329188a5f6bd24d5d935d2bba345f7ab8151d1baa1505b5da9f227fb139354b043711490c798e91f3df75991395e40142e6510a4b16409f302b849 languageName: node linkType: hard @@ -40302,9 +41974,9 @@ __metadata: languageName: node linkType: hard -"zustand@npm:^4.5.6": - version: 4.5.6 - resolution: "zustand@npm:4.5.6" +"zustand@npm:^4.3.0, zustand@npm:^4.5.6": + version: 4.5.7 + resolution: "zustand@npm:4.5.7" dependencies: use-sync-external-store: ^1.2.2 peerDependencies: @@ -40318,7 +41990,7 @@ __metadata: optional: true react: optional: true - checksum: c4e9c809c92195fa2f9e8e0cd6631b6830fc9676343c8584c20cf26d402f220c54ae0479a299dbcd5e1cdfc5977f116838f1b5f39d6a4997ff727c6cebe60d3f + checksum: 103ab43456bbc3be6afe79b18a93c7fa46ffaa1aa35c45b213f13f4cd0868fee78b43c6805c6d80a822297df2e455fd021c28be94b80529ec4806b2724f20219 languageName: node linkType: hard diff --git a/e2e-tests/.eslintrc.json b/e2e-tests/.eslintrc.json deleted file mode 100644 index 5ebcabd77d..0000000000 --- a/e2e-tests/.eslintrc.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint", "filenames"], - "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], - "ignorePatterns": ["node_modules", "playwright-report", "test-results"], - "rules": { - "@typescript-eslint/naming-convention": [ - "error", - { - "selector": "variable", - "format": ["camelCase"] - }, - { - "selector": "variable", - "modifiers": ["const", "exported"], - "format": ["UPPER_CASE"] - }, - { - "selector": "function", - "format": ["camelCase"] - }, - { - "selector": "parameter", - "format": ["camelCase"], - "leadingUnderscore": "allow" - }, - { - "selector": "memberLike", - "modifiers": ["private"], - "format": ["camelCase"], - "leadingUnderscore": "allow" - }, - { - "selector": "typeLike", - "format": ["PascalCase"] - }, - { - "selector": "enumMember", - "format": ["UPPER_CASE"] - }, - { - "selector": "class", - "format": ["PascalCase"] - } - ], - "filenames/match-regex": ["error", "^[a-z0-9-.]+$", true] - } -} diff --git a/e2e-tests/.lintstagedrc.js b/e2e-tests/.lintstagedrc.js new file mode 100644 index 0000000000..44b67a0d84 --- /dev/null +++ b/e2e-tests/.lintstagedrc.js @@ -0,0 +1,8 @@ +/** + * @type {import('lint-staged').Configuration} + */ +export default { + "*": "yarn prettier:fix", + "*.{js,jsx,ts,tsx,mjs,cjs}": "yarn lint:fix", + "*.{ts,tsx}": () => "yarn tsc:check", +}; diff --git a/e2e-tests/.lintstagedrc.json b/e2e-tests/.lintstagedrc.json deleted file mode 100644 index 1e9f6fb0d1..0000000000 --- a/e2e-tests/.lintstagedrc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "*": "prettier --ignore-unknown --write", - "*.{js,jsx,ts,tsx,mjs,cjs}": "eslint --ext .js,.ts --fix" -} diff --git a/e2e-tests/data_router/data_router_metadata_template.json b/e2e-tests/data_router/data_router_metadata_template.json deleted file mode 100644 index 494da7013b..0000000000 --- a/e2e-tests/data_router/data_router_metadata_template.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "targets": { - "reportportal": { - "disabled": false, - "config": { - "hostname": "", - "project": "" - }, - "processing": { - "apply_tfa": true, - "property_filter": [".*"], - "launch": { - "name": "", - "description": "", - "attributes": [] - }, - "tfa": { - "add_attributes": true, - "auto_finalize_defect_type": true - } - } - } - } -} diff --git a/e2e-tests/eslint.config.js b/e2e-tests/eslint.config.js new file mode 100644 index 0000000000..f4e9cfebaf --- /dev/null +++ b/e2e-tests/eslint.config.js @@ -0,0 +1,123 @@ +import js from "@eslint/js"; +import tseslint from "typescript-eslint"; +import checkFile from "eslint-plugin-check-file"; +import { fileURLToPath } from "url"; +import { dirname } from "path"; +import playwright from "eslint-plugin-playwright"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +export default [ + js.configs.recommended, + ...tseslint.configs.recommended, + { + files: ["**/*.ts", "**/*.tsx"], + languageOptions: { + parserOptions: { + project: "./tsconfig.json", + tsconfigRootDir: __dirname, + }, + }, + rules: { + "@typescript-eslint/naming-convention": [ + "error", + { + selector: "variable", + format: ["camelCase"], + }, + { + selector: "variable", + modifiers: ["const", "exported"], + format: ["UPPER_CASE"], + }, + { + selector: "function", + format: ["camelCase"], + }, + { + selector: "parameter", + format: ["camelCase"], + leadingUnderscore: "allow", + }, + { + selector: "memberLike", + modifiers: ["private"], + format: ["camelCase"], + leadingUnderscore: "allow", + }, + { + selector: "typeLike", + format: ["PascalCase"], + }, + { + selector: "enumMember", + format: ["UPPER_CASE"], + }, + { + selector: "class", + format: ["PascalCase"], + }, + ], + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/await-thenable": "error", + }, + }, + { + files: ["**/*.{js,ts,jsx,tsx}"], + plugins: { + "check-file": checkFile, + }, + rules: { + "check-file/filename-naming-convention": [ + "error", + { + "**/*.{js,ts,jsx,tsx}": "KEBAB_CASE", + }, + { + ignoreMiddleExtensions: true, + }, + ], + "check-file/folder-naming-convention": [ + "error", + { + "**": "KEBAB_CASE", + }, + ], + }, + }, + { + ignores: ["node_modules/**", "playwright-report/**", "test-results/**"], + }, + // Playwright recommended rules for test files + { + ...playwright.configs["flat/recommended"], + files: ["**/*.spec.ts", "**/*.test.ts", "playwright/**/*.ts"], + rules: { + ...playwright.configs["flat/recommended"].rules, + // Only disable rules that cause errors, keep warnings + "playwright/expect-expect": "off", // Allow tests without explicit assertions + "playwright/valid-title": "off", // Allow duplicate prefixes in test titles + "playwright/valid-describe-callback": "off", // Allow async describe callbacks + "playwright/valid-expect": "error", // Keep this as error to catch missing matchers + "playwright/no-wait-for-selector": "off", // Allow wait for selector + "playwright/no-wait-for-timeout": "off", // Allow wait for timeout + "playwright/no-skipped-test": [ + "warn", + { + allowConditional: true, + }, + ], + // Custom rule to disallow test.describe.fixme() as it's not valid in Playwright + "no-restricted-syntax": [ + "error", + { + selector: + "CallExpression[callee.property.name='fixme'][callee.object.property.name='describe'][callee.object.object.name='test']", + message: + "test.describe.fixme() is not valid in Playwright. Use test.fixme() on individual tests instead.", + }, + ], + }, + }, +]; diff --git a/e2e-tests/package.json b/e2e-tests/package.json index dafab4fb9b..e1e89db4b5 100644 --- a/e2e-tests/package.json +++ b/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "e2e-tests", - "version": "1.7.0", + "version": "1.8.0", "private": true, "type": "module", "engines": { @@ -20,29 +20,34 @@ "showcase-auth-providers": "playwright test --project=showcase-auth-providers", "showcase-sanity-plugins": "playwright test --project=showcase-sanity-plugins", "lint:check": "eslint . --ext .js,.ts", - "lint:fix": "eslint . --ext .js,.ts --fix", - "postinstall": "playwright install", + "lint:fix": "eslint . \"playwright/**/*.{ts,js}\" --fix", + "postinstall": "playwright install chromium", "tsc": "tsc", + "tsc:check": "tsc -p tsconfig.json", "prettier:check": "prettier --ignore-unknown --check .", "prettier:fix": "prettier --ignore-unknown --write ." }, "devDependencies": { "@axe-core/playwright": "^4.10.2", - "@microsoft/microsoft-graph-types": "2.40.0", - "@playwright/test": "1.53.2", + "@eslint/js": "^9.34.0", + "@microsoft/microsoft-graph-types": "2.43.1", + "@playwright/test": "1.56.0", "@types/node": "22.16.3", - "@typescript-eslint/eslint-plugin": "6.21.0", - "@typescript-eslint/parser": "6.21.0", - "eslint": "8.57.1", + "@typescript-eslint/eslint-plugin": "^8.46.0", + "@typescript-eslint/parser": "^8.46.0", + "eslint": "^9.34.0", + "eslint-plugin-check-file": "^3.3.0", "eslint-plugin-filenames": "1.3.2", - "ioredis": "5.6.1", + "eslint-plugin-playwright": "^2.2.2", + "ioredis": "5.8.1", "otplib": "12.0.1", "prettier": "3.6.2", - "sealights-playwright-plugin": "^2.0.113", - "typescript": "5.8.3" + "sealights-playwright-plugin": "^2.0.124", + "typescript": "^5.9.2", + "typescript-eslint": "^8.41.0" }, "dependencies": { - "@azure/arm-network": "^34.0.0", + "@azure/arm-network": "34.0.0", "@azure/identity": "4.9.1", "@keycloak/keycloak-admin-client": "25.0.6", "@kubernetes/client-node": "0.22.3", @@ -51,9 +56,9 @@ "js-yaml": "4.1.0", "node-fetch": "2.7.0", "octokit": "4.1.4", - "uuid": "^11.1.0", + "uuid": "11.1.0", "winston": "3.14.2", - "yaml": "^2.8.0" + "yaml": "2.8.1" }, "jest": { "testTimeout": 20000 diff --git a/e2e-tests/playwright.config.ts b/e2e-tests/playwright.config.ts index ee1364709c..12ccd02600 100644 --- a/e2e-tests/playwright.config.ts +++ b/e2e-tests/playwright.config.ts @@ -25,10 +25,11 @@ export default defineConfig({ reporter: [ ["html"], ["list"], - ["junit", { outputFile: "junit-results.xml" }], + ["junit", { outputFile: process.env.JUNIT_RESULTS || "junit-results.xml" }], ], /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { + locale: process.env.LOCALE || "en", baseURL: process.env.BASE_URL, ignoreHTTPSErrors: true, /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ @@ -56,31 +57,36 @@ export default defineConfig({ }, { name: "showcase", + dependencies: ["smoke-test"], testIgnore: [ "**/playwright/e2e/plugins/rbac/**/*.spec.ts", "**/playwright/e2e/**/*-rbac.spec.ts", "**/playwright/e2e/verify-tls-config-with-external-postgres-db.spec.ts", - "**/playwright/e2e/authProviders/**/*.spec.ts", + "**/playwright/e2e/auth-providers/**/*.spec.ts", "**/playwright/e2e/plugins/bulk-import.spec.ts", "**/playwright/e2e/verify-tls-config-health-check.spec.ts", "**/playwright/e2e/configuration-test/config-map.spec.ts", "**/playwright/e2e/plugins/tekton/tekton.spec.ts", + "**/playwright/e2e/plugins/scorecard/scorecard.spec.ts", ], }, { name: "showcase-rbac", + dependencies: ["smoke-test"], testMatch: [ "**/playwright/e2e/plugins/rbac/**/*.spec.ts", "**/playwright/e2e/**/*-rbac.spec.ts", "**/playwright/e2e/verify-tls-config-with-external-postgres-db.spec.ts", "**/playwright/e2e/plugins/bulk-import.spec.ts", + "**/playwright/e2e/plugins/quick-start.spec.ts", + "**/playwright/e2e/plugins/scorecard/scorecard.spec.ts", ], }, { name: "showcase-auth-providers", - testMatch: ["**/playwright/e2e/authProviders/*.spec.ts"], + testMatch: ["**/playwright/e2e/auth-providers/*.spec.ts"], testIgnore: [ - "**/playwright/e2e/authProviders/github-happy-path.spec.ts", // temporarily disable + "**/playwright/e2e/auth-providers/github-happy-path.spec.ts", // temporarily disable "**/playwright/e2e/verify-tls-config-health-check.spec.ts", ], retries: 1, @@ -94,15 +100,16 @@ export default defineConfig({ "**/playwright/e2e/plugins/rbac/**/*.spec.ts", "**/playwright/e2e/**/*-rbac.spec.ts", "**/playwright/e2e/verify-tls-config-with-external-postgres-db.spec.ts", - "**/playwright/e2e/authProviders/**/*.spec.ts", + "**/playwright/e2e/auth-providers/**/*.spec.ts", "**/playwright/e2e/plugins/bulk-import.spec.ts", "**/playwright/e2e/plugins/tekton/tekton.spec.ts", - "**/playwright/e2e/catalog-scaffoldedfromLink.spec.ts", + "**/playwright/e2e/scaffolder-backend-module-annotator.spec.ts", "**/playwright/e2e/plugins/ocm.spec.ts", "**/playwright/e2e/audit-log/**/*.spec.ts", "**/playwright/e2e/verify-tls-config-health-check.spec.ts", "**/playwright/e2e/configuration-test/config-map.spec.ts", "**/playwright/e2e/github-happy-path.spec.ts", + "**/playwright/e2e/plugins/scorecard/scorecard.spec.ts", ], }, { @@ -113,34 +120,40 @@ export default defineConfig({ "**/playwright/e2e/plugins/rbac/**/*.spec.ts", "**/playwright/e2e/**/*-rbac.spec.ts", "**/playwright/e2e/plugins/bulk-import.spec.ts", + "**/playwright/e2e/plugins/scorecard/scorecard.spec.ts", ], }, { name: "showcase-operator", + dependencies: ["smoke-test"], testIgnore: [ "**/playwright/e2e/plugins/rbac/**/*.spec.ts", "**/playwright/e2e/**/*-rbac.spec.ts", "**/playwright/e2e/verify-tls-config-with-external-postgres-db.spec.ts", - "**/playwright/e2e/authProviders/**/*.spec.ts", + "**/playwright/e2e/auth-providers/**/*.spec.ts", "**/playwright/e2e/plugins/bulk-import.spec.ts", "**/playwright/e2e/plugins/tekton/tekton.spec.ts", - "**/playwright/e2e/catalog-scaffoldedfromLink.spec.ts", + "**/playwright/e2e/scaffolder-backend-module-annotator.spec.ts", "**/playwright/e2e/audit-log/**/*.spec.ts", "**/playwright/e2e/verify-tls-config-health-check.spec.ts", "**/playwright/e2e/configuration-test/config-map.spec.ts", "**/playwright/e2e/github-happy-path.spec.ts", + "**/playwright/e2e/plugins/scorecard/scorecard.spec.ts", ], }, { name: "showcase-operator-rbac", + dependencies: ["smoke-test"], testMatch: [ "**/playwright/e2e/plugins/rbac/**/*.spec.ts", "**/playwright/e2e/**/*-rbac.spec.ts", "**/playwright/e2e/plugins/bulk-import.spec.ts", + "**/playwright/e2e/plugins/scorecard/scorecard.spec.ts", ], }, { name: "showcase-runtime", + dependencies: ["smoke-test"], testMatch: [ "**/playwright/e2e/configuration-test/config-map.spec.ts", "**/playwright/e2e/verify-tls-config-health-check.spec.ts", @@ -149,6 +162,7 @@ export default defineConfig({ { name: "showcase-sanity-plugins", + dependencies: ["smoke-test"], testMatch: [ "**/playwright/e2e/catalog-timestamp.spec.ts", "**/playwright/e2e/plugins/frontend/sidebar.spec.ts", @@ -162,6 +176,7 @@ export default defineConfig({ }, { name: "showcase-upgrade", + dependencies: ["smoke-test"], testMatch: [ "**/playwright/e2e/home-page-customization.spec.ts", "**/playwright/e2e/plugins/quick-access-and-tech-radar.spec.ts", diff --git a/e2e-tests/playwright/e2e/audit-log/auditor-catalog.spec.ts b/e2e-tests/playwright/e2e/audit-log/auditor-catalog.spec.ts index e72969df51..4d1a6bb501 100644 --- a/e2e-tests/playwright/e2e/audit-log/auditor-catalog.spec.ts +++ b/e2e-tests/playwright/e2e/audit-log/auditor-catalog.spec.ts @@ -4,7 +4,6 @@ import { UIhelper } from "../../utils/ui-helper"; import { LogUtils } from "./log-utils"; import { CatalogImport } from "../../support/pages/catalog-import"; import { APIHelper } from "../../utils/api-helper"; - const template = "https://github.com/RoadieHQ/sample-service/blob/main/demo_template.yaml"; const entityName = "hello-world-2"; @@ -32,18 +31,25 @@ test.describe.serial("Audit Log check for Catalog Plugin", () => { let common: Common; let catalogImport: CatalogImport; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "audit-log", + }); + }); + test.beforeEach(async ({ page }) => { uiHelper = new UIhelper(page); common = new Common(page); catalogImport = new CatalogImport(page); await common.loginAsGuest(); - await page.goto("/create"); + await uiHelper.goToPageUrl("/create", "Self-service"); }); test("Should fetch logs for entity-mutate event and validate log structure and values", async () => { // Ensure the entity exists await ensureEntityExists(); - await uiHelper.clickButton("Register Existing Component"); + await uiHelper.clickButton("Import an existing Git repository"); // Register as existing (should trigger entity-mutate) await catalogImport.registerExistingComponent(template, false); await LogUtils.validateLogEvent( @@ -61,7 +67,7 @@ test.describe.serial("Audit Log check for Catalog Plugin", () => { test("Should fetch logs for location-mutate event and validate log structure and values", async () => { await ensureEntityDoesNotExist(); - await uiHelper.clickButton("Register Existing Component"); + await uiHelper.clickButton("Import an existing Git repository"); // Register as new (should trigger location-mutate) await catalogImport.registerExistingComponent(template, false); await LogUtils.validateLogEvent( diff --git a/e2e-tests/playwright/e2e/audit-log/auditor-rbac.spec.ts b/e2e-tests/playwright/e2e/audit-log/auditor-rbac.spec.ts index 3629b15551..b30b7c42db 100644 --- a/e2e-tests/playwright/e2e/audit-log/auditor-rbac.spec.ts +++ b/e2e-tests/playwright/e2e/audit-log/auditor-rbac.spec.ts @@ -13,7 +13,6 @@ import { httpMethod, } from "./rbac-test-utils"; import RhdhRbacApi from "../../support/api/rbac-api"; - let common: Common; let rbacApi: RhdhRbacApi; @@ -26,7 +25,13 @@ test.describe("Auditor check for RBAC Plugin", () => { process.env.IS_OPENSHIFT === "false", "Failing on Kubernetes clusters, fix https://issues.redhat.com/browse/RHIDP-7559", ); + test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "audit-log", + }); + await (await import("./log-utils")).LogUtils.loginToOpenShift(); const page = (await setupBrowser(browser, testInfo)).page; common = new Common(page); diff --git a/e2e-tests/playwright/e2e/audit-log/log-utils.ts b/e2e-tests/playwright/e2e/audit-log/log-utils.ts index 64060dda11..0ef83147bd 100644 --- a/e2e-tests/playwright/e2e/audit-log/log-utils.ts +++ b/e2e-tests/playwright/e2e/audit-log/log-utils.ts @@ -225,7 +225,7 @@ export class LogUtils { await LogUtils.executeCommand(command, args); console.log("Login successful."); } catch (error) { - console.error("Error during login"); + console.error("Error during login: ", error); throw new Error(`Failed to login to OpenShift`); } } diff --git a/e2e-tests/playwright/e2e/authProviders/README.md b/e2e-tests/playwright/e2e/auth-providers/README.md similarity index 100% rename from e2e-tests/playwright/e2e/authProviders/README.md rename to e2e-tests/playwright/e2e/auth-providers/README.md diff --git a/e2e-tests/playwright/e2e/authProviders/github.spec.ts b/e2e-tests/playwright/e2e/auth-providers/github.spec.ts similarity index 93% rename from e2e-tests/playwright/e2e/authProviders/github.spec.ts rename to e2e-tests/playwright/e2e/auth-providers/github.spec.ts index 1c1089838e..2104fdc443 100644 --- a/e2e-tests/playwright/e2e/authProviders/github.spec.ts +++ b/e2e-tests/playwright/e2e/auth-providers/github.spec.ts @@ -3,7 +3,6 @@ import RHDHDeployment from "../../utils/authentication-providers/rhdh-deployment import { Common, setupBrowser } from "../../utils/common"; import { UIhelper } from "../../utils/ui-helper"; import { NO_USER_FOUND_IN_CATALOG_ERROR_MESSAGE } from "../../utils/constants"; - let page: Page; let context: BrowserContext; @@ -42,6 +41,11 @@ test.describe("Configure Github Provider", async () => { test.use({ baseURL: backstageUrl }); test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "authentication", + }); + test.info().setTimeout(600 * 1000); // load default configs from yaml files await deployment.loadAllConfigs(); @@ -67,7 +71,7 @@ test.describe("Configure Github Provider", async () => { await deployment.deleteNamespaceIfExists(); // create namespace and wait for it to be active - (await deployment.createNamespace()).waitForNamespaceActive(); + await (await deployment.createNamespace()).waitForNamespaceActive(); // create all base configmaps await deployment.createAllConfigs(); @@ -77,30 +81,30 @@ test.describe("Configure Github Provider", async () => { // set enviroment variables and create secret if (!process.env.ISRUNNINGLOCAL) { - deployment.addSecretData("BASE_URL", backstageUrl); - deployment.addSecretData("BASE_BACKEND_URL", backstageBackendUrl); + await deployment.addSecretData("BASE_URL", backstageUrl); + await deployment.addSecretData("BASE_BACKEND_URL", backstageBackendUrl); } - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_GH_ORG_NAME", process.env.AUTH_PROVIDERS_GH_ORG_NAME, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_GH_ORG_CLIENT_SECRET", process.env.AUTH_PROVIDERS_GH_ORG_CLIENT_SECRET, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_GH_ORG_CLIENT_ID", process.env.AUTH_PROVIDERS_GH_ORG_CLIENT_ID, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_GH_ORG_APP_ID", process.env.AUTH_PROVIDERS_GH_ORG_APP_ID, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_GH_ORG1_PRIVATE_KEY", process.env.AUTH_PROVIDERS_GH_ORG1_PRIVATE_KEY, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_GH_ORG_WEBHOOK_SECRET", process.env.AUTH_PROVIDERS_GH_ORG_WEBHOOK_SECRET, ); @@ -136,7 +140,7 @@ test.describe("Configure Github Provider", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("RHDH QE Admin"); await common.signOut(); await context.clearCookies(); @@ -234,7 +238,7 @@ test.describe("Configure Github Provider", async () => { expect(actualDuration).toBeGreaterThan(threeDays - tolerance); expect(actualDuration).toBeLessThan(threeDays + tolerance); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("RHDH QE Admin"); await common.signOut(); await context.clearCookies(); diff --git a/e2e-tests/playwright/e2e/authProviders/ldap.spec.ts b/e2e-tests/playwright/e2e/auth-providers/ldap.spec.ts similarity index 98% rename from e2e-tests/playwright/e2e/authProviders/ldap.spec.ts rename to e2e-tests/playwright/e2e/auth-providers/ldap.spec.ts index fa15e83542..21458a097a 100644 --- a/e2e-tests/playwright/e2e/authProviders/ldap.spec.ts +++ b/e2e-tests/playwright/e2e/auth-providers/ldap.spec.ts @@ -5,7 +5,6 @@ import RHDHDeployment from "../../utils/authentication-providers/rhdh-deployment import { Common, setupBrowser } from "../../utils/common"; import { UIhelper } from "../../utils/ui-helper"; import { MSClient } from "../../utils/authentication-providers/msgraph-helper"; - let page: Page; let context: BrowserContext; @@ -42,6 +41,11 @@ test.describe("Configure LDAP Provider", async () => { test.use({ baseURL: backstageUrl }); test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "authentication", + }); + test.info().setTimeout(600 * 1000); // load default configs from yaml files await deployment.loadAllConfigs(); @@ -196,7 +200,7 @@ test.describe("Configure LDAP Provider", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("User 1"); await common.signOut(); }); diff --git a/e2e-tests/playwright/e2e/authProviders/microsoft.spec.ts b/e2e-tests/playwright/e2e/auth-providers/microsoft.spec.ts similarity index 83% rename from e2e-tests/playwright/e2e/authProviders/microsoft.spec.ts rename to e2e-tests/playwright/e2e/auth-providers/microsoft.spec.ts index 182915a274..006005e7e5 100644 --- a/e2e-tests/playwright/e2e/authProviders/microsoft.spec.ts +++ b/e2e-tests/playwright/e2e/auth-providers/microsoft.spec.ts @@ -4,7 +4,6 @@ import { Common, setupBrowser } from "../../utils/common"; import { UIhelper } from "../../utils/ui-helper"; import { MSClient } from "../../utils/authentication-providers/msgraph-helper"; import { NO_USER_FOUND_IN_CATALOG_ERROR_MESSAGE } from "../../utils/constants"; - let page: Page; let context: BrowserContext; @@ -44,6 +43,11 @@ test.describe("Configure Microsoft Provider", async () => { test.use({ baseURL: backstageUrl }); test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "authentication", + }); + test.info().setTimeout(600 * 1000); // load default configs from yaml files await deployment.loadAllConfigs(); @@ -63,7 +67,7 @@ test.describe("Configure Microsoft Provider", async () => { await deployment.deleteNamespaceIfExists(); // create namespace and wait for it to be active - (await deployment.createNamespace()).waitForNamespaceActive(); + await (await deployment.createNamespace()).waitForNamespaceActive(); // create all base configmaps await deployment.createAllConfigs(); @@ -73,38 +77,38 @@ test.describe("Configure Microsoft Provider", async () => { // set enviroment variables and create secret if (!process.env.ISRUNNINGLOCAL) { - deployment.addSecretData("BASE_URL", backstageUrl); - deployment.addSecretData("BASE_BACKEND_URL", backstageBackendUrl); + await deployment.addSecretData("BASE_URL", backstageUrl); + await deployment.addSecretData("BASE_BACKEND_URL", backstageBackendUrl); } - deployment.addSecretData( + await deployment.addSecretData( "DEFAULT_USER_PASSWORD", process.env.DEFAULT_USER_PASSWORD, ); - deployment.addSecretData( + await deployment.addSecretData( "DEFAULT_USER_PASSWORD_2", process.env.DEFAULT_USER_PASSWORD_2, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_AZURE_CLIENT_ID", process.env.AUTH_PROVIDERS_AZURE_CLIENT_ID, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_AZURE_CLIENT_SECRET", process.env.AUTH_PROVIDERS_AZURE_CLIENT_SECRET, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_AZURE_TENANT_ID", process.env.AUTH_PROVIDERS_AZURE_TENANT_ID, ); - deployment.addSecretData( + await deployment.addSecretData( "MICROSOFT_CLIENT_ID", process.env.AUTH_PROVIDERS_AZURE_CLIENT_ID, ); - deployment.addSecretData( + await deployment.addSecretData( "MICROSOFT_CLIENT_SECRET", process.env.AUTH_PROVIDERS_AZURE_CLIENT_SECRET, ); - deployment.addSecretData( + await deployment.addSecretData( "MICROSOFT_TENANT_ID", process.env.AUTH_PROVIDERS_AZURE_TENANT_ID, ); @@ -152,7 +156,7 @@ test.describe("Configure Microsoft Provider", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("TEST Zeus"); await common.signOut(); await context.clearCookies(); @@ -179,7 +183,7 @@ test.describe("Configure Microsoft Provider", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("TEST Zeus"); await common.signOut(); await context.clearCookies(); @@ -215,49 +219,51 @@ test.describe("Configure Microsoft Provider", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("TEST Zeus"); await common.signOut(); await context.clearCookies(); }); - //TODO: entiny name is "name": "zeus_rhdhtesting.onmicrosoft.com", email is "email": "zeus@rhdhtesting.onmicrosoft.com" - //not resolving? - test.skip("Login with Microsoft emailLocalPartMatchingUserEntityName resolver", async () => { - //A common sign-in resolver that looks up the user using the local part of their email address as the entity name. - await deployment.setMicrosoftResolver( - "emailLocalPartMatchingUserEntityName", - false, - ); - await deployment.updateAllConfigs(); - await deployment.restartLocalDeployment(); - await page.waitForTimeout(3000); - await deployment.waitForDeploymentReady(); + //TODO: entiny name is "name": "zeus_rhdhtesting.onmicrosoft.com", email is "email": "zeus@rhdhtesting.onmicrosoft.com" not resolving? + test.fixme( + "Login with Microsoft emailLocalPartMatchingUserEntityName resolver", + async () => { + //A common sign-in resolver that looks up the user using the local part of their email address as the entity name. + await deployment.setMicrosoftResolver( + "emailLocalPartMatchingUserEntityName", + false, + ); + await deployment.updateAllConfigs(); + await deployment.restartLocalDeployment(); + await page.waitForTimeout(3000); + await deployment.waitForDeploymentReady(); - // wait for rhdh first sync and portal to be reachable - await deployment.waitForSynced(); + // wait for rhdh first sync and portal to be reachable + await deployment.waitForSynced(); - const login = await common.MicrosoftAzureLogin( - "zeus@rhdhtesting.onmicrosoft.com", - process.env.DEFAULT_USER_PASSWORD_2, - ); - expect(login).toBe("Login successful"); + const login = await common.MicrosoftAzureLogin( + "zeus@rhdhtesting.onmicrosoft.com", + process.env.DEFAULT_USER_PASSWORD_2, + ); + expect(login).toBe("Login successful"); - await page.goto("/settings"); - await uiHelper.verifyHeading("TEST Zeus"); - await common.signOut(); - await context.clearCookies(); + await uiHelper.goToPageUrl("/settings", "Settings"); + await uiHelper.verifyHeading("TEST Zeus"); + await common.signOut(); + await context.clearCookies(); - const login2 = await common.MicrosoftAzureLogin( - "tyke@rhdhtesting.onmicrosoft.com", - process.env.DEFAULT_USER_PASSWORD_2, - ); - expect(login2).toBe("Login successful"); + const login2 = await common.MicrosoftAzureLogin( + "tyke@rhdhtesting.onmicrosoft.com", + process.env.DEFAULT_USER_PASSWORD_2, + ); + expect(login2).toBe("Login successful"); - await uiHelper.verifyAlertErrorMessage( - NO_USER_FOUND_IN_CATALOG_ERROR_MESSAGE, - ); - }); + await uiHelper.verifyAlertErrorMessage( + NO_USER_FOUND_IN_CATALOG_ERROR_MESSAGE, + ); + }, + ); test(`Set Micrisoft sessionDuration and confirm in auth cookie duration has been set`, async () => { deployment.setAppConfigProperty( @@ -293,7 +299,7 @@ test.describe("Configure Microsoft Provider", async () => { expect(actualDuration).toBeGreaterThan(threeDays - tolerance); expect(actualDuration).toBeLessThan(threeDays + tolerance); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("TEST Zeus"); await common.signOut(); }); diff --git a/e2e-tests/playwright/e2e/authProviders/oidc.spec.ts b/e2e-tests/playwright/e2e/auth-providers/oidc.spec.ts similarity index 89% rename from e2e-tests/playwright/e2e/authProviders/oidc.spec.ts rename to e2e-tests/playwright/e2e/auth-providers/oidc.spec.ts index 389b8bc518..3f0115de0b 100644 --- a/e2e-tests/playwright/e2e/authProviders/oidc.spec.ts +++ b/e2e-tests/playwright/e2e/auth-providers/oidc.spec.ts @@ -4,7 +4,6 @@ import { Common, setupBrowser } from "../../utils/common"; import { UIhelper } from "../../utils/ui-helper"; import { KeycloakHelper } from "../../utils/authentication-providers/keycloak-helper"; import { NO_USER_FOUND_IN_CATALOG_ERROR_MESSAGE } from "../../utils/constants"; - let page: Page; let context: BrowserContext; @@ -53,6 +52,11 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { test.use({ baseURL: backstageUrl }); test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "authentication", + }); + test.info().setTimeout(600 * 1000); // load default configs from yaml files await deployment.loadAllConfigs(); @@ -77,7 +81,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { await deployment.deleteNamespaceIfExists(); // create namespace and wait for it to be active - (await deployment.createNamespace()).waitForNamespaceActive(); + await (await deployment.createNamespace()).waitForNamespaceActive(); // create all base configmaps await deployment.createAllConfigs(); @@ -87,30 +91,33 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { // set enviroment variables and create secret if (!process.env.ISRUNNINGLOCAL) { - deployment.addSecretData("BASE_URL", backstageUrl); - deployment.addSecretData("BASE_BACKEND_URL", backstageBackendUrl); + await deployment.addSecretData("BASE_URL", backstageUrl); + await deployment.addSecretData("BASE_BACKEND_URL", backstageBackendUrl); } - deployment.addSecretData( + await deployment.addSecretData( "DEFAULT_USER_PASSWORD", process.env.DEFAULT_USER_PASSWORD, ); - deployment.addSecretData( + await deployment.addSecretData( "DEFAULT_USER_PASSWORD_2", process.env.DEFAULT_USER_PASSWORD_2, ); - deployment.addSecretData("RHBK_BASE_URL", process.env.RHBK_BASE_URL); - deployment.addSecretData("RHBK_REALM", process.env.RHBK_REALM); - deployment.addSecretData("RHBK_CLIENT_ID", process.env.RHBK_CLIENT_ID); - deployment.addSecretData( + await deployment.addSecretData("RHBK_BASE_URL", process.env.RHBK_BASE_URL); + await deployment.addSecretData("RHBK_REALM", process.env.RHBK_REALM); + await deployment.addSecretData( + "RHBK_CLIENT_ID", + process.env.RHBK_CLIENT_ID, + ); + await deployment.addSecretData( "RHBK_CLIENT_SECRET", process.env.RHBK_CLIENT_SECRET, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_GH_ORG_CLIENT_ID", process.env.AUTH_PROVIDERS_GH_ORG_CLIENT_ID, ); - deployment.addSecretData( + await deployment.addSecretData( "AUTH_PROVIDERS_GH_ORG_CLIENT_SECRET", process.env.AUTH_PROVIDERS_GH_ORG_CLIENT_SECRET, ); @@ -146,7 +153,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Zeus Giove"); await common.signOut(); }); @@ -171,7 +178,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Zeus Giove"); await common.signOut(); }); @@ -195,7 +202,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Zeus Giove"); await common.signOut(); }); @@ -219,7 +226,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Zeus Giove"); await common.signOut(); @@ -255,7 +262,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Zeus Giove"); await common.signOut(); @@ -264,7 +271,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { process.env.DEFAULT_USER_PASSWORD, ); expect(login2).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Atena Minerva"); await common.signOut(); }); @@ -288,7 +295,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { ); expect(login).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Atena Minerva"); await common.signOut(); }); @@ -326,7 +333,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { expect(actualDuration).toBeGreaterThan(threeDays - tolerance); expect(actualDuration).toBeLessThan(threeDays + tolerance); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Zeus Giove"); await common.signOut(); }); @@ -371,20 +378,15 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { test(`Ingestion of users and groups with invalid characters: check sanitize[User/Group]NameTransformer`, async () => { expect( - await deployment.checkUserIsIngestedInCatalog([ - "Invalid Username", - ]), + await deployment.checkUserIsIngestedInCatalog(["Invalid Username"]), ).toBe(true); expect( - await deployment.checkGroupIsIngestedInCatalog([ - "invalid@groupname", - ]), + await deployment.checkGroupIsIngestedInCatalog(["invalid@groupname"]), ).toBe(true); }); test("Ensure Guest login is disabled when setting environment to production", async () => { - await page.goto("/"); - await uiHelper.verifyHeading("Select a sign-in method"); + await uiHelper.goToPageUrl("/", "Select a sign-in method"); const singInMethods = await page .locator("div[class^='MuiCardHeader-root']") .allInnerTexts(); @@ -399,7 +401,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { expect(oidcLogin).toBe("Login successful"); - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Zeus Giove"); expect(process.env.AUTH_PROVIDERS_GH_ORG_CLIENT_SECRET).toBeDefined(); @@ -436,7 +438,7 @@ test.describe("Configure OIDC provider (using RHBK)", async () => { await page.getByTitle("Sign out from GitHub").click(); // Sign out for OIDC - await page.goto("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Zeus Giove"); await common.signOut(); await context.clearCookies(); diff --git a/e2e-tests/playwright/e2e/catalog-timestamp.spec.ts b/e2e-tests/playwright/e2e/catalog-timestamp.spec.ts index add60108ae..73ca3449a9 100644 --- a/e2e-tests/playwright/e2e/catalog-timestamp.spec.ts +++ b/e2e-tests/playwright/e2e/catalog-timestamp.spec.ts @@ -2,11 +2,12 @@ import { Page, expect, test } from "@playwright/test"; import { UIhelper } from "../utils/ui-helper"; import { Common, setupBrowser } from "../utils/common"; import { CatalogImport } from "../support/pages/catalog-import"; -import { UI_HELPER_ELEMENTS } from "../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../support/page-objects/global-obj"; let page: Page; test.describe("Test timestamp column on Catalog", () => { test.skip(() => process.env.JOB_NAME.includes("osd-gcp")); // skipping due to RHIDP-5704 on OSD Env + let uiHelper: UIhelper; let common: Common; let catalogImport: CatalogImport; @@ -15,6 +16,11 @@ test.describe("Test timestamp column on Catalog", () => { "https://github.com/janus-qe/custom-catalog-entities/blob/main/timestamp-catalog-info.yaml"; test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + page = (await setupBrowser(browser, testInfo)).page; common = new Common(page); @@ -30,9 +36,9 @@ test.describe("Test timestamp column on Catalog", () => { await uiHelper.openCatalogSidebar("Component"); }); - test("Register an existing component and verify `Created At` column and value in the Catalog Page", async () => { + test("Import an existing Git repository and verify `Created At` column and value in the Catalog Page", async () => { await uiHelper.clickButton("Self-service"); - await uiHelper.clickButton("Register Existing Component"); + await uiHelper.clickButton("Import an existing Git repository"); await catalogImport.registerExistingComponent(component); await uiHelper.openCatalogSidebar("Component"); await uiHelper.searchInputPlaceholder("timestamp-test-created"); diff --git a/e2e-tests/playwright/e2e/configuration-test/config-map.spec.ts b/e2e-tests/playwright/e2e/configuration-test/config-map.spec.ts index 6215971f84..c404959049 100644 --- a/e2e-tests/playwright/e2e/configuration-test/config-map.spec.ts +++ b/e2e-tests/playwright/e2e/configuration-test/config-map.spec.ts @@ -2,8 +2,14 @@ import { test, expect } from "@playwright/test"; import { KubeClient } from "../../utils/kube-client"; import { Common } from "../../utils/common"; import { UIhelper } from "../../utils/ui-helper"; - test.describe("Change app-config at e2e test runtime", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "configuration", + }); + }); + // operator nightly does not require this test as RDS tls test also verifies runtime change test.skip(() => process.env.JOB_NAME.includes("operator")); @@ -12,6 +18,7 @@ test.describe("Change app-config at e2e test runtime", () => { // Start with a common name, but let KubeClient find the actual ConfigMap const configMapName = "app-config-rhdh"; + // eslint-disable-next-line playwright/no-conditional-in-test const namespace = process.env.NAME_SPACE_RUNTIME || "showcase-runtime"; const deploymentName = "rhdh-developer-hub"; diff --git a/e2e-tests/playwright/e2e/custom-theme.spec.ts b/e2e-tests/playwright/e2e/custom-theme.spec.ts index e6e5d07631..c954d8ca2e 100644 --- a/e2e-tests/playwright/e2e/custom-theme.spec.ts +++ b/e2e-tests/playwright/e2e/custom-theme.spec.ts @@ -4,9 +4,8 @@ import { ThemeVerifier } from "../utils/custom-theme/theme-verifier"; import { CUSTOM_FAVICON, CUSTOM_SIDEBAR_LOGO, -} from "../support/testData/custom-theme"; +} from "../support/test-data/custom-theme"; import { ThemeConstants } from "../data/theme-constants"; - let page: Page; test.describe("CustomTheme should be applied", () => { @@ -14,14 +13,19 @@ test.describe("CustomTheme should be applied", () => { let themeVerifier: ThemeVerifier; test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + page = (await setupBrowser(browser, testInfo)).page; common = new Common(page); themeVerifier = new ThemeVerifier(page); await common.loginAsGuest(); + await page.getByRole("button", { name: "Hide" }).click(); }); - // eslint-disable-next-line no-empty-pattern test("Verify theme colors are applied and make screenshots", async ({}, testInfo: TestInfo) => { const themes = ThemeConstants.getThemes(); @@ -41,24 +45,35 @@ test.describe("CustomTheme should be applied", () => { }); test("Verify that the RHDH favicon can be customized", async () => { - expect(await page.locator("#dynamic-favicon").getAttribute("href")).toEqual( + await expect(page.locator("#dynamic-favicon")).toHaveAttribute( + "href", CUSTOM_FAVICON.LIGHT, ); }); - test("Verify that RHDH SidebarLogo can be customized", async () => { + test("Verify that RHDH CompanyLogo can be customized", async () => { await themeVerifier.setTheme("Light"); - expect(await page.getByTestId("home-logo").getAttribute("src")).toEqual( + await expect(page.getByTestId("home-logo")).toHaveAttribute( + "src", CUSTOM_SIDEBAR_LOGO.LIGHT, ); await themeVerifier.setTheme("Dark"); - expect(await page.getByTestId("home-logo").getAttribute("src")).toEqual( + await expect(page.getByTestId("home-logo")).toHaveAttribute( + "src", CUSTOM_SIDEBAR_LOGO.DARK, ); }); + test("Verify logo link", async () => { + await expect( + page.getByTestId("global-header-company-logo").locator("a"), + ).toHaveAttribute("href", "/"); + await page.getByTestId("global-header-company-logo").click(); + await expect(page).toHaveURL("/"); + }); + test("Verify that title for Backstage can be customized", async () => { await expect(page).toHaveTitle(/Red Hat Developer Hub/); }); diff --git a/e2e-tests/playwright/e2e/default-global-header.spec.ts b/e2e-tests/playwright/e2e/default-global-header.spec.ts index 91ab4f8138..e37e391056 100644 --- a/e2e-tests/playwright/e2e/default-global-header.spec.ts +++ b/e2e-tests/playwright/e2e/default-global-header.spec.ts @@ -6,6 +6,13 @@ test.describe("Default Global Header", () => { let common: Common; let uiHelper: UIhelper; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "navigation", + }); + }); + test.beforeEach(async ({ page }) => { uiHelper = new UIhelper(page); common = new Common(page); @@ -47,8 +54,7 @@ test.describe("Default Global Header", () => { await uiHelper.verifyHeading("Self-service"); }); - // TODO: Fix failing test - https://issues.redhat.com/browse/RHDHBUGS-1870 - test.skip("Verify that clicking on Support button in HelpDropdown opens a new tab", async ({ + test("Verify that clicking on Support button in HelpDropdown opens a new tab", async ({ context, page, }) => { @@ -66,7 +72,7 @@ test.describe("Default Global Header", () => { await helpDropdownButton.click(); await page.waitForTimeout(500); - expect(await uiHelper.isTextVisible("Support")).toBeTruthy(); + await uiHelper.verifyTextVisible("Support"); const [newTab] = await Promise.all([ context.waitForEvent("page"), @@ -81,13 +87,12 @@ test.describe("Default Global Header", () => { await newTab.close(); }); - // TODO: Fix failing test - https://issues.redhat.com/browse/RHDHBUGS-1870 - test.skip("Verify Profile Dropdown behaves as expected", async ({ page }) => { + test("Verify Profile Dropdown behaves as expected", async ({ page }) => { await uiHelper.openProfileDropdown(); - expect(await uiHelper.isLinkVisible("Settings")).toBeTruthy(); - expect(await uiHelper.isTextVisible("Sign out")).toBeTruthy(); + await uiHelper.verifyLinkVisible("Settings"); + await uiHelper.verifyTextVisible("Sign out"); - await uiHelper.clickLink({ href: "/settings" }); + await page.getByRole("menuitem", { name: "Settings" }).click(); await uiHelper.verifyHeading("Settings"); await uiHelper.goToMyProfilePage(); @@ -109,7 +114,7 @@ test.describe("Default Global Header", () => { await searchBar.fill("test query term"); expect(await uiHelper.isBtnVisibleByTitle("Clear")).toBeTruthy(); const dropdownList = page.locator(`ul[role="listbox"]`); - expect(await dropdownList.isVisible()).toBeTruthy(); + await expect(dropdownList).toBeVisible(); await searchBar.press("Enter"); await uiHelper.verifyHeading("Search"); const searchResultPageInput = page.locator( @@ -118,8 +123,7 @@ test.describe("Default Global Header", () => { await expect(searchResultPageInput).toHaveValue("test query term"); }); - // TODO: Fix failing test - https://issues.redhat.com/browse/RHDHBUGS-1870 - test.skip("Verify Notifications button behaves as expected", async ({ + test("Verify Notifications button behaves as expected", async ({ baseURL, request, page, diff --git a/e2e-tests/playwright/e2e/extensions.spec.ts b/e2e-tests/playwright/e2e/extensions.spec.ts index efc9482cb9..24c72bbb6f 100644 --- a/e2e-tests/playwright/e2e/extensions.spec.ts +++ b/e2e-tests/playwright/e2e/extensions.spec.ts @@ -4,11 +4,35 @@ import { UIhelper } from "../utils/ui-helper"; import { Extensions } from "../support/pages/extensions"; import { runAccessibilityTests } from "../utils/accessibility"; -test.describe("Admin > Extensions > Catalog", () => { +test.describe("Admin > Extensions", () => { let extensions: Extensions; let uiHelper: UIhelper; const isMac = process.platform === "darwin"; + const commonHeadings = [ + "Versions", + "Author", + "Tags", + "Category", + "Publisher", + "Support Provider", + ]; + const supportTypeOptions = [ + "Generally available", + "Certified", + "Custom plugin", + "Tech preview", + "Dev preview", + "Community plugin", + ]; + + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + }); + test.beforeEach(async ({ page }) => { extensions = new Extensions(page); uiHelper = new UIhelper(page); @@ -18,125 +42,502 @@ test.describe("Admin > Extensions > Catalog", () => { await uiHelper.verifyHeading("Extensions"); }); - test("Verify search bar in extensions", async ({ page }) => { - await uiHelper.searchInputPlaceholder("Dynatrace"); - await uiHelper.verifyHeading("DynaTrace"); - await page.getByRole("button", { name: "Clear Search" }).click(); - }); + test.describe("Extensions > Catalog", () => { + test("Verify search bar in extensions", async ({ page }) => { + await uiHelper.searchInputPlaceholder("Dynatrace"); + await uiHelper.verifyHeading("DynaTrace"); + await page.getByRole("button", { name: "Clear Search" }).click(); + }); - test("Verify filters in extensions", async ({ page }, testInfo) => { - await uiHelper.verifyHeading(/Plugins \(\d+\)/); - - await runAccessibilityTests(page, testInfo); - - await uiHelper.clickTab("Catalog"); - await uiHelper.clickButton("CI/CD"); - await extensions.selectDropdown("Category"); - await page.getByRole("option", { name: "CI/CD" }).isChecked(); - await page.keyboard.press(`Escape`); - await extensions.selectDropdown("Author"); - await extensions.toggleOption("Red Hat"); - await page.keyboard.press(`Escape`); - await uiHelper.verifyHeading("Red Hat Argo CD"); - await uiHelper.verifyText("by Red Hat"); - await page.getByRole("heading", { name: "Red Hat Argo CD" }).click(); - await uiHelper.verifyTableHeadingAndRows([ - "Package name", - "Version", - "Role", - "Supported version", - "Status", - ]); - await uiHelper.verifyHeading("Versions"); - await page.getByRole("button", { name: "close" }).click(); - await uiHelper.clickLink("Read more"); - await page.getByRole("button", { name: "close" }).click(); - await extensions.selectDropdown("Author"); - await extensions.toggleOption("Red Hat"); - await expect( - page.getByRole("option", { name: "Red Hat" }).getByRole("checkbox"), - ).not.toBeChecked(); - await expect( - page.getByRole("button", { name: "Red Hat" }), - ).not.toBeVisible(); - await page.keyboard.press(`Escape`); - await page.getByTestId("CancelIcon").first().click(); - await expect(page.getByLabel("Category").getByRole("combobox")).toBeEmpty(); - await page.keyboard.press(`Escape`); - }); + test("Verify category and author filters in extensions", async ({ + page, + }, testInfo) => { + await uiHelper.verifyHeading(/Plugins \(\d+\)/); - test("Verify certified badge in extensions", async ({ page }) => { - await extensions.selectDropdown("Support type"); - await extensions.toggleOption("Certified by Red Hat"); - await page.keyboard.press(`Escape`); - await uiHelper.verifyHeading("DynaTrace"); - await expect(page.getByLabel("Certified by Red Hat").first()).toBeVisible(); - await expect(extensions.badge.first()).toBeVisible(); - await extensions.badge.first().hover(); - await uiHelper.verifyTextInTooltip("Certified by Red Hat"); - await uiHelper.verifyHeading("DynaTrace"); - await page.getByRole("heading", { name: "DynaTrace" }).first().click(); - await page.getByRole("button", { name: "close" }).click(); - await uiHelper.clickLink("Read more"); - await uiHelper.verifyDivHasText(/^Certified$/); - await uiHelper.verifyText("About"); - await uiHelper.verifyHeading("Versions"); - await uiHelper.verifyTableHeadingAndRows([ - "Package name", - "Version", - "Role", - "Supported version", - "Status", - ]); - await page.getByRole("button", { name: "close" }).click(); - await extensions.selectDropdown("Support type"); - await extensions.toggleOption("Certified by Red Hat"); - await extensions.toggleOption("Verified by Red Hat"); - await page.keyboard.press(`Escape`); - await expect(page.getByLabel("Verified by Red Hat").first()).toBeVisible(); - await expect(extensions.badge.first()).toBeVisible(); - await extensions.badge.first().hover(); - await uiHelper.verifyTextInTooltip("Verified by Red Hat"); - }); + await runAccessibilityTests(page, testInfo); + + await uiHelper.clickTab("Catalog"); + await uiHelper.clickButton("CI/CD"); + await extensions.selectDropdown("Category"); + await page.getByRole("option", { name: "CI/CD" }).isChecked(); + await page.keyboard.press(`Escape`); + await extensions.selectDropdown("Author"); + await extensions.toggleOption("Red Hat"); + await page.keyboard.press(`Escape`); + await uiHelper.verifyHeading("Red Hat Argo CD"); + await uiHelper.verifyText("by Red Hat"); + await page.getByRole("heading", { name: "Red Hat Argo CD" }).click(); + await uiHelper.verifyTableHeadingAndRows([ + "Package name", + "Version", + "Role", + "Backstage compatibility version", + "Status", + ]); + await uiHelper.verifyHeading("Versions"); + await page.getByRole("button", { name: "close" }).click(); + await uiHelper.clickLink("Read more"); + await page.getByRole("button", { name: "close" }).click(); + await extensions.selectDropdown("Author"); + await extensions.toggleOption("Red Hat"); + await expect( + page.getByRole("option", { name: "Red Hat" }).getByRole("checkbox"), + ).not.toBeChecked(); + await expect(page.getByRole("button", { name: "Red Hat" })).toBeHidden(); + await page.keyboard.press(`Escape`); + await expect( + page.getByLabel("Category").getByRole("combobox"), + ).toBeEmpty(); + await page.keyboard.press(`Escape`); + }); + + test("Verify support type filters in extensions", async ({ page }) => { + await extensions.selectDropdown("Support type"); + await expect(page.getByRole("listbox")).toBeVisible(); + + // Verify all support type options are present + for (const option of supportTypeOptions) { + await expect(page.getByRole("listbox")).toContainText(option); + } + + await page.keyboard.press("Escape"); + await expect( + page.getByLabel("Category").getByRole("combobox"), + ).toBeEmpty(); + }); + + test("Verify certified badge in extensions", async ({ page }) => { + await extensions.selectDropdown("Support type"); + await extensions.toggleOption("Certified"); + await page.keyboard.press(`Escape`); + await uiHelper.verifyHeading("DynaTrace"); + await expect( + page.getByLabel("Certified by Red Hat").first(), + ).toBeVisible(); + await expect(extensions.badge.first()).toBeVisible(); + await extensions.badge.first().hover(); + await uiHelper.verifyTextInTooltip("Certified by Red Hat"); + await uiHelper.verifyHeading("DynaTrace"); + await page.getByRole("heading", { name: "DynaTrace" }).first().click(); + await page.getByRole("button", { name: "close" }).click(); + await uiHelper.clickLink("Read more"); + await expect( + page.getByLabel("Stable and secured by Red Hat").getByText("Certified"), + ).toBeVisible(); + await uiHelper.verifyText("About"); + await uiHelper.verifyHeading("Versions"); + await uiHelper.verifyTableHeadingAndRows([ + "Package name", + "Version", + "Role", + "Backstage compatibility version", + "Status", + ]); + await page.getByRole("button", { name: "close" }).click(); + await extensions.selectDropdown("Support type"); + await extensions.toggleOption("Certified"); + }); + + test("Verify Generally available badge in extensions", async ({ page }) => { + await extensions.selectSupportTypeFilter("Generally available (GA)"); + + await expect( + page + .getByLabel("Generally available (GA) and supported by Red Hat") + .first(), + ).toBeVisible(); + await expect(extensions.badge.first()).toBeVisible(); + await extensions.badge.first().hover(); + await uiHelper.verifyTextInTooltip( + "Generally available (GA) and supported by Red Hat", + ); + + await uiHelper.clickLink("Read more"); + await expect( + page + .getByLabel("Production-ready and supported by Red Hat") + .getByText("Generally available (GA)"), + ).toBeVisible(); + + for (const heading of commonHeadings) { + console.log(`Verifying heading: ${heading}`); + await uiHelper.verifyHeading(heading); + } + + await page.getByRole("button", { name: "close" }).click(); + + await extensions.resetSupportTypeFilter("Generally available (GA)"); + }); + + // Skipping below test due to the issue: https://issues.redhat.com/browse/RHDHBUGS-2104 + test.skip("Verify custom plugin badge in extensions", async ({ page }) => { + await extensions.selectDropdown("Support type"); + await extensions.toggleOption("Custom plugin"); + await page.keyboard.press(`Escape`); + await expect(page.getByLabel("Custom plugins").first()).toBeVisible(); + await expect(extensions.badge.first()).toBeVisible(); + await extensions.badge.first().hover(); + await uiHelper.verifyTextInTooltip("Custom plugins"); + await uiHelper.clickLink("Read more"); + await expect( + page + .getByLabel("Plugins added by the administrator") + .getByText("Custom"), + ).toBeVisible(); + await page.getByRole("button", { name: "close" }).click(); + await extensions.selectDropdown("Support type"); + await extensions.toggleOption("Custom plugin"); + await page.keyboard.press(`Escape`); + }); + + test("Verify tech preview badge in extensions", async () => { + await extensions.verifySupportTypeBadge({ + supportType: "Tech preview (TP)", + pluginName: "Bulk Import", + badgeLabel: "Plugin still in development", + badgeText: "Tech preview (TP)", + tooltipText: "", + searchTerm: "Bulk Import", + headings: ["About", "Versions", ...commonHeadings], + includeTable: true, + includeAbout: false, + }); + }); - test.use({ - permissions: ["clipboard-read", "clipboard-write"], + test("Verify dev preview badge in extensions", async () => { + await extensions.selectSupportTypeFilter("Dev preview (DP)"); + await uiHelper.verifyHeading("Developer Lightspeed"); + + await extensions.verifyPluginDetails({ + pluginName: "Developer Lightspeed", + badgeLabel: "An early-stage, experimental", + badgeText: "Dev preview (DP)", + headings: commonHeadings, + includeTable: true, + includeAbout: false, + }); + + await extensions.resetSupportTypeFilter("Dev preview (DP)"); + }); + + test("Verify community plugin badge in extensions", async ({ page }) => { + await extensions.selectSupportTypeFilter("Community plugin"); + + await extensions.clickReadMoreByPluginTitle( + "ServiceNow Integration for Red Hat Developer Hub", + ); + await expect( + page + .getByLabel("Open-source plugins, no official support") + .getByText("Community plugin"), + ).toBeVisible(); + + await uiHelper.verifyText("About"); + for (const heading of commonHeadings) { + console.log(`Verifying heading: ${heading}`); + await uiHelper.verifyHeading(heading); + } + + await expect(page.getByText("AuthorRed Hat")).toBeVisible(); + + await page.getByRole("button", { name: "close" }).click(); + await extensions.resetSupportTypeFilter("Community plugin"); + }); + + test.use({ + permissions: ["clipboard-read", "clipboard-write"], + }); + + test("Verify plugin configuration can be viewed in the production environment", async ({ + page, + }) => { + const productionEnvAlert = page + .locator('div[class*="MuiAlertTitle-root"]') + .first(); + productionEnvAlert.getByText( + "Plugin installation is disabled in the production environment.", + { exact: true }, + ); + await uiHelper.searchInputPlaceholder("Topology"); + await extensions.waitForSearchResults("Topology"); + await extensions.clickReadMoreByPluginTitle("Topology"); + await uiHelper.clickButton("View"); + await uiHelper.verifyHeading("Application Topology for Kubernetes"); + await uiHelper.verifyText( + "- package: ./dynamic-plugins/dist/backstage-community-plugin-topology", + ); + await uiHelper.verifyText("disabled: false"); + await uiHelper.verifyText("Apply"); + await uiHelper.verifyHeading("Default configuration"); + await uiHelper.clickButton("Apply"); + await uiHelper.verifyText("pluginConfig:"); + await uiHelper.verifyText("dynamicPlugins:"); + await uiHelper.clickTab("About the plugin"); + await uiHelper.verifyHeading("Configuring The Plugin"); + await uiHelper.clickTab("Examples"); + await uiHelper.clickByDataTestId("ContentCopyRoundedIcon"); + await expect(page.getByRole("button", { name: "✔" })).toBeVisible(); + await uiHelper.clickButton("Reset"); + await expect(page.getByText("pluginConfig:")).toBeHidden(); + // eslint-disable-next-line playwright/no-conditional-in-test + const modifier = isMac ? "Meta" : "Control"; + await page.keyboard.press(`${modifier}+KeyA`); + await page.keyboard.press(`${modifier}+KeyV`); + await uiHelper.verifyText("pluginConfig:"); + await page.locator("button[class^='copy-button']").nth(0).click(); + await expect( + page.getByRole("button", { name: "✔" }).nth(0), + ).toBeVisible(); + const clipboardContent = await page.evaluate(() => + navigator.clipboard.readText(), + ); + expect(clipboardContent).not.toContain("pluginConfig:"); + expect(clipboardContent).toContain( + "backstage-community.plugin-topology:", + ); + await uiHelper.clickButton("Back"); + await expect(page.getByRole("button", { name: "View" })).toBeVisible(); + await uiHelper.verifyHeading("Application Topology for Kubernetes"); + }); + + //Following test is disabled for CI as plugin installation is disabled in CI + test.skip("Enable plugin from catalog extension page", async ({ page }) => { + await uiHelper.clickTab("Catalog"); + await extensions.clickReadMoreByPluginTitle( + "Adoption Insights for Red Hat Developer Hub", + ); + await uiHelper.verifyHeading("Adoption Insights for Red Hat"); + await page.getByTestId("plugin-actions").click(); + await expect(page.getByLabel("EditPlugin")).toBeVisible(); + await page.getByTestId("disable-plugin").click(); + const alertText = await page.getByRole("alert").first().textContent(); + expect(alertText).toContain("Backend restart required"); + expect(alertText).toContain( + "The Adoption Insights for Red Hat Developer Hub plugin requires a restart of the backend system to finish installing, updating, enabling or disabling.", + ); + }); }); - test("Verify plugin configuration can be viewed", async ({ page }) => { - await uiHelper.searchInputPlaceholder("Topology"); - await page.getByRole("heading", { name: "Topology" }).first().click(); - await uiHelper.clickButton("View"); - await uiHelper.verifyHeading("Install Application Topology for Kubernetes"); - await uiHelper.verifyText( - "- package: ./dynamic-plugins/dist/backstage-community-plugin-topology", - ); - await uiHelper.verifyText("disabled: false"); - await uiHelper.verifyText("Apply"); - await uiHelper.verifyHeading("Default configuration"); - await uiHelper.clickButton("Apply"); - await uiHelper.verifyText("pluginConfig:"); - await uiHelper.verifyText("dynamicPlugins:"); - await uiHelper.clickTab("About the plugin"); - await uiHelper.verifyHeading("Configuring The Plugin"); - await uiHelper.clickTab("Examples"); - await uiHelper.clickByDataTestId("ContentCopyRoundedIcon"); - await expect(page.getByRole("button", { name: "✔" })).toBeVisible(); - await uiHelper.clickButton("Reset"); - await expect(page.getByText("pluginConfig:")).not.toBeVisible(); - const modifier = isMac ? "Meta" : "Control"; - await page.keyboard.press(`${modifier}+KeyA`); - await page.keyboard.press(`${modifier}+KeyV`); - await uiHelper.verifyText("pluginConfig:"); - await page.locator("button[class^='copy-button']").click(); - await expect(page.getByRole("button", { name: "✔" }).nth(1)).toBeVisible(); - const clipboardContent = await page.evaluate(() => - navigator.clipboard.readText(), - ); - expect(clipboardContent).not.toContain("pluginConfig:"); - expect(clipboardContent).toContain("backstage-community.plugin-topology:"); - await uiHelper.clickButton("Back"); - await expect(page.getByRole("button", { name: "View" })).toBeVisible(); - await uiHelper.verifyHeading("Application Topology for Kubernetes"); + test.describe("Extensions > Installed Plugin", () => { + test.beforeEach(async () => { + await uiHelper.clickTab("Installed packages"); + await uiHelper.verifyHeading(/Installed packages \(\d+\)/); + }); + + test("Installed packages page", async ({ page }, testInfo) => { + await runAccessibilityTests(page, testInfo); + await uiHelper.verifyTableHeadingAndRows([ + "name", + "npm package name", + "Role", + "Version", + "Actions", + ]); + await page.waitForTimeout(2000); + await page.getByRole("button", { name: "Name", exact: true }).click(); + await expect( + page.getByRole("cell", { name: "Techdocs" }).first(), + ).toBeVisible(); + await expect( + page.getByRole("cell", { + name: "backstage-plugin-techdocs-module-addons-contrib", + }), + ).toBeVisible(); + await expect( + page.getByRole("cell", { name: "Frontend plugin module" }), + ).toBeVisible(); + await expect(page.getByRole("cell", { name: "1.1.27" })).toBeVisible(); + await expect( + page.locator(".v5-MuiBox-root.css-1i27l4i").first(), + ).toBeVisible(); + await page.getByRole("button", { name: "Rows per page: 5 rows" }).click(); + await page.getByRole("option", { name: "10", exact: true }).click(); + await page + .locator("div") + .getByRole("button", { name: "Rows per page: 10 rows" }) + .scrollIntoViewIfNeeded(); + await expect( + page.getByRole("button", { name: "Rows per page: 10 rows" }), + ).toBeVisible(); + await expect( + page.getByRole("button", { name: "Next Page" }), + ).toBeVisible(); + await expect( + page.getByRole("button", { name: "Previous Page" }), + ).toBeVisible(); + }); + + test("Topology package sidebar for CI", async ({ page }) => { + await page.getByRole("textbox", { name: "Search" }).click(); + await page.getByRole("textbox", { name: "Search" }).fill("Topology"); + await expect( + page.getByRole("cell", { name: "backstage-community-plugin-topology" }), + ).toBeVisible(); + await expect( + page + .getByRole("row", { name: "Topology backstage-community" }) + .getByTestId("EditIcon"), + ).toBeVisible(); + await expect( + page + .getByRole("row", { + name: "Topology backstage-community-plugin-topology", + }) + .getByTestId("FileDownloadOutlinedIcon"), + ).toBeVisible(); + await expect( + page + .getByRole("row", { + name: "Topology backstage-community-plugin-topology", + }) + .getByRole("checkbox"), + ).toBeVisible(); + await page + .getByRole("link", { + name: "Topology", + }) + .click(); + await expect( + page.getByRole("heading", { + name: "Topology", + }), + ).toBeVisible(); + await expect(page.getByRole("button", { name: "View" })).toBeVisible(); + await page.getByRole("button", { name: "View" }).hover(); + // Following commented code to be updated when the tooltip message is available in the production env with pr https://github.com/redhat-developer/rhdh/pull/3565 + // await uiHelper.verifyTextInTooltip( + // "You don't have permission to install plugins or view their configurations. Contact your administrator to request access or assistance", + // ); + await page.getByRole("button", { name: "close" }).click(); + await expect( + page + .getByRole("cell", { + name: "To enable actions, add a catalog entity for this package", + }) + .first(), + ).toBeVisible(); + }); + + //Following test is disabled for CI as plugin installation is disabled in CI + test.skip("Edit Analytics provider segment package through side menu ", async ({ + page, + }) => { + await page.getByRole("textbox", { name: "Search" }).click(); + await page + .getByRole("textbox", { name: "Search" }) + .fill("Analytics provider segment"); + await expect( + page.getByRole("cell", { name: "Analytics Provider Segment" }), + ).toBeVisible(); + await page + .getByRole("link", { name: "Analytics Provider Segment" }) + .click(); + await page.getByTestId("plugin-actions").click(); + await page.getByTestId("edit-configuration").click(); + await uiHelper.verifyHeading("Edit instructions"); + await expect(page.getByRole("tab", { name: "Examples" })).toBeVisible(); + await uiHelper.verifyHeading( + "backstage-community-plugin-analytics-provider-segment", + ); + await expect(page.getByText("SaveCancelReset")).toBeVisible(); + await expect(page.getByText('plugins: - package: "./')).toBeVisible(); + await page.getByRole("button", { name: "Apply" }).click(); + await expect( + page.locator( + '.v5-MuiCardContent-root [data-mode-id="yaml"] [role="code"]', + ), + ).toContainText("testMode: ${SEGMENT_TEST_MODE}"); + await page.getByRole("button", { name: "Reset" }).click(); + await expect( + page.locator( + '.v5-MuiCardContent-root [data-mode-id="yaml"] [role="code"]', + ), + ).not.toContainText("testMode: ${SEGMENT_TEST_MODE}"); + await page.getByRole("button", { name: "Cancel" }).click(); + await expect( + page + .locator("div") + .filter({ hasText: "Analytics Provider Segmentby" }) + .nth(4), + ).toBeVisible(); + await page.getByRole("button", { name: "close" }).click(); + }); + + //Following test is disabled for CI as plugin installation is disabled in CI + test.skip("Edit Analytics provider segment package through action cell in the installed package row ", async ({ + page, + }) => { + await page.getByRole("textbox", { name: "Search" }).click(); + await page + .getByRole("textbox", { name: "Search" }) + .fill("Analytics provider segment"); + await expect( + page.getByRole("cell", { name: "Analytics Provider Segment" }), + ).toBeVisible(); + await page + .getByRole("button", { name: "Edit package configuration" }) + .click(); + await uiHelper.verifyHeading("Edit instructions"); + await expect(page.getByText("SaveCancelReset")).toBeVisible(); + await page.getByRole("button", { name: "Save" }).click(); + await uiHelper.verifyHeading(/Installed packages \(\d+\)/, 10000); + await expect(page.getByRole("alert").first()).toContainText( + "The Analytics Provider Segment package requires a restart of the backend system to finish installing, updating, enabling or disabling.", + { timeout: 10000 }, + ); + }); + + //Following test is disabled for CI as plugin installation is disabled in CI + test.skip("Plugin enable-disable toggle in action cell in the installed package row ", async ({ + page, + }) => { + await page.getByRole("textbox", { name: "Search" }).click(); + await page + .getByRole("textbox", { name: "Search" }) + .fill("Dynamic Home Page"); + await expect( + page.getByRole("cell", { name: "Dynamic Home Page" }), + ).toBeVisible(); + await page.getByRole("checkbox").hover(); + await expect(page.getByLabel("Disable package")).toBeVisible(); + await page.getByRole("checkbox").click(); + await expect(page.getByRole("alert").first()).toContainText( + "The red-hat-developer-hub-backstage-plugin-dynamic-home-page package requires a restart of the backend system to finish installing, updating, enabling or disabling.", + { timeout: 15000 }, + ); + await page.getByRole("textbox", { name: "Search" }).fill("Global Header"); + await expect( + page.getByRole("cell", { name: "Global Header" }), + ).toBeVisible(); + await page.getByRole("checkbox").hover(); + await expect(page.getByLabel("Disable package")).toBeVisible(); + await page.getByRole("checkbox").click(); + + await page.getByRole("button", { name: "View packages" }).click(); + await expect( + page + .getByLabel("Backend restart required") + .getByText("Backend restart required"), + ).toBeVisible({ timeout: 10000 }); + + const packageVerifications = [ + { rowTitle: "Name", rowValue: "Action" }, + { + rowTitle: "red-hat-developer-hub-backstage-plugin-dynamic-home-page", + rowValue: "Package disabled", + }, + { + rowTitle: "red-hat-developer-hub-backstage-plugin-global-header", + rowValue: "Package disabled", + }, + ]; + + for (const { rowTitle, rowValue } of packageVerifications) { + await extensions.verifyKeyValueRowElements(rowTitle, rowValue); + } + + await expect(page.getByText("To finish the package")).toBeVisible(); + await page.getByRole("button", { name: "close", exact: true }).click(); + }); }); }); diff --git a/e2e-tests/playwright/e2e/github-discovery.spec.ts b/e2e-tests/playwright/e2e/github-discovery.spec.ts index 3811ddb290..5e0bb2ebb4 100644 --- a/e2e-tests/playwright/e2e/github-discovery.spec.ts +++ b/e2e-tests/playwright/e2e/github-discovery.spec.ts @@ -4,7 +4,6 @@ import { CATALOG_FILE, JANUS_QE_ORG } from "../utils/constants"; import { Common } from "../utils/common"; import { assert } from "console"; import { Catalog } from "../support/pages/catalog"; - type GithubDiscoveryFixture = { catalogPage: Catalog; githubApi: GithubApi; @@ -16,34 +15,43 @@ const test = base.extend({ await new Common(page).loginAsGithubUser(); const catalog = new Catalog(page); await catalog.go(); - use(catalog); + await use(catalog); }, githubApi: new GithubApi(), testOrganization: JANUS_QE_ORG, }); -//TODO: skipping due to RHIDP-4992 -test.describe.skip("Github Discovery Catalog", () => { - test(`Discover Organization's Catalog`, async ({ - catalogPage, - githubApi, - testOrganization, - }) => { - const organizationRepos = await githubApi.getReposFromOrg(testOrganization); - const reposNames: string[] = organizationRepos.map((repo) => repo["name"]); - const realComponents: string[] = reposNames.filter( - async (repo) => - await githubApi.fileExistsOnRepo( - `${testOrganization}/${repo}`, - CATALOG_FILE, - ), - ); - - for (let i = 0; i != realComponents.length; i++) { - const repo = realComponents[i]; - await catalogPage.search(repo); - const row = await catalogPage.tableRow(repo); - assert(await row.isVisible()); - } +test.describe("Github Discovery Catalog", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "api", + }); }); + + //TODO: https://issues.redhat.com/browse/RHIDP-4992 + test.fixme( + `Discover Organization's Catalog`, + async ({ catalogPage, githubApi, testOrganization }) => { + const organizationRepos = + await githubApi.getReposFromOrg(testOrganization); + const reposNames: string[] = organizationRepos.map( + (repo) => repo["name"], + ); + const realComponents: string[] = reposNames.filter( + async (repo) => + await githubApi.fileExistsOnRepo( + `${testOrganization}/${repo}`, + CATALOG_FILE, + ), + ); + + for (let i = 0; i != realComponents.length; i++) { + const repo = realComponents[i]; + await catalogPage.search(repo); + const row = await catalogPage.tableRow(repo); + assert(await row.isVisible()); + } + }, + ); }); diff --git a/e2e-tests/playwright/e2e/github-happy-path.spec.ts b/e2e-tests/playwright/e2e/github-happy-path.spec.ts index 8a5735d25d..4c93da91a4 100644 --- a/e2e-tests/playwright/e2e/github-happy-path.spec.ts +++ b/e2e-tests/playwright/e2e/github-happy-path.spec.ts @@ -1,18 +1,17 @@ import { test, expect, Page, BrowserContext } from "@playwright/test"; import { UIhelper } from "../utils/ui-helper"; import { Common, setupBrowser } from "../utils/common"; -import { RESOURCES } from "../support/testData/resources"; +import { RESOURCES } from "../support/test-data/resources"; import { BackstageShowcase, CatalogImport, } from "../support/pages/catalog-import"; -import { TEMPLATES } from "../support/testData/templates"; +import { TEMPLATES } from "../support/test-data/templates"; let page: Page; let context: BrowserContext; -// test suite skipped for now, until it's migrated back to the main showcase job -test.describe("GitHub Happy path", async () => { +test.describe.serial("GitHub Happy path", async () => { let common: Common; let uiHelper: UIhelper; let catalogImport: CatalogImport; @@ -22,6 +21,11 @@ test.describe("GitHub Happy path", async () => { "https://github.com/redhat-developer/rhdh/blob/main/catalog-entities/all.yaml"; test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + ({ page, context } = await setupBrowser(browser, testInfo)); uiHelper = new UIhelper(page); common = new Common(page); @@ -44,17 +48,16 @@ test.describe("GitHub Happy path", async () => { }); test("Verify Profile is Github Account Name in the Settings page", async () => { - await page.goto("/settings"); - await expect(page).toHaveURL("/settings"); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading(process.env.GH_USER2_ID); await uiHelper.verifyHeading(`User Entity: ${process.env.GH_USER2_ID}`); }); - test("Register an existing component", async () => { + test("Import an existing Git repository", async () => { await uiHelper.openSidebar("Catalog"); await uiHelper.selectMuiBox("Kind", "Component"); await uiHelper.clickButton("Self-service"); - await uiHelper.clickButton("Register Existing Component"); + await uiHelper.clickButton("Import an existing Git repository"); await catalogImport.registerExistingComponent(component); }); @@ -80,7 +83,7 @@ test.describe("GitHub Happy path", async () => { await uiHelper.openSidebar("Catalog"); await uiHelper.selectMuiBox("Kind", "User"); await uiHelper.searchInputPlaceholder("rhdh"); - await uiHelper.verifyRowsInTable(["rhdh-qe"]); + await uiHelper.verifyRowsInTable(["rhdh-qe rhdh-qe"]); }); test("Verify all 12 Software Templates appear in the Create page", async () => { @@ -104,10 +107,15 @@ test.describe("GitHub Happy path", async () => { timeout: 20000, }); // Optionally, verify that the current URL contains the expected path - await expect(page.url()).toContain(expectedPath); + expect(page.url()).toContain(expectedPath); await common.clickOnGHloginPopup(); await uiHelper.verifyLink("About RHDH", { exact: false }); + + // Workaround for RHDHBUGS-2091: Change the size to 10 to avoid information not being displayed + await page.getByRole("button", { name: "20" }).click(); + await page.getByRole("option", { name: "10", exact: true }).click(); + await backstageShowcase.verifyPRStatisticsRendered(); await backstageShowcase.verifyAboutCardIsDisplayed(); }); @@ -180,33 +188,45 @@ test.describe("GitHub Happy path", async () => { await backstageShowcase.verifyPRRowsPerPage(20, allPRs); }); - test("Verify that the CI tab renders 5 most recent github actions and verify the table properly displays the actions when page sizes are changed and filters are applied", async () => { - await page.locator("a").getByText("CI", { exact: true }).first().click(); - await common.checkAndClickOnGHloginPopup(); - - const workflowRuns = await backstageShowcase.getWorkflowRuns(); - - for (const workflowRun of workflowRuns.slice(0, 5)) { - await uiHelper.verifyText(workflowRun.id); - } - }); - - test("Click on the Dependencies tab and verify that all the relations have been listed and displayed", async () => { - await uiHelper.clickTab("Dependencies"); - for (const resource of RESOURCES) { - const resourceElement = page.locator( - `#workspace:has-text("${resource}")`, - ); - await resourceElement.scrollIntoViewIfNeeded(); - await expect(resourceElement).toBeVisible(); - } - }); - - test("Sign out and verify that you return back to the Sign in page", async () => { - await uiHelper.goToSettingsPage(); - await common.signOut(); - context.clearCookies(); - }); + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2099 + test.fixme( + "Verify that the CI tab renders 5 most recent github actions and verify the table properly displays the actions when page sizes are changed and filters are applied", + async () => { + await page.locator("a").getByText("CI", { exact: true }).first().click(); + await common.checkAndClickOnGHloginPopup(); + + const workflowRuns = await backstageShowcase.getWorkflowRuns(); + + for (const workflowRun of workflowRuns.slice(0, 5)) { + await uiHelper.verifyText(workflowRun.id); + } + }, + ); + + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2099 + test.fixme( + "Click on the Dependencies tab and verify that all the relations have been listed and displayed", + async () => { + await uiHelper.clickTab("Dependencies"); + for (const resource of RESOURCES) { + const resourceElement = page.locator( + `#workspace:has-text("${resource}")`, + ); + await resourceElement.scrollIntoViewIfNeeded(); + await expect(resourceElement).toBeVisible(); + } + }, + ); + + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2099 + test.fixme( + "Sign out and verify that you return back to the Sign in page", + async () => { + await uiHelper.goToPageUrl("/settings", "Settings"); + await common.signOut(); + await context.clearCookies(); + }, + ); test.afterAll(async () => { await page.close(); diff --git a/e2e-tests/playwright/e2e/github-integration-org-fetch.spec.ts b/e2e-tests/playwright/e2e/github-integration-org-fetch.spec.ts index f6df658d1a..8e7f128ead 100644 --- a/e2e-tests/playwright/e2e/github-integration-org-fetch.spec.ts +++ b/e2e-tests/playwright/e2e/github-integration-org-fetch.spec.ts @@ -1,9 +1,15 @@ import { test, Page } from "@playwright/test"; import { UIhelper } from "../utils/ui-helper"; import { Common, setupBrowser } from "../utils/common"; - let page: Page; test.describe.serial("GitHub integration with Org data fetching", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "api", + }); + }); + test.skip(() => process.env.JOB_NAME.includes("osd-gcp")); // skipping due to RHIDP-5704 on OSD Env let common: Common; let uiHelper: UIhelper; @@ -15,7 +21,6 @@ test.describe.serial("GitHub integration with Org data fetching", () => { await common.loginAsKeycloakUser(); }); - // eslint-disable-next-line no-empty-pattern test.beforeEach(({}, testInfo) => { if (testInfo.retry > 0) { // progressively increase test timeout for retries @@ -47,6 +52,6 @@ test.describe.serial("GitHub integration with Org data fetching", () => { await uiHelper.selectMuiBox("Kind", "User"); await uiHelper.searchInputPlaceholder("r"); - await uiHelper.verifyRowsInTable(["rhdh-qe"]); + await uiHelper.verifyRowsInTable(["rhdh-qe rhdh-qe"]); }); }); diff --git a/e2e-tests/playwright/e2e/google-signin-happy-path.spec.ts b/e2e-tests/playwright/e2e/google-signin-happy-path.spec.ts index 3919caddec..8eb91f3b19 100644 --- a/e2e-tests/playwright/e2e/google-signin-happy-path.spec.ts +++ b/e2e-tests/playwright/e2e/google-signin-happy-path.spec.ts @@ -1,9 +1,16 @@ import { test, Page } from "@playwright/test"; import { Common } from "../utils/common"; import { UIhelper } from "../utils/ui-helper"; - let page: Page; -test.describe.skip("Google signin happy path", () => { + +test.describe("Google signin happy path", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "authentication", + }); + }); + let uiHelper: UIhelper; let common: Common; const googleUserId = process.env.GOOGLE_USER_ID; @@ -25,8 +32,9 @@ test.describe.skip("Google signin happy path", () => { await common.loginAsGuest(); }); - test("Verify Google Sign in", async () => { - await uiHelper.goToSettingsPage(); + // TODO: https://issues.redhat.com/browse/RHDHBUGS-675 + test.fixme("Verify Google Sign in", async () => { + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.clickTab("Authentication Providers"); await page.getByTitle("Sign in to Google").click(); await uiHelper.clickButton("Log in"); diff --git a/e2e-tests/playwright/e2e/guest-signin-happy-path.spec.ts b/e2e-tests/playwright/e2e/guest-signin-happy-path.spec.ts index c9082295f6..48028c3137 100644 --- a/e2e-tests/playwright/e2e/guest-signin-happy-path.spec.ts +++ b/e2e-tests/playwright/e2e/guest-signin-happy-path.spec.ts @@ -2,8 +2,14 @@ import { test } from "@playwright/test"; import { UIhelper } from "../utils/ui-helper"; import { HomePage } from "../support/pages/home-page"; import { Common } from "../utils/common"; - test.describe("Guest Signing Happy path", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "authentication", + }); + }); + let uiHelper: UIhelper; let homePage: HomePage; let common: Common; @@ -22,14 +28,13 @@ test.describe("Guest Signing Happy path", () => { }); test("Verify Profile is Guest in the Settings page", async () => { - await uiHelper.goToSettingsPage(); + await uiHelper.goToPageUrl("/settings", "Settings"); await uiHelper.verifyHeading("Guest"); await uiHelper.verifyHeading("User Entity: guest"); }); test("Sign Out and Verify that you return to the Sign-in page", async () => { - await uiHelper.goToSettingsPage(); - await uiHelper.goToSettingsPage(); + await uiHelper.goToPageUrl("/settings", "Settings"); await common.signOut(); }); }); diff --git a/e2e-tests/playwright/e2e/header-mount-points.spec.ts b/e2e-tests/playwright/e2e/header-mount-points.spec.ts index 79de979281..4e24ed1c87 100644 --- a/e2e-tests/playwright/e2e/header-mount-points.spec.ts +++ b/e2e-tests/playwright/e2e/header-mount-points.spec.ts @@ -1,11 +1,17 @@ import { expect, test } from "@playwright/test"; import { UIhelper } from "../utils/ui-helper"; import { Common } from "../utils/common"; - test.describe("Header mount points", () => { let common: Common; let uiHelper: UIhelper; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "navigation", + }); + }); + test.beforeEach(async ({ page }) => { common = new Common(page); uiHelper = new UIhelper(page); @@ -18,7 +24,7 @@ test.describe("Header mount points", () => { }) => { const header = page.locator("nav[id='global-header']"); await expect(header).toBeVisible(); - uiHelper.verifyLink({ label: "test-logo" }); + await uiHelper.verifyLink({ label: "test-logo" }); }); test("Verify that additional header button component from a custom header plugin in global header is visible", async ({ @@ -26,8 +32,8 @@ test.describe("Header mount points", () => { }) => { const header = page.locator("nav[id='global-header']"); await expect(header).toBeVisible(); - expect( - await header.locator("button", { hasText: "Test Button" }), + await expect( + header.locator("button", { hasText: "Test Button" }), ).toHaveCount(1); }); diff --git a/e2e-tests/playwright/e2e/home-page-customization.spec.ts b/e2e-tests/playwright/e2e/home-page-customization.spec.ts index 254fe12dc9..d9a938fb5f 100644 --- a/e2e-tests/playwright/e2e/home-page-customization.spec.ts +++ b/e2e-tests/playwright/e2e/home-page-customization.spec.ts @@ -9,6 +9,13 @@ test.describe("Home page customization", () => { let uiHelper: UIhelper; let homePage: HomePage; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + }); + test.beforeEach(async ({ page }) => { uiHelper = new UIhelper(page); common = new Common(page); diff --git a/e2e-tests/playwright/e2e/instance-health-check.spec.ts b/e2e-tests/playwright/e2e/instance-health-check.spec.ts index ef836a7adf..734505fd69 100644 --- a/e2e-tests/playwright/e2e/instance-health-check.spec.ts +++ b/e2e-tests/playwright/e2e/instance-health-check.spec.ts @@ -1,13 +1,21 @@ import { test, expect } from "@playwright/test"; +test.describe("Application health check", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + }); -test("Application health check", async ({ request }) => { - const healthCheckEndpoint = "/healthcheck"; + test("Application health check", async ({ request }) => { + const healthCheckEndpoint = "/healthcheck"; - const response = await request.get(healthCheckEndpoint); + const response = await request.get(healthCheckEndpoint); - const responseBody = await response.json(); + const responseBody = await response.json(); - expect(response.status()).toBe(200); + expect(response.status()).toBe(200); - expect(responseBody).toHaveProperty("status", "ok"); + expect(responseBody).toHaveProperty("status", "ok"); + }); }); diff --git a/e2e-tests/playwright/e2e/learning-path-page.spec.ts b/e2e-tests/playwright/e2e/learning-path-page.spec.ts index 9419229682..de7b7e0927 100644 --- a/e2e-tests/playwright/e2e/learning-path-page.spec.ts +++ b/e2e-tests/playwright/e2e/learning-path-page.spec.ts @@ -4,6 +4,13 @@ import { Common } from "../utils/common"; import { runAccessibilityTests } from "../utils/accessibility"; test.describe("Learning Paths", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + }); + let common: Common; let uiHelper: UIhelper; @@ -24,7 +31,7 @@ test.describe("Learning Paths", () => { .locator(`div[class*="MuiGrid-item"]>a[target="_blank"]`) .nth(i); await expect(learningPathCard).toBeVisible(); - expect(await learningPathCard.getAttribute("href")).not.toBe(""); + await expect(learningPathCard).not.toHaveAttribute("href", ""); } await runAccessibilityTests(page, testInfo); diff --git a/e2e-tests/playwright/e2e/localization/locale-test.spec.ts b/e2e-tests/playwright/e2e/localization/locale-test.spec.ts new file mode 100644 index 0000000000..b58db7a70f --- /dev/null +++ b/e2e-tests/playwright/e2e/localization/locale-test.spec.ts @@ -0,0 +1,51 @@ +import { test, expect } from "@playwright/test"; +import { + getTranslations, + getLocale, +} from "../../support/translations/settings"; +import { Common } from "../../utils/common"; +import { UIhelper } from "../../utils/ui-helper"; + +const t = getTranslations(); + +test.describe(`RHDH Localization - ${t.settings.rhdhLanguage}`, () => { + test.beforeEach(async ({ page }) => { + const common = new Common(page); + const uiHelper = new UIhelper(page); + await common.loginAsGuest(); + await uiHelper.goToPageUrl("/settings", "Settings"); + }); + + // Run tests only for the selected language + test(`Should display correct language section ARIA content in ${t.settings.rhdhLanguage}`, async ({ + page, + }) => { + await page.getByRole("button", { name: "Hide" }).click(); + await expect(page.getByRole("list").first()).toMatchAriaSnapshot(` + - listitem: + - text: Language + - paragraph: Change the language + `); + + await expect(page.getByTestId("select").locator("div")).toContainText( + t.settings.rhdhLanguage, + ); + await page + .getByTestId("select") + .getByRole("button", { name: t.settings.rhdhLanguage }) + .click(); + await expect(page.getByRole("listbox")).toMatchAriaSnapshot(` + - listbox: + - option "English" + - option "Français" + - option "Deutsch" + `); + const french = getLocale("fr"); + await page + .getByRole("option", { name: french.settings.rhdhLanguage }) + .click(); + await expect(page.getByTestId("select").locator("div")).toContainText( + french.settings.rhdhLanguage, + ); + }); +}); diff --git a/e2e-tests/playwright/e2e/plugins/acr.spec.ts b/e2e-tests/playwright/e2e/plugins/acr.spec.ts index fcf1b815ec..6184da18ea 100644 --- a/e2e-tests/playwright/e2e/plugins/acr.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/acr.spec.ts @@ -4,6 +4,13 @@ import { Common, setupBrowser } from "../../utils/common"; let page; test.describe("Test ACR plugin", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + let uiHelper: UIhelper; let common: Common; const dateRegex = diff --git a/e2e-tests/playwright/e2e/plugins/adoption-Insights/adoption-Insights.spec.ts b/e2e-tests/playwright/e2e/plugins/adoption-insights/adoption-insights.spec.ts similarity index 59% rename from e2e-tests/playwright/e2e/plugins/adoption-Insights/adoption-Insights.spec.ts rename to e2e-tests/playwright/e2e/plugins/adoption-insights/adoption-insights.spec.ts index be7d8b6885..e7093572fe 100644 --- a/e2e-tests/playwright/e2e/plugins/adoption-Insights/adoption-Insights.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/adoption-insights/adoption-insights.spec.ts @@ -1,10 +1,20 @@ -import { test, expect } from '@playwright/test'; +import { test, expect } from "@playwright/test"; import { Common } from "../../../utils/common"; -import { UIhelper } from "../../../utils/ui-helper"; -import { TestHelper } from "../../../support/pages/adoption-Insights"; +import { UIhelper } from "../../../utils/ui-helper"; +import { TestHelper } from "../../../support/pages/adoption-insights"; + +/* eslint-disable playwright/no-conditional-in-test */ test.describe.serial("Test Adoption Insights", () => { - test.describe.serial("Test Adoption Insights plugin: load permission policies and conditions from files", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + + test.describe + .serial("Test Adoption Insights plugin: load permission policies and conditions from files", () => { let context; let page; let testHelper: TestHelper; @@ -21,28 +31,26 @@ test.describe.serial("Test Adoption Insights", () => { uiHelper = new UIhelper(page); testHelper = new TestHelper(page); await new Common(page).loginAsKeycloakUser(); - await page.goto("/"); + await uiHelper.goToPageUrl("/", "Welcome back!"); }); test.afterAll(async () => { await context?.close(); }); - test("Check UI navigation by nav bar when adoption-insights is enabled", async () => { - await uiHelper.openSidebarButton("Administration"); - await uiHelper.clickLink('Adoption Insights'); + await uiHelper.openSidebarButton("Administration"); + await uiHelper.clickLink("Adoption Insights"); await testHelper.waitForPanelApiCalls(page); - await testHelper.waitUntilApiCallSucceeds(page); - + await uiHelper.verifyHeading("Adoption Insights"); expect(page.url()).toContain("adoption-insights"); }); test("Select date range", async () => { const dateRanges = ["Today", "Last week", "Last month", "Last year"]; - await testHelper.clickByText('Last 28 days'); + await testHelper.clickByText("Last 28 days"); for (const range of dateRanges) { await expect(page.getByRole("option", { name: range })).toBeVisible(); } @@ -53,7 +61,7 @@ test.describe.serial("Test Adoption Insights", () => { }); await expect(datePicker).toBeVisible(); await datePicker.getByRole("button", { name: "Cancel" }).click(); - await expect(datePicker).not.toBeVisible(); + await expect(datePicker).toBeHidden(); await Promise.all([ testHelper.waitForPanelApiCalls(page), @@ -66,8 +74,14 @@ test.describe.serial("Test Adoption Insights", () => { hasText: "Active users", }); await expect(panel.locator(".recharts-surface")).toBeVisible(); - await expect(panel.getByText(/^\d+ active users per hour$/)).toBeVisible(); - await expect(panel.getByRole('button', { name: 'Export CSV' })).toBeVisible(); + await expect( + panel.getByText( + /^Average peak active user count was \d+ per hour for this period\.$/, + ), + ).toBeVisible(); + await expect( + panel.getByRole("button", { name: "Export CSV" }), + ).toBeVisible(); }); test("Total number of users panel shows visitor of 100", async () => { @@ -76,33 +90,35 @@ test.describe.serial("Test Adoption Insights", () => { }); await expect(panel.locator(".recharts-surface")).toBeVisible(); await expect(panel.getByText(/^\d+of 100$/)).toBeVisible(); - await expect(panel.getByText(/^\d+%have logged in$/)).toBeVisible(); + await expect(panel.getByText(/^\d+%have logged in$/)).toBeVisible(); }); test("Data shows in Top plugins Entity", async () => { - await testHelper.expectTopEntriesToBePresent("Top 3 plugins"); + await testHelper.expectTopEntriesToBePresent("plugins"); }); - + test("Rest of the panels are visible", async () => { - const titles = [ - "templates", - "catalog entities", - "techdocs", - "Searches", - ]; - + const titles = ["templates", "catalog entities", "techdocs", "Searches"]; + for (const title of titles) { - const panel = page.locator(".v5-MuiPaper-root", { hasText: title }).last(); + const panel = page + .locator(".v5-MuiPaper-root", { hasText: title }) + .last(); await expect(panel).toBeVisible(); - - if (title === "catalog entities" || title === "techdocs" || title === "templates") { + + if ( + title === "catalog entities" || + title === "techdocs" || + title === "templates" + ) { const firstRow = await testHelper.getVisibleFirstRowText(panel); - + if (title === "templates") templatesFirstEntry = firstRow; - else if (title === "catalog entities") catalogEntitiesFirstEntry = firstRow; + else if (title === "catalog entities") + catalogEntitiesFirstEntry = firstRow; else if (title === "techdocs") techdocsFirstEntry = firstRow; } - + if (title === "Searches") { const count = await testHelper.getCountFromPanel(panel); initialSearchCount = count || 0; @@ -119,63 +135,70 @@ test.describe.serial("Test Adoption Insights", () => { uiHelper, templatesFirstEntry, catalogEntitiesFirstEntry, - techdocsFirstEntry + techdocsFirstEntry, ); // Do a search - await page.getByPlaceholder('Search...').fill('Dummy search'); + await page.getByPlaceholder("Search...").fill("Dummy search"); await testHelper.waitUntilApiCallSucceeds(page); - await expect(page.getByText('No results found')).toBeVisible(); - + await expect(page.getByText("No results found")).toBeVisible(); + await uiHelper.clickLink("Catalog"); await testHelper.waitUntilApiCallSucceeds(page); - await uiHelper.clickLink('Adoption Insights'); - await testHelper.clickByText('Last 28 days'); + await uiHelper.clickLink("Adoption Insights"); + await testHelper.clickByText("Last 28 days"); await Promise.all([ testHelper.waitForPanelApiCalls(page), testHelper.selectOption("Today"), ]); }); - + test("Visited component shows up in top catalog entities", async () => { - await testHelper.expectTopEntriesToBePresent("Top catalog entities"); + await testHelper.expectTopEntriesToBePresent("catalog entities"); }); - + test("Visited techdoc shows up in top techdocs", async () => { - await testHelper.expectTopEntriesToBePresent("Top 3 techdocs"); + await testHelper.expectTopEntriesToBePresent("techdocs"); }); - + test("Visited templates shows in top templates", async () => { - await testHelper.expectTopEntriesToBePresent("Top 3 templates"); + await testHelper.expectTopEntriesToBePresent("templates"); }); - test("Changes are Reflecting in panels", async () => { - const titles = [ - "catalog entities", - "techdocs", - ]; + const titles = ["catalog entities", "techdocs"]; interface PanelState { - firstRow?: any; + firstRow?: string[]; initialViewsCount?: number; } - - let state: Record = { + + const state: Record = { "catalog entities": {}, - "techdocs": {}, + techdocs: {}, }; for (const title of titles) { - const panel = page.locator(".v5-MuiPaper-root", { hasText: title }).last(); - if (title === "catalog entities" || title === "techdocs" || title === "templates") { - state[title].firstRow = await testHelper.getVisibleFirstRowText(panel); - - if (title === "catalog entities") catalogEntitiesFirstEntry = state[title].firstRow; - else if (title === "techdocs") techdocsFirstEntry = state[title].firstRow; + const panel = page + .locator(".v5-MuiPaper-root", { hasText: title }) + .last(); + if ( + title === "catalog entities" || + title === "techdocs" || + title === "templates" + ) { + state[title].firstRow = + await testHelper.getVisibleFirstRowText(panel); + + if (title === "catalog entities") + catalogEntitiesFirstEntry = state[title].firstRow; + else if (title === "techdocs") + techdocsFirstEntry = state[title].firstRow; } - const firstRow = panel.locator('table.v5-MuiTable-root tbody tr').first(); - const firstEntry = firstRow.locator('td').first(); + const firstRow = panel + .locator("table.v5-MuiTable-root tbody tr") + .first(); + const firstEntry = firstRow.locator("td").first(); state[title].firstRow = firstRow; let headerTxt: string; @@ -183,22 +206,23 @@ test.describe.serial("Test Adoption Insights", () => { if (title === "techdocs") { headerTxt = techdocsFirstEntry[0]; state[title].initialViewsCount = Number(techdocsFirstEntry[1]); - if(headerTxt === "docs") { + if (headerTxt === "docs") { headerTxt = "Documentation"; } await testHelper.clickAndVerifyText(firstEntry, headerTxt); - } else if (title === "catalog entities") { headerTxt = catalogEntitiesFirstEntry[0]; - state[title].initialViewsCount = Number(catalogEntitiesFirstEntry[1]); + state[title].initialViewsCount = Number( + catalogEntitiesFirstEntry[1], + ); await testHelper.clickAndVerifyText(firstEntry, headerTxt); } } await page.reload(); await testHelper.waitUntilApiCallSucceeds(page); await uiHelper.openSidebarButton("Administration"); - await uiHelper.clickLink('Adoption Insights'); - await testHelper.clickByText('Last 28 days'); + await uiHelper.clickLink("Adoption Insights"); + await testHelper.clickByText("Last 28 days"); await Promise.all([ testHelper.waitForPanelApiCalls(page), testHelper.selectOption("Today"), @@ -206,10 +230,18 @@ test.describe.serial("Test Adoption Insights", () => { await testHelper.waitUntilApiCallSucceeds(page); for (const title of titles) { - const finalViews = await state[title].firstRow.locator('td').last(); - await state[title].firstRow.waitFor({ state: "visible" }); + const panel = page + .locator(".v5-MuiPaper-root", { hasText: title }) + .last(); + const firstRow = panel + .locator("table.v5-MuiTable-root tbody tr") + .first(); + const finalViews = firstRow.locator("td").last(); + await firstRow.waitFor({ state: "visible" }); const finalViewsCount = await finalViews.textContent(); - expect(Number(finalViewsCount)).toBeGreaterThan(state[title].initialViewsCount); + expect(Number(finalViewsCount)).toBeGreaterThan( + state[title].initialViewsCount, + ); } }); @@ -218,11 +250,12 @@ test.describe.serial("Test Adoption Insights", () => { hasText: "searches", }); await expect(panel.locator(".recharts-surface")).toBeVisible(); - await expect(panel).toContainText(/An average of \d+ searches per hour were conducted during this period\./); + await expect(panel).toContainText( + /Average search count was \d+ per \w+ for this period\./, + ); const recount = await testHelper.getCountFromPanel(panel); expect(recount).toBeGreaterThan(initialSearchCount); }); - }); }); }); diff --git a/e2e-tests/playwright/e2e/plugins/analytics/analytics-disabled-rbac.spec.ts b/e2e-tests/playwright/e2e/plugins/analytics/analytics-disabled-rbac.spec.ts index ea4e8c8fc3..a2cb8d1e8e 100644 --- a/e2e-tests/playwright/e2e/plugins/analytics/analytics-disabled-rbac.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/analytics/analytics-disabled-rbac.spec.ts @@ -2,19 +2,28 @@ import { test, expect } from "@playwright/test"; import { Analytics } from "../../../utils/analytics/analytics"; import { APIHelper } from "../../../utils/api-helper"; -test('Check "analytics-provider-segment" plugin is disabled', async () => { - const analytics = new Analytics(); - const api = new APIHelper(); +test.describe('Check "analytics-provider-segment" plugin is disabled', () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "monitoring", + }); + }); - // This test uses the Guest token to check the loaded plugins. - // Static token is not allowed to list the plugins. - // If this breaks, we can use RhdhAuthApiHack to get the User token. - const authHeader = await api.getGuestAuthHeader(); - const pluginsList = await analytics.getLoadedDynamicPluginsList(authHeader); - const isPluginListed = analytics.checkPluginListed( - pluginsList, - "backstage-community-plugin-analytics-provider-segment", - ); + test('Check "analytics-provider-segment" plugin is disabled', async () => { + const analytics = new Analytics(); + const api = new APIHelper(); - expect(isPluginListed).toBe(false); + // This test uses the Guest token to check the loaded plugins. + // Static token is not allowed to list the plugins. + // If this breaks, we can use RhdhAuthApiHack to get the User token. + const authHeader = await api.getGuestAuthHeader(); + const pluginsList = await analytics.getLoadedDynamicPluginsList(authHeader); + const isPluginListed = analytics.checkPluginListed( + pluginsList, + "backstage-community-plugin-analytics-provider-segment", + ); + + expect(isPluginListed).toBe(false); + }); }); diff --git a/e2e-tests/playwright/e2e/plugins/analytics/analytics-enabled.spec.ts b/e2e-tests/playwright/e2e/plugins/analytics/analytics-enabled.spec.ts index 628f7407c4..078e476869 100644 --- a/e2e-tests/playwright/e2e/plugins/analytics/analytics-enabled.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/analytics/analytics-enabled.spec.ts @@ -2,19 +2,28 @@ import { test, expect } from "@playwright/test"; import { Analytics } from "../../../utils/analytics/analytics"; import { APIHelper } from "../../../utils/api-helper"; -test('Check "analytics-provider-segment" plugin is enabled', async () => { - const analytics = new Analytics(); - const api = new APIHelper(); +test.describe('Check "analytics-provider-segment" plugin is enabled', () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "monitoring", + }); + }); - // This test uses the Guest token to check the loaded plugins. - // Static token is not allowed to list the plugins. - // If this breaks, we can use RhdhAuthApiHack to get the User token. - const authHeader = await api.getGuestAuthHeader(); - const pluginsList = await analytics.getLoadedDynamicPluginsList(authHeader); - const isPluginListed = analytics.checkPluginListed( - pluginsList, - "backstage-community-plugin-analytics-provider-segment", - ); + test('Check "analytics-provider-segment" plugin is enabled', async () => { + const analytics = new Analytics(); + const api = new APIHelper(); - expect(isPluginListed).toBe(true); + // This test uses the Guest token to check the loaded plugins. + // Static token is not allowed to list the plugins. + // If this breaks, we can use RhdhAuthApiHack to get the User token. + const authHeader = await api.getGuestAuthHeader(); + const pluginsList = await analytics.getLoadedDynamicPluginsList(authHeader); + const isPluginListed = analytics.checkPluginListed( + pluginsList, + "backstage-community-plugin-analytics-provider-segment", + ); + + expect(isPluginListed).toBe(true); + }); }); diff --git a/e2e-tests/playwright/e2e/plugins/application-listener.spec.ts b/e2e-tests/playwright/e2e/plugins/application-listener.spec.ts index b787e5a52d..a9a1de6e09 100644 --- a/e2e-tests/playwright/e2e/plugins/application-listener.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/application-listener.spec.ts @@ -3,6 +3,13 @@ import { UIhelper } from "../../utils/ui-helper"; import { Common } from "../../utils/common"; test.describe("Test ApplicationListener", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + let uiHelper: UIhelper; test.beforeEach(async ({ page }) => { diff --git a/e2e-tests/playwright/e2e/plugins/application-provider.spec.ts b/e2e-tests/playwright/e2e/plugins/application-provider.spec.ts index e6a8990389..6990451805 100644 --- a/e2e-tests/playwright/e2e/plugins/application-provider.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/application-provider.spec.ts @@ -1,9 +1,16 @@ import { expect, test } from "@playwright/test"; import { UIhelper } from "../../utils/ui-helper"; import { Common } from "../../utils/common"; -import { UI_HELPER_ELEMENTS } from "../../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../../support/page-objects/global-obj"; test.describe("Test ApplicationProvider", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + let uiHelper: UIhelper; test.beforeEach(async ({ page }) => { @@ -13,7 +20,7 @@ test.describe("Test ApplicationProvider", () => { }); test("Verify that the TestPage is rendered", async ({ page }) => { - await page.goto("/application-provider-test-page"); + await uiHelper.goToPageUrl("/application-provider-test-page"); await uiHelper.verifyText("application/provider TestPage"); await uiHelper.verifyText( "This card will work only if you register the TestProviderOne and TestProviderTwo correctly.", @@ -30,8 +37,8 @@ test.describe("Test ApplicationProvider", () => { .locator("button") .filter({ hasText: "+" }); await contextOneIncrementButton.click(); - expect(contextOneFirstLocator.getByText("1")).toBeVisible(); - expect(contextOneSecondLocator.getByText("1")).toBeVisible(); + await expect(contextOneFirstLocator.getByText("1")).toBeVisible(); + await expect(contextOneSecondLocator.getByText("1")).toBeVisible(); await uiHelper.verifyTextinCard("Context two", "Context two"); const contextTwoFirstLocator = page @@ -44,7 +51,7 @@ test.describe("Test ApplicationProvider", () => { .locator("button") .filter({ hasText: "+" }); await contextTwoIncrementButton.click(); - expect(contextTwoFirstLocator.getByText("1")).toBeVisible(); - expect(contextTwoSecondLocator.getByText("1")).toBeVisible(); + await expect(contextTwoFirstLocator.getByText("1")).toBeVisible(); + await expect(contextTwoSecondLocator.getByText("1")).toBeVisible(); }); }); diff --git a/e2e-tests/playwright/e2e/plugins/bulk-import.spec.ts b/e2e-tests/playwright/e2e/plugins/bulk-import.spec.ts index 8ef669dd34..2e28118e55 100644 --- a/e2e-tests/playwright/e2e/plugins/bulk-import.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/bulk-import.spec.ts @@ -7,23 +7,40 @@ import { CatalogImport } from "../../support/pages/catalog-import"; import { DEFAULT_CATALOG_INFO_YAML, UPDATED_CATALOG_INFO_YAML, -} from "../../support/testData/bulk-import"; +} from "../../support/test-data/bulk-import"; // Pre-req : plugin-bulk-import & plugin-bulk-import-backend-dynamic test.describe.serial("Bulk Import plugin", () => { - test.fixme(); // TODO: Fix failing tests - https://issues.redhat.com/browse/RHDHBUGS-1869 test.skip(() => process.env.JOB_NAME.includes("osd-gcp")); // skipping due to RHIDP-5704 on OSD Env + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2116 + test.fixme(() => process.env.JOB_TYPE.includes("presubmit")); // skip on PR checks + test.fixme(() => !process.env.JOB_NAME.includes("ocp")); // run only on OCP jobs to avoid GH rate limit + test.describe.configure({ retries: process.env.CI ? 5 : 0 }); + let page: Page; let uiHelper: UIhelper; let common: Common; + let bulkimport: BulkImport; + const catalogRepoName = `janus-test-1-bulk-import-test-${Date.now()}`; const catalogRepoDetails = { - name: "janus-test-1-bulk-import-test", - url: "github.com/janus-test/janus-test-1-bulk-import-test", + name: catalogRepoName, + url: `github.com/janus-test/${catalogRepoName}`, org: "github.com/janus-test", owner: "janus-test", }; + + const catalogInfoYamlContent = `apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: ${catalogRepoName} + annotations: + github.com/project-slug: janus-test/${catalogRepoName} +spec: + type: other + lifecycle: unknown + owner: user:default/rhdh-qe-2`; const newRepoName = `bulk-import-${Date.now()}`; const newRepoDetails = { owner: "janus-test", @@ -32,13 +49,27 @@ test.describe.serial("Bulk Import plugin", () => { labels: `bulkimport1: test1;bulkimport2: test2`, repoUrl: `github.com/janus-test/${newRepoName}`, }; + test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + page = (await setupBrowser(browser, testInfo)).page; uiHelper = new UIhelper(page); common = new Common(page); bulkimport = new BulkImport(page); + // Create the repository with catalog-info.yaml file dynamically + await APIHelper.createGitHubRepoWithFile( + catalogRepoDetails.owner, + catalogRepoDetails.name, + "catalog-info.yaml", + catalogInfoYamlContent, + ); + await bulkimport.newGitHubRepo( newRepoDetails.owner, newRepoDetails.repoName, @@ -52,15 +83,16 @@ test.describe.serial("Bulk Import plugin", () => { // Select two repos: one with an existing catalog.yaml file and another without it test("Add a Repository from the Repository Tab and Confirm its Preview", async () => { await uiHelper.openSidebar("Bulk import"); - await uiHelper.clickButton("Add"); + await uiHelper.clickButton("Import"); await uiHelper.searchInputPlaceholder(catalogRepoDetails.name); + await uiHelper.verifyRowInTableByUniqueText(catalogRepoDetails.name, [ "Not Generated", ]); await bulkimport.selectRepoInTable(catalogRepoDetails.name); await uiHelper.verifyRowInTableByUniqueText(catalogRepoDetails.name, [ catalogRepoDetails.url, - "Ready Preview file", + "Ready to import Preview file", ]); await uiHelper.clickOnLinkInTableByUniqueText( @@ -78,7 +110,7 @@ test.describe.serial("Bulk Import plugin", () => { await uiHelper.verifyRowInTableByUniqueText(newRepoDetails.owner, [ new RegExp(`github.com/${newRepoDetails.owner}`), /1\/(\d+) Edit/, - /Ready Preview file/, + /Ready to import Preview file/, ]); await uiHelper.clickOnLinkInTableByUniqueText(newRepoDetails.owner, "Edit"); await bulkimport.searchInOrg(newRepoDetails.repoName); @@ -87,14 +119,14 @@ test.describe.serial("Bulk Import plugin", () => { await uiHelper.verifyRowInTableByUniqueText(newRepoDetails.owner, [ new RegExp(`github.com/${newRepoDetails.owner}`), /2\/(\d+) Edit/, - /Ready Preview files/, + /Ready to import Preview files/, ]); - await expect( - await uiHelper.clickButton("Create pull requests"), - ).toBeDisabled({ timeout: 10000 }); + await expect(await uiHelper.clickButton("Import")).toBeDisabled({ + timeout: 10000, + }); }); - test('Verify that the two selected repositories are listed: one with the status "Added" and another with the status "WAIT_PR_APPROVAL."', async () => { + test('Verify that the two selected repositories are listed: one with the status "Already imported" and another with the status "WAIT_PR_APPROVAL."', async () => { await common.waitForLoad(); await bulkimport.filterAddedRepo(catalogRepoDetails.name); await uiHelper.verifyRowInTableByUniqueText(catalogRepoDetails.name, [ @@ -134,7 +166,7 @@ test.describe.serial("Bulk Import plugin", () => { newRepoDetails.updatedComponentName, ); await bulkimport.fillTextInputByNameAtt("prLabels", newRepoDetails.labels); - await expect(await uiHelper.clickButton("Save")).not.toBeVisible(); + await expect(await uiHelper.clickButton("Save")).toBeHidden(); const prCatalogInfoYaml = await APIHelper.getfileContentFromPR( newRepoDetails.owner, @@ -151,12 +183,12 @@ test.describe.serial("Bulk Import plugin", () => { expect(prCatalogInfoYaml).toEqual(expectedCatalogInfoYaml); }); - test("Verify Selected repositories shows catalog-info.yaml status as 'Added' and 'WAIT_PR_APPROVAL'", async () => { + test("Verify Selected repositories shows catalog-info.yaml status as 'Already imported' and 'WAIT_PR_APPROVAL'", async () => { await uiHelper.openSidebar("Bulk import"); - await uiHelper.clickButton("Add"); + await uiHelper.clickButton("Import"); await uiHelper.searchInputPlaceholder(catalogRepoDetails.name); await uiHelper.verifyRowInTableByUniqueText(catalogRepoDetails.name, [ - "Added", + "Already imported", ]); await uiHelper.searchInputPlaceholder(newRepoDetails.repoName); await uiHelper.verifyRowInTableByUniqueText(newRepoDetails.repoName, [ @@ -164,7 +196,7 @@ test.describe.serial("Bulk Import plugin", () => { ]); }); - test("Merge the PR on GitHub and Confirm the Status Updates to 'Added'", async () => { + test("Merge the PR on GitHub and Confirm the Status Updates to 'Already imported'", async () => { await uiHelper.openSidebar("Bulk import"); // Merge PR is generated for the repository without the catalog.yaml file. await APIHelper.mergeGitHubPR( @@ -182,13 +214,13 @@ test.describe.serial("Bulk Import plugin", () => { ).toHaveLength(0); await bulkimport.filterAddedRepo(newRepoDetails.repoName); - // verify that the status has changed to "ADDED." + // verify that the status has changed to "Already imported." await uiHelper.clickOnButtonInTableByUniqueText( newRepoDetails.repoName, "Refresh", ); await uiHelper.verifyRowInTableByUniqueText(newRepoDetails.repoName, [ - "Added", + "Already imported", ]); }); @@ -226,16 +258,34 @@ test.describe.serial("Bulk Import plugin", () => { }); test.afterAll(async () => { - await APIHelper.deleteGitHubRepo( - newRepoDetails.owner, - newRepoDetails.repoName, - ); + try { + // Delete the dynamically created GitHub repository with catalog-info.yaml + await APIHelper.deleteGitHubRepo( + catalogRepoDetails.owner, + catalogRepoDetails.name, + ); + + // Delete the GitHub repository + await APIHelper.deleteGitHubRepo( + newRepoDetails.owner, + newRepoDetails.repoName, + ); + + console.log( + `[Cleanup] Deleted GitHub repositories: ${catalogRepoDetails.name}, ${newRepoDetails.repoName}`, + ); + } catch (error) { + console.error(`[Cleanup] Final cleanup failed: ${error.message}`); + } }); }); test.describe .serial("Bulk Import - Verify existing repo are displayed in bulk import Added repositories", () => { test.skip(() => process.env.JOB_NAME.includes("osd-gcp")); // skipping due to RHIDP-5704 on OSD Env + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2116 + test.fixme(() => process.env.JOB_TYPE.includes("presubmit")); // skip on PR checks + test.fixme(() => !process.env.JOB_NAME.includes("ocp")); // run only on OCP jobs to avoid GH rate limit let page: Page; let uiHelper: UIhelper; let common: Common; @@ -266,15 +316,15 @@ test.describe await common.waitForLoad(); await bulkimport.filterAddedRepo(existingRepoFromAppConfig); await uiHelper.verifyRowInTableByUniqueText(existingRepoFromAppConfig, [ - "Added", + "Already imported", ]); }); - test('Verify repo from "register existing component" are displayed in bulk import Added repositories', async () => { - // Register Existing Component + test('Verify repo from "import an existing git repository" are displayed in bulk import Added repositories', async () => { + // Import an existing Git repository await uiHelper.openSidebar("Catalog"); await uiHelper.clickButton("Self-service"); - await uiHelper.clickButton("Register Existing Component"); + await uiHelper.clickButton("Import an existing Git repository"); await catalogImport.registerExistingComponent( existingComponentDetails.url, true, @@ -286,7 +336,7 @@ test.describe await bulkimport.filterAddedRepo(existingComponentDetails.repoName); await uiHelper.verifyRowInTableByUniqueText( existingComponentDetails.repoName, - ["Added"], + ["Already imported"], ); }); }); @@ -294,6 +344,9 @@ test.describe test.describe .serial("Bulk Import - Ensure users without bulk import permissions cannot access the bulk import plugin", () => { test.skip(() => process.env.JOB_NAME.includes("osd-gcp")); // skipping due to RHIDP-5704 on OSD Env + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2116 + test.fixme(() => process.env.JOB_TYPE.includes("presubmit")); // skip on PR checks + test.fixme(() => !process.env.JOB_NAME.includes("ocp")); // run only on OCP jobs to avoid GH rate limit let page: Page; let uiHelper: UIhelper; let common: Common; @@ -308,6 +361,6 @@ test.describe test("Bulk Import - Verify users without permission cannot access", async () => { await uiHelper.openSidebar("Bulk import"); await uiHelper.verifyText("Permission required"); - expect(await uiHelper.isBtnVisible("Add")).toBeFalsy(); + expect(await uiHelper.isBtnVisible("Import")).toBeFalsy(); }); }); diff --git a/e2e-tests/playwright/e2e/plugins/dynamic-plugins-info/dynamic-plugins-info.spec.ts b/e2e-tests/playwright/e2e/plugins/dynamic-plugins-info/dynamic-plugins-info.spec.ts deleted file mode 100644 index 394bd22533..0000000000 --- a/e2e-tests/playwright/e2e/plugins/dynamic-plugins-info/dynamic-plugins-info.spec.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { expect, test } from "@playwright/test"; -import { UIhelper } from "../../../utils/ui-helper"; -import { Common } from "../../../utils/common"; -import { UI_HELPER_ELEMENTS } from "../../../support/pageObjects/global-obj"; - -test.describe("dynamic-plugins-info UI tests", () => { - let uiHelper: UIhelper; - let common: Common; - - test.beforeEach(async ({ page }) => { - uiHelper = new UIhelper(page); - common = new Common(page); - await common.loginAsGuest(); - await uiHelper.openSidebarButton("Administration"); - await uiHelper.openSidebar("Extensions"); - await uiHelper.verifyHeading("Extensions"); - await uiHelper.clickTab("Installed"); - }); - - test("it should show a table, and the table should contain techdocs plugins", async ({ - page, - }) => { - // what shows up in the list depends on how the instance is configured so - // let's check for the main basic elements of the component to verify the - // mount point is working as expected - await uiHelper.verifyText(/Plugins \(\d+\)/); - await uiHelper.verifyText("5 rows", false); - await uiHelper.verifyColumnHeading( - ["Name", "Version", "Enabled", "Preinstalled", "Role"], - true, - ); - - // Check the filter and use that to verify that the table contains the - // dynamic-plugins-info plugin, which is required for this test to run - // properly anyways - await page - .getByPlaceholder("Filter", { exact: true }) - .pressSequentially("techdocs\n", { delay: 300 }); - await uiHelper.verifyRowsInTable(["backstage-plugin-techdocs"], true); - }); - - test("it should have a plugin-tech-radar plugin which is Enabled and Preinstalled", async ({ - page, - }) => { - await page - .getByPlaceholder("Filter", { exact: true }) - .pressSequentially("plugin-tech-radar\n", { delay: 300 }); - const row = await page.locator( - UI_HELPER_ELEMENTS.rowByText("backstage-community-plugin-tech-radar"), - ); - expect(await row.locator("td").nth(2).innerText()).toBe("Yes"); // enabled - expect(await row.locator("td").nth(3).innerText()).toBe("Yes"); // preinstalled - }); - - test("it should have a plugin-3scale-backend plugin which is not Enabled but Preinstalled", async ({ - page, - }) => { - await page - .getByPlaceholder("Filter", { exact: true }) - .pressSequentially("plugin-3scale-backend-dynamic\n", { - delay: 100, - }); - const row = await page.locator( - UI_HELPER_ELEMENTS.rowByText( - "backstage-community-plugin-3scale-backend-dynamic", - ), - ); - expect(await row.locator("td").nth(2).innerText()).toBe("No"); // not enabled - expect(await row.locator("td").nth(3).innerText()).toBe("Yes"); // preinstalled - }); - - // TODO: Enable this test once the behavior for loading this plugin is fixed. - // TODO: In RHDH 1.5, this plugin incorrectly appears as disabled despite being properly imported and explicitly enabled. - test.skip("it should have a plugin-todo-list plugin which is Enabled but not Preinstalled", async ({ - page, - }) => { - await page - .getByPlaceholder("Search", { exact: true }) - .pressSequentially("plugin-todo\n", { delay: 300 }); - - // Verify the Enabled and Preinstalled column values for the specific row - await uiHelper.verifyPluginRow( - "@backstage-community/plugin-todo", // Text to locate the row (Name column) - "Yes", // Expected value in the Enabled column - "No", // Expected value in the Preinstalled column - ); - }); -}); diff --git a/e2e-tests/playwright/e2e/plugins/frontend/sidebar.spec.ts b/e2e-tests/playwright/e2e/plugins/frontend/sidebar.spec.ts index e0e00733b4..1eed548a56 100644 --- a/e2e-tests/playwright/e2e/plugins/frontend/sidebar.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/frontend/sidebar.spec.ts @@ -9,6 +9,11 @@ test.describe("Validate Sidebar Navigation Customization", () => { let common: Common; test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + page = (await setupBrowser(browser, testInfo)).page; uiHelper = new UIhelper(page); common = new Common(page); @@ -40,18 +45,18 @@ test.describe("Validate Sidebar Navigation Customization", () => { await uiHelper.verifyText("Test enabled"); await expect( page.getByRole("link", { name: "Test disabled" }), - ).not.toBeVisible(); + ).toBeHidden(); // Verify the presence/absense of nested 'Test' buttons in the sidebar await uiHelper.openSidebarButton("Test enabled"); await uiHelper.verifyText("Test nested enabled"); await expect( page.getByRole("link", { name: "Test nested disabled" }), - ).not.toBeVisible(); + ).toBeHidden(); await uiHelper.verifyText("Test_i enabled"); await expect( page.getByRole("link", { name: "Test_i disabled" }), - ).not.toBeVisible(); + ).toBeHidden(); }); }); diff --git a/e2e-tests/playwright/e2e/plugins/gitlab/gitlab-discovery.spec.ts b/e2e-tests/playwright/e2e/plugins/gitlab/gitlab-discovery.spec.ts index d05bd66238..878e7a7be6 100644 --- a/e2e-tests/playwright/e2e/plugins/gitlab/gitlab-discovery.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/gitlab/gitlab-discovery.spec.ts @@ -8,6 +8,13 @@ test.describe("gitlab discovery UI tests", () => { let uiHelper: UIhelper; let common: Common; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test.beforeEach(async ({ page }) => { uiHelper = new UIhelper(page); common = new Common(page); @@ -15,15 +22,19 @@ test.describe("gitlab discovery UI tests", () => { await uiHelper.openSidebar("Catalog"); }); - test("GitLab integration for discovering catalog entities from GitLab", async () => { - await uiHelper.verifyText("rhdh-my-new-service"); - await uiHelper.clickLink("rhdh-my-new-service"); - await uiHelper.verifyHeading("rhdh-my-new-service"); - await uiHelper.verifyText("Description of my new service"); - await uiHelper.verifyText("java"); - await uiHelper.verifyText("production"); - await uiHelper.verifyLink("team-a"); - await uiHelper.verifyLink("project-x"); - await uiHelper.verifyLink("View Source"); - }); + // TODO: https://issues.redhat.com/browse/RHDHBUGS-1977 + test.fixme( + "GitLab integration for discovering catalog entities from GitLab", + async () => { + await uiHelper.verifyText("rhdh-my-new-service"); + await uiHelper.clickLink("rhdh-my-new-service"); + await uiHelper.verifyHeading("rhdh-my-new-service"); + await uiHelper.verifyText("Description of my new service"); + await uiHelper.verifyText("java"); + await uiHelper.verifyText("production"); + await uiHelper.verifyLink("team-a"); + await uiHelper.verifyLink("project-x"); + await uiHelper.verifyLink("View Source"); + }, + ); }); diff --git a/e2e-tests/playwright/e2e/plugins/global-floating-button.spec.ts b/e2e-tests/playwright/e2e/plugins/global-floating-button.spec.ts index 0ebdac8c21..dc84ace37e 100644 --- a/e2e-tests/playwright/e2e/plugins/global-floating-button.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/global-floating-button.spec.ts @@ -1,13 +1,20 @@ import { test } from "@playwright/test"; import { Common } from "../../utils/common"; -import { FabPo } from "../../support/pageObjects/global-fab-po"; +import { FabPo } from "../../support/page-objects/global-fab-po"; import { UIhelper } from "../../utils/ui-helper"; -import { PagesUrl } from "../../support/pageObjects/page"; +import { PagesUrl } from "../../support/page-objects/page"; test.describe("Test global floating action button plugin", () => { let uiHelper: UIhelper; let fabHelper: FabPo; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test.beforeEach(async ({ page }) => { const common = new Common(page); await common.loginAsGuest(); @@ -21,7 +28,7 @@ test.describe("Test global floating action button plugin", () => { await fabHelper.verifyFabButtonByLabel("Git"); await fabHelper.verifyFabButtonByDataTestId("bulk-import"); await fabHelper.clickFabMenuByTestId("bulk-import"); - await uiHelper.verifyText("Added repositories"); + await uiHelper.verifyText("Imported entities"); }); test("Check if floating button is shown with two sub-menu actions on the Catalog Page, verify Git sub-menu", async () => { diff --git a/e2e-tests/playwright/e2e/plugins/http-request.spec.ts b/e2e-tests/playwright/e2e/plugins/http-request.spec.ts index f7fd160495..92ab645c94 100644 --- a/e2e-tests/playwright/e2e/plugins/http-request.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/http-request.spec.ts @@ -6,7 +6,6 @@ import { CatalogImport } from "../../support/pages/catalog-import"; // https://github.com/RoadieHQ/roadie-backstage-plugins/tree/main/plugins/scaffolder-actions/scaffolder-backend-module-http-request // Pre-req: Enable roadiehq-scaffolder-backend-module-http-request-dynamic plugin // Pre-req: Enable janus-idp-backstage-plugin-quay plugin -//TODO Re-enable when roadiehq-scaffolder-backend-module-http-request-dynamic is included in the Helm image test.describe("Testing scaffolder-backend-module-http-request to invoke an external request", () => { test.skip(() => process.env.JOB_NAME.includes("osd-gcp")); // skipping due to RHIDP-5704 on OSD Env let uiHelper: UIhelper; @@ -15,6 +14,13 @@ test.describe("Testing scaffolder-backend-module-http-request to invoke an exter const template = "https://github.com/janus-qe/software-template/blob/main/test-http-request.yaml"; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test.beforeEach(async ({ page }) => { uiHelper = new UIhelper(page); common = new Common(page); @@ -26,7 +32,7 @@ test.describe("Testing scaffolder-backend-module-http-request to invoke an exter test.setTimeout(130000); await uiHelper.clickLink({ ariaLabel: "Self-service" }); await uiHelper.verifyHeading("Templates"); - await uiHelper.clickButton("Register Existing Component"); + await uiHelper.clickButton("Import an existing Git repository"); await catalogImport.registerExistingComponent(template, false); await uiHelper.openSidebar("Catalog"); diff --git a/e2e-tests/playwright/e2e/plugins/keycloak/catalog-users.spec.ts b/e2e-tests/playwright/e2e/plugins/keycloak/catalog-users.spec.ts index 8c59cbfc14..a8502e17fd 100644 --- a/e2e-tests/playwright/e2e/plugins/keycloak/catalog-users.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/keycloak/catalog-users.spec.ts @@ -1,18 +1,23 @@ -import { CatalogUsersPO } from "../../../support/pageObjects/catalog/catalog-users-obj"; +import { CatalogUsersPO } from "../../../support/page-objects/catalog/catalog-users-obj"; import Keycloak from "../../../utils/keycloak/keycloak"; import { UIhelper } from "../../../utils/ui-helper"; import { Common } from "../../../utils/common"; import { test, expect } from "@playwright/test"; +import { ChildProcessWithoutNullStreams, spawn, exec } from "child_process"; import { KubeClient } from "../../../utils/kube-client"; -test.describe.skip("Test Keycloak plugin", () => { - // Skipping this test due to https://issues.redhat.com/browse/RHIDP-6844 +test.describe("Test Keycloak plugin", () => { let uiHelper: UIhelper; let keycloak: Keycloak; let common: Common; let token: string; test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + keycloak = new Keycloak(); token = await keycloak.getAuthenticationToken(); }); @@ -43,6 +48,7 @@ test.describe.skip("Test Keycloak plugin", () => { ); expect(userFound).not.toBeNull(); + // eslint-disable-next-line playwright/no-conditional-in-test if (userFound) { await keycloak.checkUserDetails( page, @@ -57,53 +63,56 @@ test.describe.skip("Test Keycloak plugin", () => { }); test.describe("Test Keycloak plugin metrics", () => { - test.fixme( - process.env.IS_OPENSHIFT === "false", - "Failing on Kubernetes clusters, need to add Ingress, fix https://issues.redhat.com/browse/RHIDP-7531", - ); - const namespace = process.env.NAME_SPACE || "showcase-ci-nightly"; - const baseRHDHURL: string = process.env.BASE_URL; - let kubeClient: KubeClient; - const routerName = "rhdh-metrics"; - - test.beforeEach(() => { - kubeClient = new KubeClient(); + let portForward: ChildProcessWithoutNullStreams; + + test.beforeEach(async () => { + const namespace = process.env.NAME_SPACE || "showcase-ci-nightly"; + const kubeClient = new KubeClient(); + + console.log("Starting port-forward process..."); + + const services = await kubeClient.getServiceByLabel( + namespace, + "app.kubernetes.io/instance=rhdh", + ); + const rhdhMetricsServiceName = services.find((service) => + service.spec?.ports.some((p) => p.port === 9464), + ); + portForward = spawn("/bin/sh", [ + "-c", + ` + oc login --token="${process.env.K8S_CLUSTER_TOKEN}" --server="${process.env.K8S_CLUSTER_URL}" --insecure-skip-tls-verify=true && + kubectl config set-context --current --namespace="${namespace}" && + kubectl port-forward service/${rhdhMetricsServiceName.metadata?.name} 9464:9464 --namespace="${namespace}" + `, + ]); + + console.log("Waiting for port-forward to be ready..."); + await new Promise((resolve, reject) => { + portForward.stdout.on("data", (data) => { + if (data.toString().includes("Forwarding from 127.0.0.1:9464")) { + resolve(); + } + }); + + portForward.stderr.on("data", (data) => { + console.error(`Port forwarding failed: ${data.toString()}`); + reject(new Error(`Port forwarding failed: ${data.toString()}`)); + }); + }); }); - test.afterAll(async () => { - const metricsRoute = await kubeClient.getRoute(namespace, routerName); - if (metricsRoute) { - await kubeClient.deleteRoute(namespace, routerName); - } + test.afterEach(() => { + console.log("Killing port-forward process with ID:", portForward.pid); + portForward.kill("SIGKILL"); + console.log("Killing remaining port-forward process."); + exec( + `ps aux | grep 'kubectl port-forward' | grep -v grep | awk '{print $2}' | xargs kill -9`, + ); }); test("Test keycloak metrics with failure counters", async () => { - const host: string = new URL(baseRHDHURL).hostname; - const domain = host.split(".").slice(1).join("."); - - const metricsRoute = await kubeClient.getRoute(namespace, routerName); - if (!metricsRoute) { - const service = await kubeClient.getServiceByLabel( - namespace, - "app.kubernetes.io/name=backstage", - ); - const rhdhServiceName = service[0].metadata.name; - const route = { - apiVersion: "route.openshift.io/v1", - kind: "Route", - metadata: { name: routerName, namespace }, - spec: { - host: `${routerName}.${domain}`, - to: { kind: "Service", name: rhdhServiceName }, - port: { targetPort: "http-metrics" }, - }, - }; - await kubeClient.createRoute(namespace, route); - // Wait until the route is available. - await new Promise((resolve) => setTimeout(resolve, 10000)); - } - - const metricsEndpointURL = `http://${routerName}.${domain}/metrics`; + const metricsEndpointURL = "http://localhost:9464/metrics"; const metricLines = await fetchMetrics(metricsEndpointURL); const metricLineStartWith = diff --git a/e2e-tests/playwright/e2e/plugins/kubernetes-actions/kubernetes-actions.spec.ts b/e2e-tests/playwright/e2e/plugins/kubernetes-actions/kubernetes-actions.spec.ts index b8852ded87..397c38179d 100644 --- a/e2e-tests/playwright/e2e/plugins/kubernetes-actions/kubernetes-actions.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/kubernetes-actions/kubernetes-actions.spec.ts @@ -2,7 +2,7 @@ import { expect, Page, test } from "@playwright/test"; import { Common, setupBrowser } from "../../../utils/common"; import { UIhelper } from "../../../utils/ui-helper"; import { KubeClient } from "../../../utils/kube-client"; -import { UI_HELPER_ELEMENTS } from "../../../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../../../support/page-objects/global-obj"; test.describe("Test Kubernetes Actions plugin", () => { let common: Common; @@ -12,15 +12,33 @@ test.describe("Test Kubernetes Actions plugin", () => { let namespace: string; test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + page = (await setupBrowser(browser, testInfo)).page; common = new Common(page); uiHelper = new UIhelper(page); kubeClient = new KubeClient(); + test.setTimeout(testInfo.timeout + 6500); + await common.loginAsGuest(); await uiHelper.clickLink({ ariaLabel: "Self-service" }); }); + test.beforeEach(async ({}, testInfo) => { + // Add cool-down period before retries (except on first attempt) + if (testInfo.retry > 0) { + const coolDownMs = 2000; + console.log( + `Attempt ${testInfo.retry + 1} failed, waiting ${coolDownMs}ms before retry...`, + ); + await page.waitForTimeout(coolDownMs); + } + }); + test("Creates kubernetes namespace", async () => { namespace = `test-kubernetes-actions-${Date.now()}`; await uiHelper.verifyHeading("Self-service"); @@ -31,14 +49,18 @@ test.describe("Test Kubernetes Actions plugin", () => { await uiHelper.fillTextInputByLabel("Url", process.env.K8S_CLUSTER_URL); await uiHelper.fillTextInputByLabel("Token", process.env.K8S_CLUSTER_TOKEN); await uiHelper.checkCheckbox("Skip TLS verification"); + await page.waitForTimeout(2000); await uiHelper.clickButton("Review"); + await page.waitForTimeout(1500); await uiHelper.clickButton("Create"); + await page.waitForTimeout(1500); await page.waitForSelector( `${UI_HELPER_ELEMENTS.MuiTypography}:has-text("second")`, ); + await page.waitForTimeout(1500); await expect( page.locator(`${UI_HELPER_ELEMENTS.MuiTypography}:has-text("Error")`), - ).not.toBeVisible(); + ).toBeHidden(); await kubeClient.getNamespaceByName(namespace); }); diff --git a/e2e-tests/playwright/e2e/plugins/kubernetes/kubernetes-rbac.spec.ts b/e2e-tests/playwright/e2e/plugins/kubernetes/kubernetes-rbac.spec.ts index adbd41fd57..b97134b666 100644 --- a/e2e-tests/playwright/e2e/plugins/kubernetes/kubernetes-rbac.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/kubernetes/kubernetes-rbac.spec.ts @@ -2,7 +2,7 @@ import { test, expect } from "@playwright/test"; import { Common } from "../../../utils/common"; import { UIhelper } from "../../../utils/ui-helper"; import { Catalog } from "../../../support/pages/catalog"; -import { KUBERNETES_COMPONENTS } from "../../../support/pageObjects/page-obj"; +import { KUBERNETES_COMPONENTS } from "../../../support/page-objects/page-obj"; import { KubernetesPage } from "../../../support/pages/kubernetes"; test.describe("Test Kubernetes Plugin", () => { @@ -11,6 +11,13 @@ test.describe("Test Kubernetes Plugin", () => { let catalog: Catalog; let kubernetes: KubernetesPage; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test.beforeEach(async ({ page }, testInfo) => { if (testInfo.retry > 0) { // progressively increase test timeout for retries diff --git a/e2e-tests/playwright/e2e/plugins/licensed-users-info-backend/licensed-users-info.spec.ts b/e2e-tests/playwright/e2e/plugins/licensed-users-info-backend/licensed-users-info.spec.ts new file mode 100644 index 0000000000..90bef50085 --- /dev/null +++ b/e2e-tests/playwright/e2e/plugins/licensed-users-info-backend/licensed-users-info.spec.ts @@ -0,0 +1,135 @@ +import { CatalogUsersPO } from "../../../support/page-objects/catalog/catalog-users-obj"; +import { RhdhAuthUiHack } from "../../../support/api/rhdh-auth-hack"; +import { Common } from "../../../utils/common"; +import { + test, + expect, + APIRequestContext, + APIResponse, + request, +} from "@playwright/test"; +import playwrightConfig from "../../../../playwright.config"; + +test.describe("Test licensed users info backend plugin", async () => { + let common: Common; + + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + + let apiToken: string; + + const baseRHDHURL: string = playwrightConfig.use.baseURL; + const pluginAPIURL: string = "api/licensed-users-info/"; + + test.beforeEach(async ({ page }) => { + common = new Common(page); + await common.loginAsGuest(); + await CatalogUsersPO.visitBaseURL(page); + + // Get the api token + const hacker: RhdhAuthUiHack = RhdhAuthUiHack.getInstance(); + apiToken = await hacker.getApiToken(page); + }); + + test("Test plugin health check endpoint", async () => { + const requestContext: APIRequestContext = await request.newContext({ + baseURL: `${baseRHDHURL}/${pluginAPIURL}`, + }); + + const response: APIResponse = await requestContext.get("health"); + const result = await response.json(); + + /* + { status: 'ok' } + */ + + expect(result).toHaveProperty("status"); + expect(result.status).toBe("ok"); + }); + + test("Test plugin user quantity url", async () => { + const requestContext: APIRequestContext = await request.newContext({ + baseURL: `${baseRHDHURL}/${pluginAPIURL}`, + extraHTTPHeaders: { + Authorization: apiToken, + Accept: "application/json", + }, + }); + + const response: APIResponse = await requestContext.get("users/quantity"); + const result = await response.json(); + + /* + { quantity: '1' } + */ + + expect(result).toHaveProperty("quantity"); + expect(Number(result.quantity)).toBeGreaterThan(0); + }); + + test("Test plugin users url", async () => { + const requestContext: APIRequestContext = await request.newContext({ + baseURL: `${baseRHDHURL}/${pluginAPIURL}`, + extraHTTPHeaders: { + Authorization: apiToken, + Accept: "application/json", + }, + }); + + const response: APIResponse = await requestContext.get("users"); + const result = await response.json(); + + /* + [ + { + userEntityRef: 'user:development/guest', + lastAuthTime: 'Thu, 17 Jul 2025 17:53:51 GMT' + } + ] + */ + + expect(Array.isArray(result)).toBe(true); + expect(result.length).toBeGreaterThan(0); + expect(result[0]).toHaveProperty("userEntityRef"); + expect(result[0]).toHaveProperty("lastAuthTime"); + expect(result[0].userEntityRef).toContain("user:"); + }); + + test("Test plugin users as a csv url", async () => { + const requestContext: APIRequestContext = await request.newContext({ + baseURL: `${baseRHDHURL}/${pluginAPIURL}`, + extraHTTPHeaders: { + Authorization: apiToken, + "Content-Type": "text/csv", + }, + }); + + const response: APIResponse = await requestContext.get("users"); + + // 'content-type': 'text/csv; charset=utf-8', + expect(response.headers()["content-type"]).toContain("text/csv"); + + // 'content-disposition': 'attachment; filename="data.csv"', + expect(response.headers()["content-disposition"]).toBe( + 'attachment; filename="data.csv"', + ); + + const result = await response.text(); + /* + userEntityRef,displayName,email,lastAuthTime + user:development/guest,undefined,undefined,"Fri, 18 Jul 2025 12:41:47 GMT" + */ + const splitText = result.split("\n"); + const csvHeaders = splitText[0]; + const csvData = splitText[1]; + + expect(csvHeaders).toContain( + "userEntityRef,displayName,email,lastAuthTime", + ); + expect(csvData).toContain("user:"); + }); +}); diff --git a/e2e-tests/playwright/e2e/plugins/middleware.spec.ts b/e2e-tests/playwright/e2e/plugins/middleware.spec.ts index a121c6f540..7685ba0251 100644 --- a/e2e-tests/playwright/e2e/plugins/middleware.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/middleware.spec.ts @@ -2,17 +2,32 @@ import test, { expect } from "@playwright/test"; import { Common } from "../../utils/common"; -test("Check the middleware is working", async ({ page }) => { - const common = new Common(page); +test.describe("Test middleware plugin", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); - await common.loginAsGuest(); - await page.goto("/simple-chat", { waitUntil: "networkidle" }); - await page.getByRole("checkbox", { name: "Use Proxy" }).check(); - await page.getByRole("textbox").fill("hi"); + test("Check the middleware is working", async ({ page }) => { + const common = new Common(page); - const responsePromise = page.waitForResponse("**/api/proxy/add-test-header"); - await page.getByRole("textbox").press("Enter"); - const response = await responsePromise; - const headers = await response.allHeaders(); - expect(headers["x-proxy-test-header"]); + await common.loginAsGuest(); + await page.goto("/simple-chat", { waitUntil: "domcontentloaded" }); + await page.getByRole("checkbox", { name: "Use Proxy" }).check(); + await page.getByRole("textbox").fill("hi"); + + const responsePromise = page.waitForResponse( + "**/api/proxy/add-test-header", + ); + await page.getByRole("textbox").press("Enter"); + const response = await responsePromise; + const headers = await response.allHeaders(); + console.log("All headers:", headers); + console.log("Target header:", headers["x-proxy-test-header"]); + + // eslint-disable-next-line playwright/valid-expect + expect(headers["x-proxy-test-header"]); + }); }); diff --git a/e2e-tests/playwright/e2e/plugins/notifications/filterNotificationSeverityCritical.spec.ts b/e2e-tests/playwright/e2e/plugins/notifications/filter-notification-severity-critical.spec.ts similarity index 89% rename from e2e-tests/playwright/e2e/plugins/notifications/filterNotificationSeverityCritical.spec.ts rename to e2e-tests/playwright/e2e/plugins/notifications/filter-notification-severity-critical.spec.ts index 28bf4d0214..ca94cb6f3b 100644 --- a/e2e-tests/playwright/e2e/plugins/notifications/filterNotificationSeverityCritical.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/notifications/filter-notification-severity-critical.spec.ts @@ -4,23 +4,27 @@ import { Common } from "../../../utils/common"; import RhdhNotficationsApi from "../../../support/api/notifications"; import { Notifications } from "../../../support/api/notifications-api-structures"; import { RhdhAuthApiHack } from "../../../support/api/rhdh-auth-api-hack"; -import { Orchestrator } from "../../../support/pages/orchestrator"; + import { NotificationPage } from "../../../support/pages/notifications"; test.describe("Filter critical notification tests", () => { let uiHelper: UIhelper; let common: Common; - let orchestrator: Orchestrator; let notificationPage: NotificationPage; - let apiToken: string; + + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "integration", + }); + }); test.beforeEach(async ({ page }) => { uiHelper = new UIhelper(page); common = new Common(page); - orchestrator = new Orchestrator(page); notificationPage = new NotificationPage(page); await common.loginAsKeycloakUser(); - apiToken = await RhdhAuthApiHack.getToken(page); + await RhdhAuthApiHack.getToken(page); }); test("Fiter notifcations by serverity - critical", async () => { diff --git a/e2e-tests/playwright/e2e/plugins/ocm.spec.ts b/e2e-tests/playwright/e2e/plugins/ocm.spec.ts index 7e791e8bcf..ff1f1426fc 100644 --- a/e2e-tests/playwright/e2e/plugins/ocm.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/ocm.spec.ts @@ -40,6 +40,13 @@ const test = base.extend<{ }); test.describe("Test OCM plugin", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test("Navigate to Clusters and Verify OCM Clusters", async ({ page, uiHelper, diff --git a/e2e-tests/playwright/e2e/plugins/quay/quay-actions.spec.ts b/e2e-tests/playwright/e2e/plugins/quay/quay-actions.spec.ts index 3c28713f00..f4a1b13b81 100644 --- a/e2e-tests/playwright/e2e/plugins/quay/quay-actions.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/quay/quay-actions.spec.ts @@ -1,10 +1,14 @@ import { Page, test } from "@playwright/test"; import { Common, setupBrowser } from "../../../utils/common"; import { UIhelper } from "../../../utils/ui-helper"; -import { UI_HELPER_ELEMENTS } from "../../../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../../../support/page-objects/global-obj"; import { QuayClient } from "../../../utils/quay/quay-client"; test.describe("Test Quay Actions plugin", () => { + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2149 + // Re-enable after quay back from read-only: https://status.redhat.com/incidents/24r8xgknfd4z + test.fixme(); + let common: Common; let uiHelper: UIhelper; let page: Page; @@ -12,6 +16,11 @@ test.describe("Test Quay Actions plugin", () => { let repository: string; test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + page = (await setupBrowser(browser, testInfo)).page; common = new Common(page); uiHelper = new UIhelper(page); diff --git a/e2e-tests/playwright/e2e/plugins/quay/quay.spec.ts b/e2e-tests/playwright/e2e/plugins/quay/quay.spec.ts index 61e4d9e9e5..0ad4b52554 100644 --- a/e2e-tests/playwright/e2e/plugins/quay/quay.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/quay/quay.spec.ts @@ -7,6 +7,13 @@ test.describe("Test Quay.io plugin", () => { const quayRepository = "rhdh-community/rhdh"; let uiHelper: UIhelper; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test.beforeEach(async ({ page }) => { const common = new Common(page); await common.loginAsGuest(); @@ -37,6 +44,9 @@ test.describe("Test Quay.io plugin", () => { }); test("Check Security Scan details", async ({ page }) => { + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2149 + // Re-enable after quay back from read-only: https://status.redhat.com/incidents/24r8xgknfd4z + test.fixme(); const cell = await ImageRegistry.getScanCell(page); await expect(cell).toBeVisible(); }); diff --git a/e2e-tests/playwright/e2e/plugins/quick-access-and-tech-radar.spec.ts b/e2e-tests/playwright/e2e/plugins/quick-access-and-tech-radar.spec.ts index 82b7b69d10..1ea8072adc 100644 --- a/e2e-tests/playwright/e2e/plugins/quick-access-and-tech-radar.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/quick-access-and-tech-radar.spec.ts @@ -7,6 +7,13 @@ import { TechRadar } from "../../support/pages/tech-radar"; // Pre-req: Enable plugin-tech-radar and plugin-tech-radar-backend Plugin test.describe("Test Customized Quick Access and tech-radar plugin", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test.beforeEach(async ({ page }) => { const common = new Common(page); await common.loginAsGuest(); diff --git a/e2e-tests/playwright/e2e/plugins/quick-start.spec.ts b/e2e-tests/playwright/e2e/plugins/quick-start.spec.ts new file mode 100644 index 0000000000..8b6a3da01e --- /dev/null +++ b/e2e-tests/playwright/e2e/plugins/quick-start.spec.ts @@ -0,0 +1,97 @@ +import { expect, test } from "@playwright/test"; +import { Common } from "../../utils/common"; +import { UIhelper } from "../../utils/ui-helper"; + +test.describe("Test Quick Start plugin", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + let uiHelper: UIhelper; + let common: Common; + + test.beforeEach(async ({ page }) => { + common = new Common(page); + uiHelper = new UIhelper(page); + }); + + test("Access Quick start from Global Header", async ({ page }) => { + await common.loginAsKeycloakUser(); + await page.waitForTimeout(1000); + // eslint-disable-next-line playwright/no-conditional-in-test + if (await page.getByRole("button", { name: "Hide" }).isHidden()) { + await uiHelper.clickButtonByLabel("Help"); + await uiHelper.clickByDataTestId("quickstart-button"); + console.log("Quick start button clicked"); + } + await expect(page.getByRole("button", { name: "Hide" })).toBeVisible(); + }); + + test("Access Quick start as Guest or Admin", async ({ page }) => { + // eslint-disable-next-line playwright/no-conditional-in-test + if (test.info().project.name !== "showcase-rbac") { + await common.loginAsGuest(); + } else { + await common.loginAsKeycloakUser(); + } + await page.waitForTimeout(1000); + await uiHelper.verifyText("Let's get you started with Developer Hub"); + await uiHelper.verifyText("We'll guide you through a few quick steps"); + await uiHelper.verifyText("Not started"); + await uiHelper.clickButtonByText("Set up authentication"); + await uiHelper.verifyButtonURL( + "Learn more", + "https://docs.redhat.com/en/documentation/red_hat_developer_hub/latest/html/authentication_in_red_hat_developer_hub/", + { exact: false }, + ); + await uiHelper.clickButtonByText("Configure RBAC"); + await uiHelper.verifyButtonURL("Manage access", "/rbac"); + await uiHelper.clickButtonByText("Configure Git"); + await uiHelper.verifyButtonURL( + "Learn more", + "https://docs.redhat.com/en/documentation/red_hat_developer_hub/latest/html/integrating_red_hat_developer_hub_with_github/", + { exact: false }, + ); + await uiHelper.clickButtonByText("Manage plugins"); + await uiHelper.verifyButtonURL("Explore plugins", "/extensions"); + await uiHelper.clickButtonByText("Explore plugins"); + await uiHelper.verifyText("Catalog"); + await uiHelper.verifyText(/Plugins \((\d+)\)/); + await uiHelper.verifyText("25% progress"); + await uiHelper.clickButton("Hide"); + await expect(page.getByRole("button", { name: "Hide" })).toBeHidden(); + }); + + test("Access Quick start as User", async ({ page }) => { + // eslint-disable-next-line playwright/no-conditional-in-test + if (test.info().project.name !== "showcase-rbac") { + test.skip(); + } + await common.loginAsKeycloakUser( + process.env.GH_USER2_ID, + process.env.GH_USER2_PASS, + ); + await page.waitForTimeout(1000); + await uiHelper.verifyText("Let's get you started with Developer Hub"); + await uiHelper.verifyText("We'll guide you through a few quick steps"); + await uiHelper.clickButtonByText("Import application"); + await uiHelper.verifyButtonURL("Import", "/bulk-import/repositories"); + await uiHelper.clickButtonByText("Import"); + await uiHelper.verifyHeading("Bulk import"); + await uiHelper.clickButtonByText("Learn about the Catalog"); + await uiHelper.verifyButtonURL("View Catalog", "/catalog"); + await uiHelper.clickButtonByText("View Catalog"); + await uiHelper.verifyHeading(/All Components \((\d+)\)/); + await uiHelper.clickButtonByText("Explore Self-service templates"); + await uiHelper.verifyButtonURL("Explore templates", "/create"); + await uiHelper.clickButtonByText("Explore templates"); + await uiHelper.verifyHeading("Self-service"); + await uiHelper.clickButtonByText("Find all Learning Paths"); + await uiHelper.verifyButtonURL("View Learning Paths", "/learning-paths"); + await uiHelper.clickButtonByText("View Learning Paths"); + await uiHelper.verifyHeading("Learning Paths"); + await uiHelper.verifyText("100% progress"); + }); +}); diff --git a/e2e-tests/playwright/e2e/plugins/rbac/rbac.spec.ts b/e2e-tests/playwright/e2e/plugins/rbac/rbac.spec.ts index 1a01f7cbed..a8d0f4b5a2 100644 --- a/e2e-tests/playwright/e2e/plugins/rbac/rbac.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/rbac/rbac.spec.ts @@ -1,14 +1,14 @@ import { Locator, Page, expect, test } from "@playwright/test"; import { Response, Roles } from "../../../support/pages/rbac"; -import { UI_HELPER_ELEMENTS } from "../../../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../../../support/page-objects/global-obj"; import { SEARCH_OBJECTS_COMPONENTS, - ROLE_OVERVIEW_COMPONENTS, + ROLE_OVERVIEW_COMPONENTS_TEST_ID, ROLES_PAGE_COMPONENTS, -} from "../../../support/pageObjects/page-obj"; +} from "../../../support/page-objects/page-obj"; import { Common, setupBrowser } from "../../../utils/common"; import { UIhelper } from "../../../utils/ui-helper"; -import { RbacPo } from "../../../support/pageObjects/rbac-po"; +import { RbacPo } from "../../../support/page-objects/rbac-po"; import { RhdhAuthApiHack } from "../../../support/api/rhdh-auth-api-hack"; import RhdhRbacApi from "../../../support/api/rbac-api"; import { RbacConstants } from "../../../data/rbac-constants"; @@ -22,18 +22,25 @@ import { downloadAndReadFile } from "../../../utils/helper"; https://docs.redhat.com/en/documentation/red_hat_developer_hub/1.3/html/authorization/managing-authorizations-by-using-the-web-ui#proc-rbac-ui-edit-role_title-authorization */ test.describe.serial("Test RBAC", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); test.describe .serial("Test RBAC plugin: load permission policies and conditions from files", () => { test.beforeEach(async ({ page }) => { await new Common(page).loginAsKeycloakUser(); - await page.goto("/rbac"); + const uiHelper = new UIhelper(page); + await uiHelper.goToPageUrl("/rbac"); }); test("Check UI navigation by nav bar when RBAC is enabled", async ({ page, }) => { - await page.goto("/"); const uiHelper = new UIhelper(page); + await uiHelper.goToPageUrl("/", "Welcome back!"); await uiHelper.openSidebarButton("Administration"); const dropdownMenuLocator = page.locator(`text="RBAC"`); await expect(dropdownMenuLocator).toBeVisible(); @@ -101,7 +108,7 @@ test.describe.serial("Test RBAC", () => { }) => { const uiHelper = new UIhelper(page); const testUser = "test-rhdh-qe-2"; - await page.goto("/catalog"); + await uiHelper.goToPageUrl("/catalog"); await uiHelper.selectMuiBox("Kind", "Component"); await uiHelper.searchInputPlaceholder(testUser); @@ -149,7 +156,7 @@ test.describe.serial("Test RBAC", () => { const uiHelper = new UIhelper(page); // rhdh-qe-parent-team owns mock-site const testParentGroup = "rhdh-qe-parent-team"; - await page.goto("/catalog"); + await uiHelper.goToPageUrl("/catalog"); await uiHelper.selectMuiBox("Kind", "Component"); await uiHelper.searchInputPlaceholder("mock-site"); @@ -158,7 +165,7 @@ test.describe.serial("Test RBAC", () => { // rhdh-qe-child-team owns mock-child-site, check that it can see it's own groups' components const testChildGroup = "rhdh-qe-child-team"; - await page.goto("/catalog"); + await uiHelper.goToPageUrl("/catalog"); await uiHelper.selectMuiBox("Kind", "Component"); await uiHelper.searchInputPlaceholder("mock-child-site"); @@ -178,7 +185,7 @@ test.describe.serial("Test RBAC", () => { const uiHelper = new UIhelper(page); // rhdh-qe-parent-team owns mock-site const testParentGroup = "rhdh-qe-parent-team"; - await page.goto("/catalog"); + await uiHelper.goToPageUrl("/catalog"); await uiHelper.selectMuiBox("Kind", "Component"); await uiHelper.searchInputPlaceholder("mock-site"); @@ -187,7 +194,7 @@ test.describe.serial("Test RBAC", () => { // rhdh-qe-child-team owns mock-child-site const testChildGroup = "rhdh-qe-child-team"; - await page.goto("/catalog"); + await uiHelper.goToPageUrl("/catalog"); await uiHelper.selectMuiBox("Kind", "Component"); await uiHelper.searchInputPlaceholder("mock-child-site"); @@ -196,7 +203,7 @@ test.describe.serial("Test RBAC", () => { // rhdh-qe-sub-child-team owns mock-sub-child-site, check that it can see it's own groups' components const testSubChildGroup = "rhdh-qe-sub-child-team"; - await page.goto("/catalog"); + await uiHelper.goToPageUrl("/catalog"); await uiHelper.selectMuiBox("Kind", "Component"); await uiHelper.searchInputPlaceholder("mock-sub-child-site"); @@ -206,13 +213,12 @@ test.describe.serial("Test RBAC", () => { }); test.describe("Test RBAC plugin as an admin user", () => { - // TODO: fix https://issues.redhat.com/browse/RHIDP-6625 and remove the skip - test.skip(() => process.env.IS_OPENSHIFT.includes("false")); test.beforeEach(async ({ page }, testInfo) => { testInfo.setTimeout(testInfo.timeout + 30_000); // Additional time due to repeated timeout failure in OSD env. const common = new Common(page); await common.loginAsKeycloakUser(); - await page.goto("/rbac"); + const uiHelper = new UIhelper(page); + await uiHelper.goToPageUrl("/rbac"); await common.waitForLoad(); await new UIhelper(page).verifyHeading("RBAC", 30_000); }); @@ -228,26 +234,33 @@ test.describe.serial("Test RBAC", () => { await uiHelper.verifyCellsInTable(allCellsIdentifier); }); - test("Should download the user list", async ({ page }) => { - await page.locator('a:has-text("Download User List")').click(); - const fileContent = await downloadAndReadFile( - page, - 'a:has-text("Download User List")', - ); + test("Should export CSV of the user list", async ({ page }) => { + const exportCsvLink = page.getByRole("link", { name: "Export CSV" }); + await exportCsvLink.click(); + const fileContent = await downloadAndReadFile(page, exportCsvLink); + await test.info().attach("user-list-file", { + body: fileContent, + contentType: "text/plain", + }); const lines = fileContent.trim().split("\n"); const header = "userEntityRef,displayName,email,lastAuthTime"; - if (lines[0] !== header) { - throw new Error("Header does not match"); - } + expect(lines[0], "Header needs to match the expected header").toBe( + header, + ); - // Check that each subsequent line starts with "user:default" - const allUsersValid = lines + // Check that each subsequent line starts with "user:default" or "user:development" + const invalidLines = lines .slice(1) - .every((line) => line.startsWith("user:default")); - if (!allUsersValid) { - throw new Error("Not all users info are valid"); - } + .filter( + (line) => + !line.startsWith("user:default") && + !line.startsWith("user:development"), + ); + + await test.step(`Validate user lines: ${invalidLines.length} invalid out of ${lines.length} total`, async () => { + expect(invalidLines, "All users should be valid").toHaveLength(0); + }); }); test("View details of a role", async ({ page }) => { @@ -267,7 +280,7 @@ test.describe.serial("Test RBAC", () => { Roles.getUsersAndGroupsListCellsIdentifier(); await uiHelper.verifyCellsInTable(usersAndGroupsCellsIdentifier); - await uiHelper.verifyHeading("Permission policies (5)"); + await uiHelper.verifyHeading("5 permissions"); const permissionPoliciesColumnsText = Roles.getPermissionPoliciesListColumnsText(); await uiHelper.verifyColumnHeading(permissionPoliciesColumnsText); @@ -371,7 +384,9 @@ test.describe.serial("Test RBAC", () => { await uiHelper.verifyHeading("role:default/test-role1"); await uiHelper.clickTab("Overview"); - await page.click(ROLE_OVERVIEW_COMPONENTS.updateMembers); + await page + .getByTestId(ROLE_OVERVIEW_COMPONENTS_TEST_ID.updateMembers) + .click(); await uiHelper.verifyHeading("Edit Role"); await uiHelper.fillTextInputByLabel( "Select users and groups", @@ -388,7 +403,9 @@ test.describe.serial("Test RBAC", () => { nextButton2 = page.locator('[data-testid="nextButton-2"]'); matchNextButton2 = await nextButton2.all(); attempts++; + // eslint-disable-next-line playwright/no-conditional-in-test } while (matchNextButton2.length > 1 && attempts < 5); + // eslint-disable-next-line playwright/no-force-option await nextButton2.click({ force: true }); await page.waitForTimeout(1_000); await uiHelper.clickButton("Save"); @@ -397,7 +414,9 @@ test.describe.serial("Test RBAC", () => { ); await uiHelper.verifyHeading(rbacPo.regexpShortUsersAndGroups(1, 1)); - await page.click(ROLE_OVERVIEW_COMPONENTS.updatePolicies); + await page + .getByTestId(ROLE_OVERVIEW_COMPONENTS_TEST_ID.updatePolicies) + .click(); await uiHelper.verifyHeading("Edit Role"); await rbacPo.selectPluginsCombobox.click(); await rbacPo.selectOption("scaffolder"); @@ -409,7 +428,7 @@ test.describe.serial("Test RBAC", () => { await uiHelper.verifyText( "Role role:default/test-role1 updated successfully", ); - await uiHelper.verifyHeading("Permission Policies (2)"); + await uiHelper.verifyHeading("2 permissions"); await rbacPo.deleteRole("role:default/test-role1"); }); @@ -417,13 +436,18 @@ test.describe.serial("Test RBAC", () => { test("Create a role with a permission policy per resource type and verify that the only authorized users can access specific resources.", async ({ page, }) => { + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2127 + test.fixme(true, "Cannot delete role because of missing permissions"); + const uiHelper = new UIhelper(page); const rbacPo = new RbacPo(page); await rbacPo.createConditionalRole( "test-role1", - ["Guest User", "rhdh-qe"], + ["Guest User", "rhdh-qe rhdh-qe"], ["Backstage"], "anyOf", + "catalog", + "user:default/rhdh-qe", ); await page @@ -449,7 +473,7 @@ test.describe.serial("Test RBAC", () => { const uiHelper = new UIhelper(page); await uiHelper.openSidebarButton("Administration"); const dropdownMenuLocator = page.locator(`text="RBAC"`); - await expect(dropdownMenuLocator).not.toBeVisible(); + await expect(dropdownMenuLocator).toBeHidden(); }); }); @@ -470,41 +494,46 @@ test.describe.serial("Test RBAC", () => { apiToken = await RhdhAuthApiHack.getToken(page); }); - // eslint-disable-next-line no-empty-pattern test.beforeEach(async ({}, testInfo) => { console.log( `beforeEach: Attempting setup for ${testInfo.title}, retry: ${testInfo.retry}`, ); }); - test("Test that roles and policies from GET request are what expected", async () => { - const rbacApi = await RhdhRbacApi.build(apiToken); - - const rolesResponse = await rbacApi.getRoles(); - - const policiesResponse = await rbacApi.getPolicies(); - - if (!rolesResponse.ok()) { - throw Error( - `RBAC rolesResponse API call failed with status code ${rolesResponse.status()}`, + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2100 + test.fixme( + "Test that roles and policies from GET request are what expected", + async () => { + const rbacApi = await RhdhRbacApi.build(apiToken); + + const rolesResponse = await rbacApi.getRoles(); + + const policiesResponse = await rbacApi.getPolicies(); + + // eslint-disable-next-line playwright/no-conditional-in-test + if (!rolesResponse.ok()) { + throw Error( + `RBAC rolesResponse API call failed with status code ${rolesResponse.status()}`, + ); + } + + // eslint-disable-next-line playwright/no-conditional-in-test + if (!policiesResponse.ok()) { + throw Error( + `RBAC policiesResponse API call failed with status code ${policiesResponse.status()}`, + ); + } + + await Response.checkResponse( + rolesResponse, + RbacConstants.getExpectedRoles(), ); - } - - if (!policiesResponse.ok()) { - throw Error( - `RBAC policiesResponse API call failed with status code ${policiesResponse.status()}`, + await Response.checkResponse( + policiesResponse, + RbacConstants.getExpectedPolicies(), ); - } - - await Response.checkResponse( - rolesResponse, - RbacConstants.getExpectedRoles(), - ); - await Response.checkResponse( - policiesResponse, - RbacConstants.getExpectedPolicies(), - ); - }); + }, + ); test("Create new role for rhdh-qe, change its name, and deny it from reading catalog entities", async () => { const rbacApi = await RhdhRbacApi.build(apiToken); @@ -564,8 +593,8 @@ test.describe.serial("Test RBAC", () => { await page.reload(); await uiHelper.openSidebar("Catalog"); await uiHelper.clickButton("Self-service"); - expect(await uiHelper.isLinkVisible("Register Existing Component")); - await uiHelper.clickButton("Register Existing Component"); + await uiHelper.verifyLinkVisible("Import an existing Git repository"); + await uiHelper.clickButton("Import an existing Git repository"); const catalogImport = new CatalogImport(page); const component = "https://github.com/janus-qe/custom-catalog-entities/blob/main/timestamp-catalog-info.yaml"; @@ -651,7 +680,6 @@ test.describe.serial("Test RBAC", () => { }); test.describe.serial("Test RBAC ownership conditional rule", () => { - // eslint-disable-next-line no-empty-pattern test.beforeEach(async ({}, testInfo) => { testInfo.setTimeout(testInfo.timeout + 30_000); // Additional time due to repeated timeout failure in OSD env. }); @@ -661,15 +689,15 @@ test.describe.serial("Test RBAC", () => { }) => { const common = new Common(page); await common.loginAsKeycloakUser(); - await page.goto("/rbac"); + const uiHelper = new UIhelper(page); + await uiHelper.goToPageUrl("/rbac"); await common.waitForLoad(); await new UIhelper(page).verifyHeading("RBAC", 30_000); - const uiHelper = new UIhelper(page); const rbacPo = new RbacPo(page); await rbacPo.createRBACConditionRole( "test-conditional-role", - [process.env.QE_USER6_ID], + [`${process.env.QE_USER6_ID} ${process.env.QE_USER6_ID}`], "user:default/rhdh-qe-6", ); @@ -690,11 +718,11 @@ test.describe.serial("Test RBAC", () => { process.env.QE_USER6_ID, process.env.QE_USER6_PASS, ); - await page.goto("/rbac"); + const uiHelper = new UIhelper(page); + await uiHelper.goToPageUrl("/rbac"); await common.waitForLoad(); await new UIhelper(page).verifyHeading("RBAC", 30_000); - const uiHelper = new UIhelper(page); const rbacPo = new RbacPo(page); const testUser = "Jonathon Page"; await rbacPo.createRole( @@ -737,7 +765,8 @@ test.describe.serial("Test RBAC", () => { test("Ensure that the admin can revoke access", async ({ page }) => { const common = new Common(page); await common.loginAsKeycloakUser(); - await page.goto("/rbac"); + const uiHelper = new UIhelper(page); + await uiHelper.goToPageUrl("/rbac"); await common.waitForLoad(); await new UIhelper(page).verifyHeading("RBAC", 30_000); @@ -754,7 +783,7 @@ test.describe.serial("Test RBAC", () => { const uiHelper = new UIhelper(page); await uiHelper.openSidebarButton("Administration"); const dropdownMenuLocator = page.locator(`text="RBAC"`); - await expect(dropdownMenuLocator).not.toBeVisible(); + await expect(dropdownMenuLocator).toBeHidden(); }); }); }); diff --git a/e2e-tests/playwright/e2e/plugins/scorecard/scorecard.spec.ts b/e2e-tests/playwright/e2e/plugins/scorecard/scorecard.spec.ts new file mode 100644 index 0000000000..4fe4f7ba5b --- /dev/null +++ b/e2e-tests/playwright/e2e/plugins/scorecard/scorecard.spec.ts @@ -0,0 +1,157 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { test, expect } from "@playwright/test"; +import { Common } from "../../../utils/common"; +import { mockScorecardResponse } from "../../../utils/scorecard-utils"; +import { ComponentImportPage } from "../../../support/page-objects/scorecard/component-import-page"; +import { Catalog } from "../../../support/pages/catalog"; +import { ScorecardPage } from "../../../support/page-objects/scorecard/scorecard-page"; +import { + CUSTOM_SCORECARD_RESPONSE, + EMPTY_SCORECARD_RESPONSE, + UNAVAILABLE_METRIC_RESPONSE, + INVALID_THRESHOLD_RESPONSE, +} from "../../../utils/scorecard-response-utils"; + +test.describe.serial("Scorecard Plugin Tests", () => { + let context; + let page; + let catalog: Catalog; + let importPage: ComponentImportPage; + let scorecardPage: ScorecardPage; + + test.beforeAll(async ({ browser }, testInfo) => { + testInfo.annotations.push({ + type: "component", + description: "scorecard", + }); + + context = await browser.newContext(); + page = await context.newPage(); + catalog = new Catalog(page); + importPage = new ComponentImportPage(page); + scorecardPage = new ScorecardPage(page); + await new Common(page).loginAsKeycloakUser(); + }); + + test.afterAll(async () => { + await context?.close(); + }); + + test("Import component and validate scorecard tabs for GitHub PRs and Jira tickets", async () => { + await mockScorecardResponse(page, CUSTOM_SCORECARD_RESPONSE); + + await catalog.go(); + await importPage.startComponentImport(); + await importPage.analyzeComponent( + "https://github.com/rhdh-pai-qe/backstage-catalog/blob/main/catalog-info.yaml", + ); + await importPage.viewImportedComponent(); + await scorecardPage.openTab(); + + await scorecardPage.verifyScorecardValues({ + "GitHub open PRs": "9", + "Jira open blocking tickets": "8", + }); + + for (const metric of scorecardPage.scorecardMetrics) { + await scorecardPage.validateScorecardAriaFor(metric); + } + }); + + test("Display empty state when scorecard API returns no metrics", async () => { + await mockScorecardResponse(page, EMPTY_SCORECARD_RESPONSE); + + await catalog.go(); + await catalog.goToByName("rhdh-app"); + await scorecardPage.openTab(); + + await scorecardPage.expectEmptyState(); + }); + + test("Displays error state for unavailable data while rendering metrics", async () => { + await mockScorecardResponse(page, UNAVAILABLE_METRIC_RESPONSE); + + await catalog.go(); + await catalog.goToByName("rhdh-app"); + await scorecardPage.openTab(); + + const jiraMetric = scorecardPage.scorecardMetrics[1]; + const githubMetric = scorecardPage.scorecardMetrics[0]; + + const isJiraVisible = await scorecardPage.isScorecardVisible( + jiraMetric.title, + ); + expect(isJiraVisible).toBe(true); + + const isGithubVisible = await scorecardPage.isScorecardVisible( + githubMetric.title, + ); + expect(isGithubVisible).toBe(true); + + const errorLocator = page.getByRole("heading", { + name: "Metric data unavailable", + }); + await expect(errorLocator).toBeVisible(); + + await errorLocator.hover(); + const errorTooltip = UNAVAILABLE_METRIC_RESPONSE.find( + (metric) => metric.id === "github.open-prs", + )?.error; + + expect(errorTooltip).toBeTruthy(); + await expect(page.getByText(errorTooltip!)).toBeVisible(); + + await scorecardPage.validateScorecardAriaFor(jiraMetric); + }); + + test("Display error state for invalid threshold config while rendering metrics", async () => { + await mockScorecardResponse(page, INVALID_THRESHOLD_RESPONSE); + + await catalog.go(); + await catalog.goToByName("rhdh-app"); + await scorecardPage.openTab(); + + const githubMetric = scorecardPage.scorecardMetrics[0]; + const jiraMetric = scorecardPage.scorecardMetrics[1]; + + const isGithubVisible = await scorecardPage.isScorecardVisible( + githubMetric.title, + ); + expect(isGithubVisible).toBe(true); + + const isJiraVisible = await scorecardPage.isScorecardVisible( + jiraMetric.title, + ); + expect(isJiraVisible).toBe(true); + + const errorLocator = page.getByRole("heading", { + name: "Invalid thresholds", + }); + await expect(errorLocator).toBeVisible(); + + await errorLocator.hover(); + const errorTooltip = INVALID_THRESHOLD_RESPONSE.find( + (metric) => metric.id === "github.open-prs", + )?.result?.thresholdResult?.error; + + expect(errorTooltip).toBeTruthy(); + await expect(page.getByText(errorTooltip!)).toBeVisible(); + + await scorecardPage.validateScorecardAriaFor(jiraMetric); + }); +}); diff --git a/e2e-tests/playwright/e2e/plugins/tekton/tekton.spec.ts b/e2e-tests/playwright/e2e/plugins/tekton/tekton.spec.ts index 436f6ae56b..28963d572c 100644 --- a/e2e-tests/playwright/e2e/plugins/tekton/tekton.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/tekton/tekton.spec.ts @@ -18,6 +18,11 @@ test.describe("Test Tekton plugin", () => { let catalog: Catalog; test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + const page = (await setupBrowser(browser, testInfo)).page; common = new Common(page); await common.loginAsGuest(); diff --git a/e2e-tests/playwright/e2e/plugins/topology/topology-rbac.spec.ts b/e2e-tests/playwright/e2e/plugins/topology/topology-rbac.spec.ts index c0e365bbff..de2a81565d 100644 --- a/e2e-tests/playwright/e2e/plugins/topology/topology-rbac.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/topology/topology-rbac.spec.ts @@ -10,6 +10,13 @@ test.describe("Test Topology Plugin with RBAC", () => { let catalog: Catalog; let topology: Topology; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test.beforeEach(async ({ page }, testInfo) => { if (testInfo.retry > 0) { // progressively increase test timeout for retries @@ -57,25 +64,22 @@ test.describe("Test Topology Plugin with RBAC", () => { // User is able to read from the catalog // User has 'kubernetes.clusters.read', 'kubernetes.resources.read', 'kubernetes.proxy' permissions - test.describe.skip( - "Verify a user with permissions is able to access the Topology plugin", - () => { - //Skipping for now as it is failing RHIDP-7164 - test.beforeEach(async () => { - await common.loginAsKeycloakUser(); + test.describe("Verify a user with permissions is able to access the Topology plugin", () => { + //Skipping for now as it is failing RHIDP-7164 + test.beforeEach(async () => { + await common.loginAsKeycloakUser(); - await catalog.goToBackstageJanusProject(); - await uiHelper.clickTab("Topology"); - }); + await catalog.goToBackstageJanusProject(); + await uiHelper.clickTab("Topology"); + }); - test("Verify pods visibility in the Topology tab", async () => { - await topology.verifyDeployment("topology-test"); - }); + test("Verify pods visibility in the Topology tab", async () => { + await topology.verifyDeployment("topology-test"); + }); - test("Verify pod logs visibility in the Topology tab", async () => { - await topology.verifyDeployment("topology-test"); - await topology.verifyPodLogs(true); - }); - }, - ); + test("Verify pod logs visibility in the Topology tab", async () => { + await topology.verifyDeployment("topology-test"); + await topology.verifyPodLogs(true); + }); + }); }); diff --git a/e2e-tests/playwright/e2e/plugins/topology/topology.spec.ts b/e2e-tests/playwright/e2e/plugins/topology/topology.spec.ts index aeaa574b8f..58aeb302fb 100644 --- a/e2e-tests/playwright/e2e/plugins/topology/topology.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/topology/topology.spec.ts @@ -1,4 +1,4 @@ -import { test, expect } from "@playwright/test"; +import { test, expect, type Page } from "@playwright/test"; import { Common } from "../../../utils/common"; import { UIhelper } from "../../../utils/ui-helper"; import { Catalog } from "../../../support/pages/catalog"; @@ -10,6 +10,13 @@ test.describe("Test Topology Plugin", () => { let catalog: Catalog; let topology: Topology; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + test.beforeEach(async ({ page }) => { common = new Common(page); uiHelper = new UIhelper(page); @@ -18,83 +25,108 @@ test.describe("Test Topology Plugin", () => { await common.loginAsGuest(); }); - test("Verify pods visibility in the Topology tab", async ({ - page, - }, testInfo) => { - // progressively increase test timeout for retries - test.setTimeout(150000 + testInfo.retry * 30000); - await catalog.goToBackstageJanusProject(); - await uiHelper.clickTab("Topology"); - await uiHelper.verifyText("backstage-janus"); - await page.getByRole("button", { name: "Fit to Screen" }).click(); - await topology.verifyDeployment("topology-test"); - await uiHelper.verifyButtonURL("Open URL", "topology-test-route", { - locator: `[data-test-id="topology-test"]`, - }); - await uiHelper.clickTab("Details"); - await uiHelper.verifyText("Status"); - await uiHelper.verifyText("Active"); - await uiHelper.clickTab("Resources"); - await uiHelper.verifyHeading("Pods"); - await uiHelper.verifyHeading("Services"); - if (await page.getByText("Ingresses").isVisible()) { - await uiHelper.verifyHeading("Ingresses"); - await uiHelper.verifyText("I"); + // Helper function to determine resource type + async function getResourceType(page: Page): Promise<"ingress" | "route"> { + await page.waitForLoadState(); + const hasIngresses = await page.getByText("Ingresses").isVisible(); + return hasIngresses ? "ingress" : "route"; + } + + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2101 + test.fixme( + "Verify pods visibility in the Topology tab", + async ({ page }, testInfo) => { + // progressively increase test timeout for retries + test.setTimeout(150000 + testInfo.retry * 30000); + await catalog.goToBackstageJanusProject(); + await uiHelper.clickTab("Topology"); + await uiHelper.verifyText("backstage-janus"); + await page.getByRole("button", { name: "Fit to Screen" }).click(); + await page + .locator('[data-test-id="topology-test"]') + .getByTestId(/(status-error|status-ok)/) + .first() + .click(); + await uiHelper.verifyDivHasText( + /Pipeline (Succeeded|Failed|Cancelled|Running)/, + ); + await uiHelper.verifyDivHasText( + /\d+ (Succeeded|Failed|Cancelled|Running)/, + ); + await topology.verifyDeployment("topology-test"); + await uiHelper.verifyButtonURL("Open URL", "topology-test-route", { + locator: `[data-test-id="topology-test"]`, + }); + await uiHelper.clickTab("Details"); + await uiHelper.verifyText("Status"); + await uiHelper.verifyText("Active"); + await uiHelper.clickTab("Resources"); + await uiHelper.verifyHeading("Pods"); + await uiHelper.verifyHeading("Services"); + + // Determine resource type and run appropriate test + const resourceType = await getResourceType(page); + + // eslint-disable-next-line playwright/no-conditional-in-test + if (resourceType === "ingress") { + await testIngressResources(page, uiHelper); + } else { + await testRouteResources(page, uiHelper); + } + + await uiHelper.verifyText("Location:"); + await expect(page.getByTitle("Deployment")).toBeVisible(); + await uiHelper.verifyText("S"); + await expect(page.locator("rect").first()).toBeVisible(); + await uiHelper.clickTab("Details"); + await page.getByLabel("Pod").hover(); + await page.getByText("Display options").click(); + await page.getByLabel("Pod count").click(); + await uiHelper.verifyText("1"); + await uiHelper.verifyText("Pod"); + + // await topology.hoverOnPodStatusIndicator(); + // await uiHelper.verifyTextInTooltip("Running"); + // await uiHelper.verifyText("1Running"); + + await uiHelper.verifyButtonURL( + "Edit source code", + "https://github.com/janus-idp/backstage-showcase", + ); + await uiHelper.clickTab("Resources"); + await uiHelper.verifyText("P"); + await expect(page.getByTestId("icon-with-title-Running")).toBeVisible(); await expect( - page - .getByTestId("ingress-list") - .getByRole("link", { name: "topology-test-route" }) - .first(), + page.getByTestId("icon-with-title-Running").locator("svg"), ).toBeVisible(); - await expect(page.locator("pre").first()).toBeVisible(); - } else { - await uiHelper.verifyHeading("Routes"); - await uiHelper.verifyText("RT"); await expect( - page.getByRole("link", { name: "topology-test-route" }).first(), - ).toBeVisible(); - } - await uiHelper.verifyText("Location:"); - await expect(page.getByTitle("Deployment")).toBeVisible(); - await uiHelper.verifyText("S"); - await expect(page.locator("rect").first()).toBeVisible(); - await uiHelper.clickTab("Details"); - await page.getByLabel("Pod").hover(); - await page.getByText("Display options").click(); - await page.getByLabel("Pod count").click(); - await uiHelper.verifyText("1"); - await uiHelper.verifyText("Pod"); - // await topology.hoverOnPodStatusIndicator(); - // await uiHelper.verifyTextInTooltip("Running"); - // await uiHelper.verifyText("1Running"); - await uiHelper.verifyButtonURL( - "Edit source code", - "https://github.com/janus-idp/backstage-showcase", - ); - await uiHelper.clickTab("Resources"); - await uiHelper.verifyText("P"); - await expect(page.getByTestId("icon-with-title-Running")).toBeVisible(); - await expect( - page.getByTestId("icon-with-title-Running").locator("svg"), - ).toBeVisible(); - await expect( - page.getByTestId("icon-with-title-Running").getByTestId("status-text"), - ).toHaveText("Running"); - await uiHelper.verifyHeading("PipelineRuns"); - await uiHelper.verifyText("PL"); - await uiHelper.verifyText("PLR"); - // await expect(async () => { - // await page.getByTestId("status-ok").first().click({ - // force: true, - // timeout: 30000, - // }); - // }).toPass({ - // timeout: 30000, - // intervals: [1000, 2000, 3000], - // }); - // await uiHelper.verifyDivHasText( - // /Pipeline (Succeeded|Failed|Cancelled|Running)Task/, - // ); - // await uiHelper.verifyText(/Pipeline (Succeeded|Failed|Cancelled|Running)/); - }); + page.getByTestId("icon-with-title-Running").getByTestId("status-text"), + ).toHaveText("Running"); + await uiHelper.verifyHeading("PipelineRuns"); + await uiHelper.verifyText("PL"); + await uiHelper.verifyText("PLR"); + await uiHelper.verifyText(/(Succeeded|Failed|Cancelled|Running)/); + }, + ); }); + +// Helper functions for resource-specific testing +async function testIngressResources(page: Page, uiHelper: UIhelper) { + await uiHelper.verifyHeading("Ingresses"); + await uiHelper.verifyText("I"); + await expect( + page + .getByTestId("ingress-list") + .getByRole("link", { name: "topology-test-route" }) + .first(), + ).toBeVisible(); + await expect(page.locator("pre").first()).toBeVisible(); +} + +async function testRouteResources(page: Page, uiHelper: UIhelper) { + await uiHelper.verifyHeading("Routes"); + await uiHelper.verifyText("RT"); + await expect( + page.getByRole("link", { name: "topology-test-route" }).first(), + ).toBeVisible(); +} diff --git a/e2e-tests/playwright/e2e/plugins/user-settings-info-card.spec.ts b/e2e-tests/playwright/e2e/plugins/user-settings-info-card.spec.ts index efbae8f4d0..e932cd8c34 100644 --- a/e2e-tests/playwright/e2e/plugins/user-settings-info-card.spec.ts +++ b/e2e-tests/playwright/e2e/plugins/user-settings-info-card.spec.ts @@ -1,9 +1,16 @@ import { test } from "@playwright/test"; import { Common } from "../../utils/common"; import { UIhelper } from "../../utils/ui-helper"; -import { UI_HELPER_ELEMENTS } from "../../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../../support/page-objects/global-obj"; test.describe("Test user settings info card", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "plugins", + }); + }); + let uiHelper: UIhelper; test.beforeEach(async ({ page }) => { @@ -15,7 +22,7 @@ test.describe("Test user settings info card", () => { test("Check if customized build info is rendered", async ({ page }) => { await uiHelper.openSidebar("Home"); - page.getByText("Guest").click(); + await page.getByText("Guest").click(); await page.getByRole("menuitem", { name: "Settings" }).click(); await uiHelper.verifyTextInSelector( UI_HELPER_ELEMENTS.MuiCardHeader, diff --git a/e2e-tests/playwright/e2e/catalog-scaffolded-from-link.spec.ts b/e2e-tests/playwright/e2e/scaffolder-backend-module-annotator.spec.ts similarity index 66% rename from e2e-tests/playwright/e2e/catalog-scaffolded-from-link.spec.ts rename to e2e-tests/playwright/e2e/scaffolder-backend-module-annotator.spec.ts index 4ac48f6427..0b1d119422 100644 --- a/e2e-tests/playwright/e2e/catalog-scaffolded-from-link.spec.ts +++ b/e2e-tests/playwright/e2e/scaffolder-backend-module-annotator.spec.ts @@ -8,20 +8,22 @@ import { runAccessibilityTests } from "../utils/accessibility"; let page: Page; -test.describe.serial("Link Scaffolded Templates to Catalog Items", () => { +test.describe.serial("Test Scaffolder Backend Module Annotator Actions", () => { test.skip(() => process.env.JOB_NAME.includes("osd-gcp")); // skipping due to RHIDP-5704 on OSD Env let uiHelper: UIhelper; let common: Common; let catalogImport: CatalogImport; const template = - "https://github.com/janus-qe/01-scaffolder-template/blob/main/01-scaffolder-template.yaml"; + "https://github.com/backstage/community-plugins/blob/main/workspaces/scaffolder-backend-module-annotator/plugins/scaffolder-backend-module-annotator/examples/templates/01-scaffolder-template.yaml"; const reactAppDetails = { owner: "janus-qe/maintainers", componentName: `test-scaffoldedfromlink-${Date.now()}`, componentPartialName: `test-scaffoldedfromlink-`, description: "react app using template", + label: "some-label", + annotation: "some-annotation", repo: `test-scaffolded-${Date.now()}`, repoOwner: Buffer.from( process.env.GITHUB_ORG || "amFudXMtcWU=", @@ -30,6 +32,11 @@ test.describe.serial("Link Scaffolded Templates to Catalog Items", () => { }; test.beforeAll(async ({ browser }, testInfo) => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + page = (await setupBrowser(browser, testInfo)).page; common = new Common(page); @@ -39,7 +46,6 @@ test.describe.serial("Link Scaffolded Templates to Catalog Items", () => { await common.loginAsGuest(); }); - // eslint-disable-next-line no-empty-pattern test("Register a Template", async ({}, testInfo) => { await uiHelper.openSidebar("Catalog"); await uiHelper.verifyText("Name"); @@ -47,7 +53,7 @@ test.describe.serial("Link Scaffolded Templates to Catalog Items", () => { await runAccessibilityTests(page, testInfo); await uiHelper.clickButton("Self-service"); - await uiHelper.clickButton("Register Existing Component"); + await uiHelper.clickButton("Import an existing Git repository"); await catalogImport.registerExistingComponent(template, false); }); @@ -66,6 +72,11 @@ test.describe.serial("Link Scaffolded Templates to Catalog Items", () => { reactAppDetails.description, ); await uiHelper.fillTextInputByLabel("Owner", reactAppDetails.owner); + await uiHelper.fillTextInputByLabel("Label", reactAppDetails.label); + await uiHelper.fillTextInputByLabel( + "Annotation", + reactAppDetails.annotation, + ); await uiHelper.clickButton("Next"); await uiHelper.fillTextInputByLabel("Owner", reactAppDetails.repoOwner); @@ -82,6 +93,12 @@ test.describe.serial("Link Scaffolded Templates to Catalog Items", () => { await uiHelper.verifyRowInTableByUniqueText("Description", [ reactAppDetails.description, ]); + await uiHelper.verifyRowInTableByUniqueText("Label", [ + reactAppDetails.label, + ]); + await uiHelper.verifyRowInTableByUniqueText("Annotation", [ + reactAppDetails.annotation, + ]); await uiHelper.verifyRowInTableByUniqueText("Repository Location", [ `github.com?owner=${reactAppDetails.repoOwner}&repo=${reactAppDetails.repo}`, ]); @@ -152,6 +169,66 @@ test.describe.serial("Link Scaffolded Templates to Catalog Items", () => { await uiHelper.verifyText("Provide some simple information"); }); + test("Verify Registered Component has templated label in entity Raw Yaml", async () => { + await uiHelper.openCatalogSidebar("Component"); + await uiHelper.searchInputPlaceholder(reactAppDetails.componentName); + + await uiHelper.verifyRowInTableByUniqueText( + `${reactAppDetails.componentName}`, + ["website"], + ); + await uiHelper.clickLink(`${reactAppDetails.componentName}`); + + await catalogImport.inspectEntityAndVerifyYaml( + `labels:\n custom: ${reactAppDetails.label}\n`, + ); + }); + + test("Verify Registered Component has templated annotation in entity Raw Yaml", async () => { + await uiHelper.openCatalogSidebar("Component"); + await uiHelper.searchInputPlaceholder(reactAppDetails.componentName); + + await uiHelper.verifyRowInTableByUniqueText( + `${reactAppDetails.componentName}`, + ["website"], + ); + await uiHelper.clickLink(`${reactAppDetails.componentName}`); + + await catalogImport.inspectEntityAndVerifyYaml( + `custom.io/annotation: ${reactAppDetails.annotation}`, + ); + }); + + test("Verify Registered Component has templated version in entity Raw Yaml", async () => { + await uiHelper.openCatalogSidebar("Component"); + await uiHelper.searchInputPlaceholder(reactAppDetails.componentName); + + await uiHelper.verifyRowInTableByUniqueText( + `${reactAppDetails.componentName}`, + ["website"], + ); + await uiHelper.clickLink(`${reactAppDetails.componentName}`); + + await catalogImport.inspectEntityAndVerifyYaml( + `backstage.io/template-version: 0.0.1`, + ); + }); + + test("Verify Registered Template has templated version in entity Raw Yaml", async () => { + await uiHelper.openSidebar("Catalog"); + await uiHelper.selectMuiBox("Kind", "Template"); + + await uiHelper.searchInputPlaceholder("Create React App Template\n"); + await uiHelper.verifyRowInTableByUniqueText("Create React App Template", [ + "website", + ]); + await uiHelper.clickLink("Create React App Template"); + + await catalogImport.inspectEntityAndVerifyYaml( + `backstage.io/template-version: 0.0.1`, + ); + }); + test.afterAll(async () => { await APIHelper.githubRequest( "DELETE", @@ -167,7 +244,7 @@ test.describe.serial("Link Scaffolded Templates to Catalog Items", () => { const selector = 'a[href*="/catalog/default/component/test-scaffoldedfromlink-"]'; await page.locator(selector).first().waitFor({ state: "visible" }); - const link = await page.locator(selector).first(); + const link = page.locator(selector).first(); await expect(link).toBeVisible(); await link.click(); } diff --git a/e2e-tests/playwright/e2e/smoke-test.spec.ts b/e2e-tests/playwright/e2e/smoke-test.spec.ts index f61116e23f..de86ad9347 100644 --- a/e2e-tests/playwright/e2e/smoke-test.spec.ts +++ b/e2e-tests/playwright/e2e/smoke-test.spec.ts @@ -1,23 +1,24 @@ import { test } from "@playwright/test"; import { UIhelper } from "../utils/ui-helper"; -import { HomePage } from "../support/pages/home-page"; import { Common } from "../utils/common"; - test.describe("Smoke test", () => { let uiHelper: UIhelper; - let homePage: HomePage; let common: Common; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + }); + test.beforeEach(async ({ page }) => { uiHelper = new UIhelper(page); - homePage = new HomePage(page); common = new Common(page); await common.loginAsGuest(); }); - test("Verify the Homepage renders with Search Bar, Quick Access and Starred Entities", async () => { + test("Verify the Homepage renders", async () => { await uiHelper.verifyHeading("Welcome back!"); - await uiHelper.openSidebar("Home"); - await homePage.verifyQuickAccess("Developer Tools", "Podman Desktop"); }); }); diff --git a/e2e-tests/playwright/e2e/techdocs.spec.ts b/e2e-tests/playwright/e2e/techdocs.spec.ts index ff69d16624..79e056606d 100644 --- a/e2e-tests/playwright/e2e/techdocs.spec.ts +++ b/e2e-tests/playwright/e2e/techdocs.spec.ts @@ -9,6 +9,13 @@ test.describe("TechDocs", () => { let uiHelper: UIhelper; let catalog: Catalog; + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + }); + async function docsTextHighlight(page: Page) { await page.evaluate(() => { const shadowRoot = document.querySelector( diff --git a/e2e-tests/playwright/e2e/verify-redis-cache.spec.ts b/e2e-tests/playwright/e2e/verify-redis-cache.spec.ts index df454fe793..ab2a92e886 100644 --- a/e2e-tests/playwright/e2e/verify-redis-cache.spec.ts +++ b/e2e-tests/playwright/e2e/verify-redis-cache.spec.ts @@ -5,6 +5,13 @@ import Redis from "ioredis"; import { ChildProcessWithoutNullStreams, exec, spawn } from "child_process"; test.describe("Verify Redis Cache DB", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "core", + }); + }); + test.describe.configure({ mode: "serial" }); let common: Common; let uiHelper: UIhelper; diff --git a/e2e-tests/playwright/e2e/verify-tls-config-health-check.spec.ts b/e2e-tests/playwright/e2e/verify-tls-config-health-check.spec.ts index 73deb90c76..ea7f4e0007 100644 --- a/e2e-tests/playwright/e2e/verify-tls-config-health-check.spec.ts +++ b/e2e-tests/playwright/e2e/verify-tls-config-health-check.spec.ts @@ -4,6 +4,13 @@ import { KubeClient } from "../utils/kube-client"; test.describe .serial("Verify TLS configuration with Postgres DB health check", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "data-management", + }); + }); + const namespace = process.env.NAME_SPACE_RUNTIME || "showcase-runtime"; const job: string = process.env.JOB_NAME; let deploymentName = "rhdh-backstage"; @@ -14,55 +21,64 @@ test.describe const hostLatest2 = Buffer.from(process.env.RDS_2_HOST).toString("base64"); const hostLatest3 = Buffer.from(process.env.RDS_3_HOST).toString("base64"); - //TODO: Remove the skip once the https://issues.redhat.com/browse/RHIDP-7869 is fixed - test.skip("Verify successful DB connection and successful initialization of plugins with latest-1 postgres version", async ({ - page, - }) => { - const common = new Common(page); - await common.loginAsGuest(); - }); + //TODO: Remove the fixme once the https://issues.redhat.com/browse/RHIDP-7869 is fixed + test.fixme( + "Verify successful DB connection and successful initialization of plugins with latest-1 postgres version", + async ({ page }) => { + const common = new Common(page); + await common.loginAsGuest(); + }, + ); - //TODO: Remove the skip once the https://issues.redhat.com/browse/RHIDP-7869 is fixed - test.skip("Change the config to use the latest-2 postgres version", async () => { - const kubeCLient = new KubeClient(); - test.setTimeout(180000); - const secretData = { - POSTGRES_HOST: hostLatest2, - }; - const patch = { - data: secretData, - }; - await kubeCLient.updateSecret(secretName, namespace, patch); - await kubeCLient.restartDeployment(deploymentName, namespace); - }); + //TODO: Remove the fixme once the https://issues.redhat.com/browse/RHIDP-7869 is fixed + test.fixme( + "Change the config to use the latest-2 postgres version", + async () => { + const kubeCLient = new KubeClient(); + test.setTimeout(180000); + const secretData = { + POSTGRES_HOST: hostLatest2, + }; + const patch = { + data: secretData, + }; + await kubeCLient.updateSecret(secretName, namespace, patch); + await kubeCLient.restartDeployment(deploymentName, namespace); + }, + ); - //TODO: Remove the skip once the https://issues.redhat.com/browse/RHIDP-7869 is fixed - test.skip("Verify successful DB connection and successful initialization of plugins with latest-2 postgres version", async ({ - page, - }) => { - const common = new Common(page); - await common.loginAsGuest(); - }); + //TODO: Remove the fixme once the https://issues.redhat.com/browse/RHIDP-7869 is fixed + test.fixme( + "Verify successful DB connection and successful initialization of plugins with latest-2 postgres version", + async ({ page }) => { + const common = new Common(page); + await common.loginAsGuest(); + }, + ); - //TODO: Remove the skip once the https://issues.redhat.com/browse/RHIDP-7869 is fixed - test.skip("Change the config to use the latest-3 postgres version", async () => { - const kubeCLient = new KubeClient(); - test.setTimeout(180000); - const secretData = { - POSTGRES_HOST: hostLatest3, - }; - const patch = { - data: secretData, - }; - await kubeCLient.updateSecret(secretName, namespace, patch); - await kubeCLient.restartDeployment(deploymentName, namespace); - }); + //TODO: Remove the fixme once the https://issues.redhat.com/browse/RHIDP-7869 is fixed + test.fixme( + "Change the config to use the latest-3 postgres version", + async () => { + const kubeCLient = new KubeClient(); + test.setTimeout(180000); + const secretData = { + POSTGRES_HOST: hostLatest3, + }; + const patch = { + data: secretData, + }; + await kubeCLient.updateSecret(secretName, namespace, patch); + await kubeCLient.restartDeployment(deploymentName, namespace); + }, + ); - //TODO: Remove the skip once the https://issues.redhat.com/browse/RHIDP-7869 is fixed - test.skip("Verify successful DB connection and successful initialization of plugins with latest-3 postgres version", async ({ - page, - }) => { - const common = new Common(page); - await common.loginAsGuest(); - }); + //TODO: Remove the fixme once the https://issues.redhat.com/browse/RHIDP-7869 is fixed + test.fixme( + "Verify successful DB connection and successful initialization of plugins with latest-3 postgres version", + async ({ page }) => { + const common = new Common(page); + await common.loginAsGuest(); + }, + ); }); diff --git a/e2e-tests/playwright/e2e/verify-tls-config-with-external-postgres-db.spec.ts b/e2e-tests/playwright/e2e/verify-tls-config-with-external-postgres-db.spec.ts index 3277f10451..4a0cacbe9a 100644 --- a/e2e-tests/playwright/e2e/verify-tls-config-with-external-postgres-db.spec.ts +++ b/e2e-tests/playwright/e2e/verify-tls-config-with-external-postgres-db.spec.ts @@ -1,8 +1,14 @@ import { test, expect } from "@playwright/test"; import { UIhelper } from "../utils/ui-helper"; import { Common } from "../utils/common"; - test.describe("Verify TLS configuration with external Postgres DB", () => { + test.beforeAll(async () => { + test.info().annotations.push({ + type: "component", + description: "data-management", + }); + }); + test("Verify successful DB connection and display of expected entities in the Home Page and Catalog", async ({ page, }) => { diff --git a/e2e-tests/playwright/support/pageObjects/catalog/catalog-users-obj.ts b/e2e-tests/playwright/support/page-objects/catalog/catalog-users-obj.ts similarity index 100% rename from e2e-tests/playwright/support/pageObjects/catalog/catalog-users-obj.ts rename to e2e-tests/playwright/support/page-objects/catalog/catalog-users-obj.ts diff --git a/e2e-tests/playwright/support/pageObjects/global-fab-po.ts b/e2e-tests/playwright/support/page-objects/global-fab-po.ts similarity index 95% rename from e2e-tests/playwright/support/pageObjects/global-fab-po.ts rename to e2e-tests/playwright/support/page-objects/global-fab-po.ts index 3a6e23bb1e..67c280b887 100644 --- a/e2e-tests/playwright/support/pageObjects/global-fab-po.ts +++ b/e2e-tests/playwright/support/page-objects/global-fab-po.ts @@ -13,7 +13,7 @@ export class FabPo extends PageObject { public async verifyPopup(expectedUrl: string) { const popupPromise = this.page.waitForEvent("popup"); const popup = await popupPromise; - await expect(popup.url()).toContain(expectedUrl); + expect(popup.url()).toContain(expectedUrl); } public async clickFabMenuByLabel(label: string) { diff --git a/e2e-tests/playwright/support/pageObjects/global-obj.ts b/e2e-tests/playwright/support/page-objects/global-obj.ts similarity index 100% rename from e2e-tests/playwright/support/pageObjects/global-obj.ts rename to e2e-tests/playwright/support/page-objects/global-obj.ts diff --git a/e2e-tests/playwright/support/pageObjects/page-obj.ts b/e2e-tests/playwright/support/page-objects/page-obj.ts similarity index 90% rename from e2e-tests/playwright/support/pageObjects/page-obj.ts rename to e2e-tests/playwright/support/page-objects/page-obj.ts index 712584a2d2..7dafa6aa5c 100644 --- a/e2e-tests/playwright/support/pageObjects/page-obj.ts +++ b/e2e-tests/playwright/support/page-objects/page-obj.ts @@ -42,7 +42,7 @@ export const DELETE_ROLE_COMPONENTS = { roleName: 'input[name="delete-role"]', }; -export const ROLE_OVERVIEW_COMPONENTS = { - updatePolicies: 'span[data-testid="update-policies"]', - updateMembers: 'span[data-testid="update-members"]', +export const ROLE_OVERVIEW_COMPONENTS_TEST_ID = { + updatePolicies: "update-policies", + updateMembers: "update-members", }; diff --git a/e2e-tests/playwright/support/pageObjects/page.ts b/e2e-tests/playwright/support/page-objects/page.ts similarity index 100% rename from e2e-tests/playwright/support/pageObjects/page.ts rename to e2e-tests/playwright/support/page-objects/page.ts diff --git a/e2e-tests/playwright/support/pageObjects/rbac-po.ts b/e2e-tests/playwright/support/page-objects/rbac-po.ts similarity index 98% rename from e2e-tests/playwright/support/pageObjects/rbac-po.ts rename to e2e-tests/playwright/support/page-objects/rbac-po.ts index 8231fd9632..7699e561b0 100644 --- a/e2e-tests/playwright/support/pageObjects/rbac-po.ts +++ b/e2e-tests/playwright/support/page-objects/rbac-po.ts @@ -4,7 +4,7 @@ import { DELETE_ROLE_COMPONENTS, SEARCH_OBJECTS_COMPONENTS, ROLES_PAGE_COMPONENTS, -} from "../pageObjects/page-obj"; +} from "./page-obj"; import { type RoleBasedPolicy } from "@backstage-community/plugin-rbac-common"; type PermissionPolicyType = "anyOf" | "not"; @@ -173,7 +173,7 @@ export class RbacPo extends PageObject { } private async next() { - this.uiHelper.clickButton("Next"); + await this.uiHelper.clickButton("Next"); } private async create() { @@ -216,7 +216,7 @@ export class RbacPo extends PageObject { } async pluginRuleCount(number: string) { - expect( + await expect( this.page .locator('span[class*="MuiBadge-badge"]') .filter({ hasText: number }), @@ -234,7 +234,7 @@ export class RbacPo extends PageObject { await this.uiHelper.verifyHeading("Create role"); await this.roleName.fill(name); if (owner) { - this.roleOwner.fill(owner); + await this.roleOwner.fill(owner); } await this.uiHelper.clickButton("Next"); await this.usersAndGroupsField.click(); @@ -295,8 +295,9 @@ export class RbacPo extends PageObject { groups: string[], permissionPolicyType: PermissionPolicyType, pluginId: "catalog" | "kubernetes" | "scaffolder" = "catalog", + owner?: string, ) { - await this.createRoleUsers(name, users, groups); + await this.createRoleUsers(name, users, groups, owner); // select permissions await this.selectPluginsCombobox.click(); diff --git a/e2e-tests/playwright/support/page-objects/scorecard/component-import-page.ts b/e2e-tests/playwright/support/page-objects/scorecard/component-import-page.ts new file mode 100644 index 0000000000..6a9f7deee7 --- /dev/null +++ b/e2e-tests/playwright/support/page-objects/scorecard/component-import-page.ts @@ -0,0 +1,45 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Page } from "@playwright/test"; +import { UIhelper } from "../../../utils/ui-helper"; + +export class ComponentImportPage { + readonly page: Page; + private uiHelper: UIhelper; + + constructor(page: Page) { + this.page = page; + this.uiHelper = new UIhelper(page); + } + + async startComponentImport() { + await this.uiHelper.clickButton("Self-service"); + await this.uiHelper.clickButton("Import an existing Git repository"); + } + + async analyzeComponent(url: string) { + await this.uiHelper.fillTextInputByLabel("URL", url); + await this.uiHelper.clickButton("Analyze"); + await this.uiHelper.clickButton("Import"); + //wait for few seconds + await this.page.waitForTimeout(5000); + } + + async viewImportedComponent() { + await this.uiHelper.clickButton("View Component"); + await this.uiHelper.verifyText("Overview"); + } +} diff --git a/e2e-tests/playwright/support/page-objects/scorecard/scorecard-page.ts b/e2e-tests/playwright/support/page-objects/scorecard/scorecard-page.ts new file mode 100644 index 0000000000..f414ea21c3 --- /dev/null +++ b/e2e-tests/playwright/support/page-objects/scorecard/scorecard-page.ts @@ -0,0 +1,98 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Page, expect } from "@playwright/test"; +import { waitUntilApiCallSucceeds } from "../../../utils/scorecard-utils"; + +export class ScorecardPage { + readonly page: Page; + + constructor(page: Page) { + this.page = page; + } + + get scorecardMetrics() { + return [ + { + title: "GitHub open PRs", + description: + "Current count of open Pull Requests for a given GitHub repository.", + }, + { + title: "Jira open blocking tickets", + description: + "Highlights the number of critical, blocking issues that are currently open in Jira.", + }, + ]; + } + + async openTab() { + const scorecardTab = this.page.getByText("Scorecard"); + await expect(scorecardTab).toBeVisible(); + await Promise.all([ + waitUntilApiCallSucceeds(this.page), + scorecardTab.click(), + ]); + } + + async verifyScorecardValues(expectedValues: { [key: string]: string }) { + for (const [metric, value] of Object.entries(expectedValues)) { + await expect(this.page.getByText(metric)).toBeVisible(); + await expect(this.page.getByText(value)).toBeVisible(); + } + } + + async expectEmptyState() { + await expect(this.page.getByText("No scorecards added yet")).toBeVisible(); + await expect(this.page.getByRole("article")).toContainText( + "Scorecards help you monitor component health at a glance. To begin, explore our documentation for setup guidelines.", + ); + await expect( + this.page.getByRole("link", { name: "View documentation" }), + ).toBeVisible(); + } + + async validateScorecardAriaFor(scorecard: { + title: string; + description: string; + }) { + const { title, description } = scorecard; + + const scorecardSection = this.page + .locator("article") + .filter({ hasText: title }); + + await expect(scorecardSection).toMatchAriaSnapshot(` + - article: + - text: ${title} + - paragraph: ${description} + - paragraph: /Error/ + - paragraph: /Warning/ + - paragraph: /Success/ + `); + } + + async isScorecardVisible(scorecardTitle: string): Promise { + try { + await expect( + this.page.getByText(scorecardTitle, { exact: true }), + ).toBeVisible({ timeout: 10000 }); + return true; + } catch { + return false; + } + } +} diff --git a/e2e-tests/playwright/support/pages/adoption-Insights.ts b/e2e-tests/playwright/support/pages/adoption-Insights.ts deleted file mode 100644 index 76f60e1110..0000000000 --- a/e2e-tests/playwright/support/pages/adoption-Insights.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Page, expect, Locator } from '@playwright/test'; - -export class TestHelper { - readonly page: Page; - - constructor(page: Page) { - this.page = page; - } - - async selectOption(optionName: string) { - const option = this.page.getByRole("option", { name: optionName }); - await option.click(); - } - - async clickByText(text: string) { - const element = this.page.getByText(text); - await element.waitFor({ state: "visible" }); - await element.click(); - } - - async getCountFromPanel(panel: Locator): Promise { - try { - const fullText = await panel.locator('h5.v5-MuiTypography-root').textContent(); - const match = fullText?.match(/\d+/); - - if (match) { - return parseInt(match[0], 10); - } - - return null; // or 0 if you'd prefer a default - } catch (error) { - console.error('Error getting count from panel:', error); - return null; - } - } - - async getVisibleFirstRowText(panel: Locator): Promise { - const firstRow = panel.locator('table.v5-MuiTable-root tbody tr').first(); - - if (await firstRow.isVisible()) { - const cells = firstRow.locator('td'); - const cellCount = await cells.count(); - const texts: string[] = []; - - for (let i = 0; i < cellCount; i++) { - const cellText = await cells.nth(i).textContent(); - texts.push(cellText?.trim() ?? ''); - } - - // Return first and last elements - return [texts[0], texts[texts.length - 1]]; - } - return []; - } - - async populateMissingPanelData( - page: Page, - uiHelper: any, - templatesFirstLast: string[], - catalogEntitiesFirstLast: string[], - techdocsFirstLast: string[] - ): Promise { - if (templatesFirstLast.length === 0) { - // Run a template - const inputText = 'reallyUniqueName'; - await page.getByRole('link', { name: 'Self-service' }).click(); - const chooseButton = page.getByRole('button', { name: 'Choose' }); - await chooseButton.last().click(); - await uiHelper.fillTextInputByLabel('Organization', inputText); - await uiHelper.fillTextInputByLabel('Repository', inputText); - await uiHelper.clickButton("Next"); - await uiHelper.fillTextInputByLabel('Image Builder', inputText); - await uiHelper.fillTextInputByLabel('Image URL', inputText); - await uiHelper.fillTextInputByLabel('Namespace', inputText); - await uiHelper.fillTextInputByLabel('Port', '8080'); - await uiHelper.clickButton('Review'); - await uiHelper.clickButton('Create'); - await page.getByText("Run of Create a tekton CI").waitFor({ state: "visible" }); - } - - if (catalogEntitiesFirstLast.length === 0) { - // Visit a catalog entity - await uiHelper.clickLink("Catalog"); - await uiHelper.clickLink('Red Hat Developer Hub'); - await expect(page.getByText('Red Hat Developer Hub')).toBeVisible(); - } - - if (techdocsFirstLast.length === 0) { - // Visit docs - await uiHelper.clickLink('docs'); - await uiHelper.clickLink('Red Hat Developer Hub'); - } - } - - async expectTopEntriesToBePresent(panelTitle: string) { - const panel = this.page.locator(".v5-MuiPaper-root", { hasText: panelTitle }); - const entries = panel.locator("tbody").locator("tr"); - expect(await entries.count()).toBeGreaterThan(0); - } - - async clickAndVerifyText( - firstEntry: Locator, - expectedText: string - ): Promise { - const [newpage] = await Promise.all([ - this.page.waitForEvent('popup'), - firstEntry.locator('a').click(), - ]); - // Wait for the expected API call to succeed - await this.waitUntilApiCallSucceeds(newpage); - - await newpage.getByText(expectedText).first().waitFor({ state: 'visible' }); - } - - async waitUntilApiCallSucceeds( - page: Page, - urlPart: string = '/api/adoption-insights/events' - ): Promise { - const response = await page.waitForResponse( - async (response) => { - const urlMatches = response.url().includes(urlPart); - const isSuccess = response.status() === 200; - return urlMatches && isSuccess; - }, - { timeout: 60000 } - ); - - expect(response.status()).toBe(200); - } - - async waitUntilApiCallIsMade(page: Page, urlPart: string): Promise { - await page.waitForResponse( - (response) => response.url().includes(urlPart), - { timeout: 60000 } - ); - } - - async waitForPanelApiCalls(page: Page): Promise { - const types = [ - 'active_users', - 'total_users', - 'top_templates', - 'top_catalog_entities', - 'top_plugins', - 'top_techdocs', - 'top_searches' - ]; - - await Promise.all( - types.map(type => this.waitUntilApiCallIsMade( - page, - `/api/adoption-insights/events?type=${type}` - )) - ); - } - - -} - diff --git a/e2e-tests/playwright/support/pages/adoption-insights.ts b/e2e-tests/playwright/support/pages/adoption-insights.ts new file mode 100644 index 0000000000..e9e0193e21 --- /dev/null +++ b/e2e-tests/playwright/support/pages/adoption-insights.ts @@ -0,0 +1,191 @@ +import { Page, expect, Locator } from "@playwright/test"; +import { UIhelper } from "../../utils/ui-helper"; + +export class TestHelper { + readonly page: Page; + + constructor(page: Page) { + this.page = page; + } + + async selectOption(optionName: string) { + const option = this.page.getByRole("option", { name: optionName }); + await option.click(); + } + + async clickByText(text: string) { + const element = this.page.getByText(text); + await element.waitFor({ state: "visible" }); + await element.click(); + } + + async getCountFromPanel(panel: Locator): Promise { + try { + const fullText = await panel + .locator("h5.v5-MuiTypography-root") + .textContent(); + const match = fullText?.match(/\d+/); + + if (match) { + return parseInt(match[0], 10); + } + + return null; // or 0 if you'd prefer a default + } catch (error) { + console.error("Error getting count from panel:", error); + return null; + } + } + + async getVisibleFirstRowText(panel: Locator): Promise { + const firstRow = panel.locator("table.v5-MuiTable-root tbody tr").first(); + + if (await firstRow.isVisible()) { + const cells = firstRow.locator("td"); + const cellCount = await cells.count(); + const texts: string[] = []; + + for (let i = 0; i < cellCount; i++) { + const cellText = await cells.nth(i).textContent(); + texts.push(cellText?.trim() ?? ""); + } + + // Return first and last elements + return [texts[0], texts[texts.length - 1]]; + } + return []; + } + + async populateMissingPanelData( + page: Page, + uiHelper: UIhelper, + templatesFirstLast: string[], + catalogEntitiesFirstLast: string[], + techdocsFirstLast: string[], + ): Promise { + if (templatesFirstLast.length === 0) { + await page.getByRole("link", { name: "Self-service" }).click(); + await page + .getByText("Templates", { exact: true }) + .waitFor({ state: "visible" }); + const panel = page + .getByRole("heading", { name: "Create a tekton CI Pipeline" }) + .first(); + const isPanelVisible = await panel + .isVisible({ timeout: 10000 }) + .catch(() => false); + if (!isPanelVisible) { + const sampleTemplate = + "https://github.com/redhat-developer/red-hat-developer-hub-software-templates/blob/main/templates/github/tekton/template.yaml"; + await page + .getByRole("button", { name: "Import an existing Git repository" }) + .click(); + await page.getByRole("textbox", { name: "URL" }).fill(sampleTemplate); + await page.getByRole("button", { name: "Analyze" }).click(); + await page.getByRole("button", { name: "Import" }).click(); + await page.getByRole("button", { name: "Register" }).click(); + await page.getByRole("link", { name: "Self-service" }).click(); + } + // Run a template + const pipelineCard = panel.locator("..").locator(".."); + await pipelineCard.getByRole("button", { name: "Choose" }).click(); + + const inputText = "reallyUniqueName"; + await uiHelper.fillTextInputByLabel("Organization", inputText); + await uiHelper.fillTextInputByLabel("Repository", inputText); + await uiHelper.clickButton("Next"); + await uiHelper.fillTextInputByLabel("Image Builder", inputText); + await uiHelper.fillTextInputByLabel("Image URL", inputText); + await uiHelper.fillTextInputByLabel("Namespace", inputText); + await page.getByRole("spinbutton", { name: "Port" }).fill("8080"); + await uiHelper.clickButton("Review"); + await uiHelper.clickButton("Create"); + await page + .getByText("Run of Create a tekton CI") + .waitFor({ state: "visible" }); + } + + if (catalogEntitiesFirstLast.length === 0) { + // Visit a catalog entity + await uiHelper.clickLink("Catalog"); + await uiHelper.clickLink("Red Hat Developer Hub"); + await page.waitForTimeout(5000); // wait for the flush interval to be sure + await expect(page.getByText("Red Hat Developer Hub")).toBeVisible(); + } + + if (techdocsFirstLast.length === 0) { + // Visit docs + await page.goto("/docs"); + await uiHelper.clickLink("Red Hat Developer Hub"); + await uiHelper.openSidebarButton("Administration"); + } + } + + async expectTopEntriesToBePresent(panelTitle: string) { + const panel = this.page.locator(".v5-MuiPaper-root", { + hasText: panelTitle, + }); + const entries = panel.locator("tbody").locator("tr"); + expect(await entries.count()).toBeGreaterThan(0); + } + + async clickAndVerifyText( + firstEntry: Locator, + expectedText: string, + ): Promise { + const [newpage] = await Promise.all([ + this.page.waitForEvent("popup"), + firstEntry.locator("a").click(), + ]); + // Wait for the expected API call to succeed + await this.waitUntilApiCallSucceeds(newpage); + + await newpage.getByText(expectedText).first().waitFor({ state: "visible" }); + await newpage.waitForTimeout(5000); // wait for the flush interval to be sure + await newpage.close(); + } + + async waitUntilApiCallSucceeds( + page: Page, + urlPart: string = "/api/adoption-insights/events", + ): Promise { + const response = await page.waitForResponse( + async (response) => { + const urlMatches = response.url().includes(urlPart); + const isSuccess = response.status() === 200; + return urlMatches && isSuccess; + }, + { timeout: 60000 }, + ); + + expect(response.status()).toBe(200); + } + + async waitUntilApiCallIsMade(page: Page, urlPart: string): Promise { + await page.waitForResponse((response) => response.url().includes(urlPart), { + timeout: 60000, + }); + } + + async waitForPanelApiCalls(page: Page): Promise { + const types = [ + "active_users", + "total_users", + "top_templates", + "top_catalog_entities", + "top_plugins", + "top_techdocs", + "top_searches", + ]; + + await Promise.all([ + ...types.map((type) => + this.waitUntilApiCallIsMade( + page, + `/api/adoption-insights/events?type=${type}`, + ), + ), + this.waitUntilApiCallSucceeds(page), + ]); + } +} diff --git a/e2e-tests/playwright/support/pages/bulk-import.ts b/e2e-tests/playwright/support/pages/bulk-import.ts index 8de6ffdb5b..593baa2258 100644 --- a/e2e-tests/playwright/support/pages/bulk-import.ts +++ b/e2e-tests/playwright/support/pages/bulk-import.ts @@ -1,6 +1,6 @@ import { Page, expect } from "@playwright/test"; import { APIHelper } from "../../utils/api-helper"; -import { UI_HELPER_ELEMENTS } from "../pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../page-objects/global-obj"; export class BulkImport { private page: Page; @@ -17,9 +17,23 @@ export class BulkImport { } async filterAddedRepo(searchText: string) { - await this.page - .getByPlaceholder("Filter", { exact: true }) - .fill(searchText); + await expect(async () => { + // Clear any existing filter first + await this.page.getByPlaceholder("Filter", { exact: true }).clear(); + + // Fill the filter with search text + await this.page + .getByPlaceholder("Filter", { exact: true }) + .fill(searchText); + + // Wait for the filter to be applied and verify no "no-import-jobs-found" message appears + await expect(this.page.getByTestId("no-import-jobs-found")).toBeHidden({ + timeout: 2000, + }); + }).toPass({ + intervals: [1_000, 2_000, 5_000], + timeout: 20_000, + }); } async newGitHubRepo(owner: string, repoName: string) { diff --git a/e2e-tests/playwright/support/pages/catalog-import.ts b/e2e-tests/playwright/support/pages/catalog-import.ts index dadcc2e621..93c359ae10 100644 --- a/e2e-tests/playwright/support/pages/catalog-import.ts +++ b/e2e-tests/playwright/support/pages/catalog-import.ts @@ -3,7 +3,7 @@ import { UIhelper } from "../../utils/ui-helper"; import { BACKSTAGE_SHOWCASE_COMPONENTS, CATALOG_IMPORT_COMPONENTS, -} from "../pageObjects/page-obj"; +} from "../page-objects/page-obj"; import { APIHelper } from "../../utils/api-helper"; import { GITHUB_API_ENDPOINTS } from "../../utils/api-endpoints"; diff --git a/e2e-tests/playwright/support/pages/extensions.ts b/e2e-tests/playwright/support/pages/extensions.ts index 4314799901..5d7a9fc37a 100644 --- a/e2e-tests/playwright/support/pages/extensions.ts +++ b/e2e-tests/playwright/support/pages/extensions.ts @@ -1,12 +1,37 @@ -import { Page, Locator } from "@playwright/test"; +import { Page, expect, Locator } from "@playwright/test"; +import { UIhelper } from "../../utils/ui-helper"; export class Extensions { private page: Page; public badge: Locator; + private uiHelper: UIhelper; + + private commonHeadings = [ + "Versions", + "Author", + "Tags", + "Category", + "Publisher", + "Support Provider", + ]; + private tableHeaders = [ + "Package name", + "Version", + "Role", + "Backstage compatibility version", + "Status", + ]; constructor(page: Page) { this.page = page; this.badge = this.page.getByTestId("TaskAltIcon"); + this.uiHelper = new UIhelper(page); + } + + async clickReadMoreByPluginTitle(pluginTitle: string) { + const allCards = this.page.locator(".v5-MuiPaper-outlined"); + const targetCard = allCards.filter({ hasText: pluginTitle }); + await targetCard.getByRole("link", { name: "Read more" }).click(); } async selectDropdown(name: string) { @@ -24,6 +49,118 @@ export class Extensions { } async clickAway() { - this.page.locator("#menu- div").first().click(); + await this.page.locator("#menu- div").first().click(); + } + + async selectSupportTypeFilter(supportType: string) { + await this.selectDropdown("Support type"); + await this.toggleOption(supportType); + await this.page.keyboard.press("Escape"); + } + + async resetSupportTypeFilter(supportType: string) { + await this.selectDropdown("Support type"); + await this.toggleOption(supportType); + await this.page.keyboard.press("Escape"); + } + + async verifyMultipleHeadings(headings: string[] = this.commonHeadings) { + for (const heading of headings) { + console.log(`Verifying heading: ${heading}`); + await this.uiHelper.verifyHeading(heading); + } + } + + async waitForSearchResults(searchText: string) { + await expect( + this.page.locator(".v5-MuiPaper-outlined").first(), + ).toContainText(searchText, { timeout: 10000 }); + } + + async verifyPluginDetails({ + pluginName, + badgeLabel, + badgeText, + headings = this.commonHeadings, + includeTable = true, + includeAbout = false, + }: { + pluginName: string; + badgeLabel: string; + badgeText: string; + headings?: string[]; + includeTable?: boolean; + includeAbout?: boolean; + }) { + await this.clickReadMoreByPluginTitle(pluginName); + await expect( + this.page.getByLabel(badgeLabel).getByText(badgeText), + ).toBeVisible(); + + if (includeAbout) { + await this.uiHelper.verifyText("About"); + } + + await this.verifyMultipleHeadings(headings); + + if (includeTable) { + await this.uiHelper.verifyTableHeadingAndRows(this.tableHeaders); + } + + await this.page.getByRole("button", { name: "close" }).click(); + } + + async verifySupportTypeBadge({ + supportType, + pluginName, + badgeLabel, + badgeText, + tooltipText, + searchTerm, + headings = this.commonHeadings, + includeTable = true, + includeAbout = false, + }: { + supportType: string; + pluginName?: string; + badgeLabel: string; + badgeText: string; + tooltipText: string; + searchTerm?: string; + headings?: string[]; + includeTable?: boolean; + includeAbout?: boolean; + }) { + await this.selectSupportTypeFilter(supportType); + + if (searchTerm) { + await this.uiHelper.searchInputPlaceholder(searchTerm); + await this.waitForSearchResults(searchTerm); + } + + if (pluginName) { + await this.verifyPluginDetails({ + pluginName, + badgeLabel, + badgeText, + headings, + includeTable, + includeAbout, + }); + } else { + await expect(this.page.getByLabel(badgeLabel).first()).toBeVisible(); + await expect(this.badge.first()).toBeVisible(); + await this.badge.first().hover(); + await this.uiHelper.verifyTextInTooltip(tooltipText); + } + + await this.resetSupportTypeFilter(supportType); + } + + async verifyKeyValueRowElements(rowTitle: string, rowValue: string) { + const rowLocator = this.page.locator(".v5-MuiTableRow-root"); + await expect(rowLocator.filter({ hasText: rowTitle })).toContainText( + rowValue, + ); } } diff --git a/e2e-tests/playwright/support/pages/home-page.ts b/e2e-tests/playwright/support/pages/home-page.ts index 7b4c057ff4..87fc50a73d 100644 --- a/e2e-tests/playwright/support/pages/home-page.ts +++ b/e2e-tests/playwright/support/pages/home-page.ts @@ -1,7 +1,7 @@ import { HOME_PAGE_COMPONENTS, SEARCH_OBJECTS_COMPONENTS, -} from "../pageObjects/page-obj"; +} from "../page-objects/page-obj"; import { UIhelper } from "../../utils/ui-helper"; import { Page, expect } from "@playwright/test"; @@ -47,8 +47,8 @@ export class HomePage { await itemLocator.waitFor({ state: "visible" }); - const isVisible = await itemLocator.isVisible(); - expect(isVisible).toBeTruthy(); + const isVisible = itemLocator; + await expect(isVisible).toBeVisible(); } async verifyVisitedCardContent(section: string) { diff --git a/e2e-tests/playwright/support/pages/kubernetes.ts b/e2e-tests/playwright/support/pages/kubernetes.ts index 85f4502ee3..61b6ad1950 100644 --- a/e2e-tests/playwright/support/pages/kubernetes.ts +++ b/e2e-tests/playwright/support/pages/kubernetes.ts @@ -1,6 +1,6 @@ import { Page, expect } from "@playwright/test"; import { UIhelper } from "../../utils/ui-helper"; -import { KUBERNETES_COMPONENTS } from "../pageObjects/page-obj"; +import { KUBERNETES_COMPONENTS } from "../page-objects/page-obj"; export class KubernetesPage { private page: Page; @@ -23,7 +23,7 @@ export class KubernetesPage { await this.verifyDeployment(text); const pods = this.page.locator(KUBERNETES_COMPONENTS.statusOk).nth(4); await pods.scrollIntoViewIfNeeded(); - expect(await pods.textContent()).toBe("1 pods"); + await expect(pods).toHaveText("1 pods"); await pods.click(); const pod = this.page.locator("h6").filter({ hasText: text }).first(); diff --git a/e2e-tests/playwright/support/pages/notifications.ts b/e2e-tests/playwright/support/pages/notifications.ts index 9642c298e1..b08948383a 100644 --- a/e2e-tests/playwright/support/pages/notifications.ts +++ b/e2e-tests/playwright/support/pages/notifications.ts @@ -14,14 +14,14 @@ export class NotificationPage { await this.uiHelper.openSidebar("Notifications"); } - async notificationContains(text: string | RegExp, nth = 0) { + async notificationContains(text: string | RegExp) { await this.page.getByLabel(/.*rows/).click(); // always expand the notifications table to show as many notifications as possible await this.page.getByRole("option", { name: "20" }).click(); await expect( this.page.getByTestId("loading-indicator").getByRole("img"), ).toHaveCount(0); - const row = await this.page.locator(`tr`, { hasText: text }).first(); + const row = this.page.locator(`tr`, { hasText: text }).first(); await expect(row).toHaveCount(1); } @@ -72,7 +72,7 @@ export class NotificationPage { ).toHaveCount(0); } - async saveSelected(nth = 1) { + async saveSelected() { await this.page .locator("thead") .getByTitle("Save selected for later") @@ -103,17 +103,17 @@ export class NotificationPage { } async markLastNotificationAsRead() { - const row = await this.page.locator("td:nth-child(3) > div").first(); + const row = this.page.locator("td:nth-child(3) > div").first(); await row.getByRole("button").nth(1).click(); } async markNotificationAsRead(text: string) { - const row = await this.page.locator(`tr:has-text("${text}")`); + const row = this.page.locator(`tr:has-text("${text}")`); await row.getByRole("button").nth(1).click(); } async markLastNotificationAsUnRead() { - const row = await this.page.locator("td:nth-child(3) > div").first(); + const row = this.page.locator("td:nth-child(3) > div").first(); await row.getByRole("button").nth(1).click(); } diff --git a/e2e-tests/playwright/support/pages/orchestrator.ts b/e2e-tests/playwright/support/pages/orchestrator.ts index adc8a70006..96fa385e57 100644 --- a/e2e-tests/playwright/support/pages/orchestrator.ts +++ b/e2e-tests/playwright/support/pages/orchestrator.ts @@ -1,6 +1,6 @@ import { expect, type Page } from "@playwright/test"; import { UIhelper } from "../../utils/ui-helper"; -import Workflows from "./Workflows"; +import Workflows from "./workflows"; export class Orchestrator { private readonly page: Page; @@ -13,7 +13,7 @@ export class Orchestrator { async openWorkflowAlert() { // This is only valid for MILESTONE 2 - const alert = await this.page.getByRole("alert"); + const alert = this.page.getByRole("alert"); await alert.getByRole("button").nth(0).click(); } @@ -32,7 +32,7 @@ export class Orchestrator { } async getPageUrl() { - return await this.page.url(); + return this.page.url(); } async gotoUrl(url = "") { diff --git a/e2e-tests/playwright/support/pages/topology.ts b/e2e-tests/playwright/support/pages/topology.ts index 55aaefc613..8dc32bb45b 100644 --- a/e2e-tests/playwright/support/pages/topology.ts +++ b/e2e-tests/playwright/support/pages/topology.ts @@ -14,7 +14,7 @@ export class Topology { async hoverOnPodStatusIndicator() { const locator = this.page .locator('[data-test-id="topology-test"]') - .getByText("1") + .getByText("1Pod") .first(); await locator.hover(); await this.page.waitForTimeout(1000); @@ -24,7 +24,7 @@ export class Topology { await this.uiHelper.verifyHeading("Missing Permission"); await this.uiHelper.verifyText("kubernetes.clusters.read"); await this.uiHelper.verifyText("kubernetes.resources.read"); - await expect(this.page.getByLabel("Pod")).not.toBeVisible(); + await expect(this.page.getByLabel("Pod")).toBeHidden(); } async verifyDeployment(name: string) { @@ -46,9 +46,12 @@ export class Topology { .click(); if (allowed) { + const downloadLogsButton = this.page.getByRole("button", { + name: "download logs", + }); const fileContent = await downloadAndReadFile( this.page, - 'role=button[name="download logs"]', + downloadLogsButton, ); expect(fileContent).not.toBeUndefined(); expect(fileContent).not.toBe(""); diff --git a/e2e-tests/playwright/support/pages/Workflows.ts b/e2e-tests/playwright/support/pages/workflows.ts similarity index 67% rename from e2e-tests/playwright/support/pages/Workflows.ts rename to e2e-tests/playwright/support/pages/workflows.ts index ef1bd0ec92..2f929d1d83 100644 --- a/e2e-tests/playwright/support/pages/Workflows.ts +++ b/e2e-tests/playwright/support/pages/workflows.ts @@ -1,4 +1,3 @@ -/* eslint-disable @backstage/no-undeclared-imports */ import { Page } from "@playwright/test"; const workflowsTable = (page: Page) => @@ -7,8 +6,8 @@ const workflowsTable = (page: Page) => .filter({ hasText: "WorkflowsNameCategoryLast" }) .nth(2); -const Workflows = { +const WORKFLOWS = { workflowsTable, }; -export default Workflows; +export default WORKFLOWS; diff --git a/e2e-tests/playwright/support/testData/bulk-import.ts b/e2e-tests/playwright/support/test-data/bulk-import.ts similarity index 100% rename from e2e-tests/playwright/support/testData/bulk-import.ts rename to e2e-tests/playwright/support/test-data/bulk-import.ts diff --git a/e2e-tests/playwright/support/testData/custom-theme.ts b/e2e-tests/playwright/support/test-data/custom-theme.ts similarity index 100% rename from e2e-tests/playwright/support/testData/custom-theme.ts rename to e2e-tests/playwright/support/test-data/custom-theme.ts diff --git a/e2e-tests/playwright/support/testData/dynamic-plugins-info.ts b/e2e-tests/playwright/support/test-data/dynamic-plugins-info.ts similarity index 100% rename from e2e-tests/playwright/support/testData/dynamic-plugins-info.ts rename to e2e-tests/playwright/support/test-data/dynamic-plugins-info.ts diff --git a/e2e-tests/playwright/support/testData/resources.ts b/e2e-tests/playwright/support/test-data/resources.ts similarity index 100% rename from e2e-tests/playwright/support/testData/resources.ts rename to e2e-tests/playwright/support/test-data/resources.ts diff --git a/e2e-tests/playwright/support/testData/templates.ts b/e2e-tests/playwright/support/test-data/templates.ts similarity index 100% rename from e2e-tests/playwright/support/testData/templates.ts rename to e2e-tests/playwright/support/test-data/templates.ts diff --git a/e2e-tests/playwright/support/translations/settings/de.ts b/e2e-tests/playwright/support/translations/settings/de.ts new file mode 100644 index 0000000000..0402d2f970 --- /dev/null +++ b/e2e-tests/playwright/support/translations/settings/de.ts @@ -0,0 +1,9 @@ +export const DE = { + sidebar: { + favorites: "Favorites", + docs: "Docs", + }, + settings: { + rhdhLanguage: "Deutsch", + }, +}; diff --git a/e2e-tests/playwright/support/translations/settings/en.ts b/e2e-tests/playwright/support/translations/settings/en.ts new file mode 100644 index 0000000000..538a4e4c21 --- /dev/null +++ b/e2e-tests/playwright/support/translations/settings/en.ts @@ -0,0 +1,9 @@ +export const EN = { + sidebar: { + favorites: "Favorites", + docs: "Docs", + }, + settings: { + rhdhLanguage: "English", + }, +}; diff --git a/e2e-tests/playwright/support/translations/settings/fr.ts b/e2e-tests/playwright/support/translations/settings/fr.ts new file mode 100644 index 0000000000..a259e1273d --- /dev/null +++ b/e2e-tests/playwright/support/translations/settings/fr.ts @@ -0,0 +1,9 @@ +export const FR = { + sidebar: { + favorites: "Favorites", + docs: "Docs", + }, + settings: { + rhdhLanguage: "Français", + }, +}; diff --git a/e2e-tests/playwright/support/translations/settings/index.ts b/e2e-tests/playwright/support/translations/settings/index.ts new file mode 100644 index 0000000000..de6933efc6 --- /dev/null +++ b/e2e-tests/playwright/support/translations/settings/index.ts @@ -0,0 +1,20 @@ +import { EN } from "./en"; +import { FR } from "./fr"; +import { DE } from "./de"; + +const locales = { en: EN, fr: FR, de: DE }; +export type Locale = keyof typeof locales; + +export function getCurrentLanguage(): Locale { + const lang = process.env.LOCALE || "en"; + return lang as Locale; +} + +export function getLocale(lang: Locale = getCurrentLanguage()) { + return locales[lang] || locales.en; +} + +export function getTranslations() { + const lang = getCurrentLanguage(); + return getLocale(lang); +} diff --git a/e2e-tests/playwright/utils/api-helper.ts b/e2e-tests/playwright/utils/api-helper.ts index 45cd279306..0febb9007c 100644 --- a/e2e-tests/playwright/utils/api-helper.ts +++ b/e2e-tests/playwright/utils/api-helper.ts @@ -76,6 +76,46 @@ export class APIHelper { expect(response.status() === 201 || response.ok()).toBeTruthy(); } + static async createGitHubRepoWithFile( + owner: string, + repoName: string, + filename: string, + fileContent: string, + ) { + // Create the repository + await APIHelper.createGitHubRepo(owner, repoName); + + // Add the specified file + await APIHelper.createFileInRepo( + owner, + repoName, + filename, + fileContent, + `Add ${filename} file`, + ); + } + + static async createFileInRepo( + owner: string, + repoName: string, + filePath: string, + content: string, + commitMessage: string, + branch = "main", + ) { + const encodedContent = Buffer.from(content).toString("base64"); + const response = await APIHelper.githubRequest( + "PUT", + `${GITHUB_API_ENDPOINTS.contents(owner, repoName)}/${filePath}`, + { + message: commitMessage, + content: encodedContent, + branch: branch, + }, + ); + expect(response.status() === 201 || response.ok()).toBeTruthy(); + } + static async initCommit(owner: string, repo: string, branch = "main") { const content = Buffer.from( "This is the initial commit for the repository.", diff --git a/e2e-tests/playwright/utils/authentication-providers/msgraph-helper.ts b/e2e-tests/playwright/utils/authentication-providers/msgraph-helper.ts index d49568d860..318a7ec163 100644 --- a/e2e-tests/playwright/utils/authentication-providers/msgraph-helper.ts +++ b/e2e-tests/playwright/utils/authentication-providers/msgraph-helper.ts @@ -3,7 +3,11 @@ import { ClientSecretCredential } from "@azure/identity"; import { Client, PageCollection } from "@microsoft/microsoft-graph-client"; import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials/index.js"; import { User, Group } from "@microsoft/microsoft-graph-types"; -import { NetworkManagementClient } from "@azure/arm-network"; +import { + NetworkManagementClient, + NetworkSecurityGroupsGetResponse, + SecurityRulesGetResponse, +} from "@azure/arm-network"; export class MSClient { private clientSecretCredential: ClientSecretCredential | undefined; @@ -406,7 +410,7 @@ export class MSClient { resourceGroupName: string, nsgName: string, ruleName: string, - ): Promise { + ): Promise { this.ensureArmInitialized(); try { console.log( @@ -455,7 +459,7 @@ export class MSClient { async getNetworkSecurityGroupAsync( resourceGroupName: string, nsgName: string, - ): Promise { + ): Promise { this.ensureArmInitialized(); try { console.log( @@ -526,14 +530,16 @@ export class MSClient { // Step 5: Create new rule with wildcard IP (*) // Find an available priority to avoid conflicts - const existingRules = await this.armNetworkClient?.securityRules.list( + const existingRules = this.armNetworkClient?.securityRules.list( resourceGroupName, nsgName, ); const existingPriorities = new Set(); - for await (const rule of existingRules || []) { - existingPriorities.add(rule.priority); + if (existingRules) { + for await (const rule of existingRules) { + existingPriorities.add(rule.priority); + } } // Find the first available priority starting from 100 diff --git a/e2e-tests/playwright/utils/authentication-providers/rhdh-deployment.ts b/e2e-tests/playwright/utils/authentication-providers/rhdh-deployment.ts index 2938f471e2..9bf7e57c9a 100644 --- a/e2e-tests/playwright/utils/authentication-providers/rhdh-deployment.ts +++ b/e2e-tests/playwright/utils/authentication-providers/rhdh-deployment.ts @@ -689,7 +689,7 @@ class RHDHDeployment { } } catch (error) { // Expected error - connection refused - console.log("Homepage is not accessible as expected"); + console.log("Homepage is not accessible as expected: ", error); } } else { console.log("No running process to kill."); @@ -769,7 +769,7 @@ class RHDHDeployment { }); // Keep the function alive to allow streaming - // eslint-disable-next-line no-constant-condition + while (Date.now() - startTime < timeoutMs && !found) { await new Promise((resolve) => setTimeout(resolve, 1000)); } @@ -1222,7 +1222,7 @@ class RHDHDeployment { async generateStaticToken(): Promise { const token = uuidv4(); - this.addSecretData("STATIC_TOKEN", token); + await this.addSecretData("STATIC_TOKEN", token); this.staticToken = token; return this; } @@ -1330,8 +1330,8 @@ class RHDHDeployment { async checkUserIsIngestedInCatalog(users: string[]) { const api = new APIHelper(); - api.UseStaticToken(this.staticToken); - api.UseBaseUrl(await this.computeBackstageBackendUrl()); + await api.UseStaticToken(this.staticToken); + await api.UseBaseUrl(await this.computeBackstageBackendUrl()); const response = await api.getAllCatalogUsersFromAPI(); const catalogUsers: UserEntity[] = response && response.items ? response.items : []; @@ -1350,8 +1350,8 @@ class RHDHDeployment { async checkGroupIsIngestedInCatalog(groups: string[]) { const api = new APIHelper(); - api.UseStaticToken(this.staticToken); - api.UseBaseUrl(await this.computeBackstageBackendUrl()); + await api.UseStaticToken(this.staticToken); + await api.UseBaseUrl(await this.computeBackstageBackendUrl()); const response = await api.getAllCatalogGroupsFromAPI(); const catalogGroups: GroupEntity[] = response && response.items ? response.items : []; @@ -1370,8 +1370,8 @@ class RHDHDeployment { async checkUserIsInGroup(user: string, group: string): Promise { const api = new APIHelper(); - api.UseStaticToken(this.staticToken); - api.UseBaseUrl(await this.computeBackstageBackendUrl()); + await api.UseStaticToken(this.staticToken); + await api.UseBaseUrl(await this.computeBackstageBackendUrl()); const groupEntity: GroupEntity = await api.getGroupEntityFromAPI(group); const members = this.parseGroupMemberFromEntity(groupEntity); console.log( @@ -1385,8 +1385,8 @@ class RHDHDeployment { child: string, ): Promise { const api = new APIHelper(); - api.UseStaticToken(this.staticToken); - api.UseBaseUrl(await this.computeBackstageBackendUrl()); + await api.UseStaticToken(this.staticToken); + await api.UseBaseUrl(await this.computeBackstageBackendUrl()); const groupEntity: GroupEntity = await api.getGroupEntityFromAPI(parent); const children = this.parseGroupChildrenFromEntity(groupEntity); console.log( @@ -1400,8 +1400,8 @@ class RHDHDeployment { parent: string, ): Promise { const api = new APIHelper(); - api.UseStaticToken(this.staticToken); - api.UseBaseUrl(await this.computeBackstageBackendUrl()); + await api.UseStaticToken(this.staticToken); + await api.UseBaseUrl(await this.computeBackstageBackendUrl()); const groupEntity: GroupEntity = await api.getGroupEntityFromAPI(child); const parents = this.parseGroupParentFromEntity(groupEntity); console.log( diff --git a/e2e-tests/playwright/utils/common.ts b/e2e-tests/playwright/utils/common.ts index da7ff395ce..8b20bafdc5 100644 --- a/e2e-tests/playwright/utils/common.ts +++ b/e2e-tests/playwright/utils/common.ts @@ -1,10 +1,10 @@ import { UIhelper } from "./ui-helper"; import { authenticator } from "otplib"; import { test, Browser, expect, Page, TestInfo } from "@playwright/test"; -import { SETTINGS_PAGE_COMPONENTS } from "../support/pageObjects/page-obj"; -import { WAIT_OBJECTS } from "../support/pageObjects/global-obj"; -import path from "path"; -import fs from "fs"; +import { SETTINGS_PAGE_COMPONENTS } from "../support/page-objects/page-obj"; +import { WAIT_OBJECTS } from "../support/page-objects/global-obj"; +import * as path from "path"; +import * as fs from "fs"; export class Common { page: Page; @@ -161,6 +161,7 @@ export class Common { .first(); await popup.waitForTimeout(3000); await locator.waitFor({ state: "visible" }); + // eslint-disable-next-line playwright/no-force-option await locator.click({ force: true }); await popup.waitForTimeout(3000); @@ -289,7 +290,10 @@ export class Common { } await popup.locator("#password").click({ timeout: 5000 }); await popup.locator("#password").fill(password, { timeout: 5000 }); - await popup.locator("[type='submit']").click({ timeout: 5000 }); + await popup + .locator("[type='submit'][value='Sign in']:not(webauthn-status *)") + .first() + .click({ timeout: 5000 }); const twofactorcode = authenticator.generate(twofactor); await popup.locator("#app_totp").click({ timeout: 5000 }); await popup.locator("#app_totp").fill(twofactorcode, { timeout: 5000 }); @@ -299,7 +303,7 @@ export class Common { } catch (e) { const authorization = popup.locator("button.js-oauth-authorize-btn"); if (await authorization.isVisible()) { - authorization.click(); + await authorization.click(); return "Login successful"; } else { throw e; diff --git a/e2e-tests/playwright/utils/custom-theme/theme-verifier.ts b/e2e-tests/playwright/utils/custom-theme/theme-verifier.ts index 2b4a0f4146..6a412e79ac 100644 --- a/e2e-tests/playwright/utils/custom-theme/theme-verifier.ts +++ b/e2e-tests/playwright/utils/custom-theme/theme-verifier.ts @@ -1,6 +1,6 @@ import { Page, expect, TestInfo } from "@playwright/test"; import { UIhelper } from "../ui-helper"; -import { UI_HELPER_ELEMENTS } from "../../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../../support/page-objects/global-obj"; export class ThemeVerifier { private readonly page: Page; @@ -12,19 +12,29 @@ export class ThemeVerifier { } async setTheme(theme: "Light" | "Dark" | "Light Dynamic" | "Dark Dynamic") { - await this.uiHelper.goToSettingsPage(); + await this.uiHelper.goToPageUrl("/settings", "Settings"); await this.uiHelper.clickBtnByTitleIfNotPressed(`Select theme ${theme}`); + const themeButton = this.page.getByRole("button", { + name: theme, + exact: true, + }); + + // TODO: https://issues.redhat.com/browse/RHDHBUGS-2076 navigating back to settings page is needed until the issue is resolved + await this.uiHelper.goToPageUrl("/settings", "Settings"); + + await expect(themeButton).toHaveAttribute("aria-pressed", "true"); } async verifyHeaderGradient(expectedGradient: string) { - const header = await this.page.locator("main header"); + const header = this.page.locator("main header").first(); + await expect(header).toBeVisible(); await expect(header).toHaveCSS("background-image", expectedGradient); } async verifyBorderLeftColor(expectedColor: string) { await this.uiHelper.openSidebar("Home"); - const locator = await this.page.locator("a").filter({ hasText: "Home" }); - await expect(locator).toHaveCSS( + const homeLinkLocator = this.page.locator("a").filter({ hasText: "Home" }); + await expect(homeLinkLocator).toHaveCSS( "border-left", `3px solid ${expectedColor}`, ); @@ -47,7 +57,6 @@ export class ThemeVerifier { UI_HELPER_ELEMENTS.MuiButtonTextPrimary, colorPrimary, ); - await this.uiHelper.goToSettingsPage(); } async takeScreenshotAndAttach( diff --git a/e2e-tests/playwright/utils/helper.ts b/e2e-tests/playwright/utils/helper.ts index bb9191cbf0..5ed8824dc3 100644 --- a/e2e-tests/playwright/utils/helper.ts +++ b/e2e-tests/playwright/utils/helper.ts @@ -1,13 +1,13 @@ -import { type Page } from "@playwright/test"; +import { type Page, type Locator } from "@playwright/test"; import fs from "fs"; export async function downloadAndReadFile( page: Page, - locator: string, + locator: Locator, ): Promise { const [download] = await Promise.all([ page.waitForEvent("download"), - page.locator(locator).click(), + locator.click(), ]); const filePath = await download.path(); diff --git a/e2e-tests/playwright/utils/keycloak/keycloak.ts b/e2e-tests/playwright/utils/keycloak/keycloak.ts index 87934ce746..b96bf5a067 100644 --- a/e2e-tests/playwright/utils/keycloak/keycloak.ts +++ b/e2e-tests/playwright/utils/keycloak/keycloak.ts @@ -3,7 +3,7 @@ import User from "./user"; import Group from "./group"; import { expect, Page } from "@playwright/test"; import { UIhelper } from "../ui-helper"; -import { CatalogUsersPO } from "../../support/pageObjects/catalog/catalog-users-obj"; +import { CatalogUsersPO } from "../../support/page-objects/catalog/catalog-users-obj"; interface AuthResponse { access_token: string; @@ -15,15 +15,27 @@ class Keycloak { private readonly clientSecret: string; constructor() { - this.baseURL = process.env.KEYCLOAK_BASE_URL; - this.realm = process.env.KEYCLOAK_REALM; - this.clientSecret = process.env.KEYCLOAK_CLIENT_SECRET; - this.clientId = process.env.KEYCLOAK_CLIENT_ID; + this.baseURL = Buffer.from( + process.env.KEYCLOAK_AUTH_BASE_URL, + "base64", + ).toString(); + this.realm = Buffer.from( + process.env.KEYCLOAK_AUTH_REALM, + "base64", + ).toString(); + this.clientSecret = Buffer.from( + process.env.KEYCLOAK_AUTH_CLIENT_SECRET, + "base64", + ).toString(); + this.clientId = Buffer.from( + process.env.KEYCLOAK_AUTH_CLIENTID, + "base64", + ).toString(); } async getAuthenticationToken(): Promise { const response = await fetch( - `${this.baseURL}/realms/${this.realm}/protocol/openid-connect/token`, + `${this.baseURL}/auth/realms/${this.realm}/protocol/openid-connect/token`, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, @@ -42,7 +54,7 @@ class Keycloak { async getUsers(authToken: string): Promise { const response = await fetch( - `${this.baseURL}/admin/realms/${this.realm}/users`, + `${this.baseURL}/auth/admin/realms/${this.realm}/users`, { method: "GET", headers: { @@ -51,13 +63,16 @@ class Keycloak { }, ); - if (response.status !== 200) throw new Error("Failed to get users"); - return response.json() as Promise; + if (response.status !== 200) { + const errorText = await response.text(); + throw new Error(`Failed to get users: ${response.status} - ${errorText}`); + } + return (await response.json()) as Promise; } async getGroupsOfUser(authToken: string, userId: string): Promise { const response = await fetch( - `${this.baseURL}/admin/realms/${this.realm}/users/${userId}/groups`, + `${this.baseURL}/auth/admin/realms/${this.realm}/users/${userId}/groups`, { method: "GET", headers: { @@ -66,9 +81,13 @@ class Keycloak { }, ); - if (response.status !== 200) - throw new Error("Failed to get groups of user"); - return response.json() as Promise; + if (response.status !== 200) { + const errorText = await response.text(); + throw new Error( + `Failed to get groups of user: ${response.status} - ${errorText}`, + ); + } + return (await response.json()) as Promise; } async checkUserDetails( diff --git a/e2e-tests/playwright/utils/kube-client.ts b/e2e-tests/playwright/utils/kube-client.ts index 9553d80085..ff24883ce1 100644 --- a/e2e-tests/playwright/utils/kube-client.ts +++ b/e2e-tests/playwright/utils/kube-client.ts @@ -5,7 +5,6 @@ import * as yaml from "js-yaml"; export class KubeClient { coreV1Api: k8s.CoreV1Api; appsApi: k8s.AppsV1Api; - k8sCustomAPI: k8s.CustomObjectsApi; kc: k8s.KubeConfig; constructor() { @@ -37,7 +36,6 @@ export class KubeClient { this.appsApi = this.kc.makeApiClient(k8s.AppsV1Api); this.coreV1Api = this.kc.makeApiClient(k8s.CoreV1Api); - this.k8sCustomAPI = this.kc.makeApiClient(k8s.CustomObjectsApi); } catch (e) { console.log(e); throw e; @@ -351,7 +349,7 @@ export class KubeClient { console.log(`Namespace '${namespace}' deletion initiated.`); await new Promise((resolve, reject) => { - watch.watch( + void watch.watch( `/api/v1/namespaces?watch=true&fieldSelector=metadata.name=${namespace}`, {}, (type) => { @@ -570,56 +568,6 @@ export class KubeClient { } } - async createRoute(namespace: string, body: k8s.KubernetesObject) { - try { - const response = await this.k8sCustomAPI.createNamespacedCustomObject( - "route.openshift.io", - "v1", - namespace, - "routes", - body, - ); - return response.body; - } catch (error) { - console.error("Error creating Route:", error); - throw error; - } - } - - async deleteRoute(namespace: string, name: string) { - try { - const response = await this.k8sCustomAPI.deleteNamespacedCustomObject( - "route.openshift.io", - "v1", - namespace, - "routes", - name, - ); - return response.body; - } catch (error) { - console.error("Error deleting Route:", error); - throw error; - } - } - - async getRoute(namespace, routeName) { - try { - const response = await this.k8sCustomAPI.getNamespacedCustomObject( - "route.openshift.io", - "v1", - namespace, - "routes", - routeName, - ); - return response.body; - } catch (error) { - if (error.statusCode === 404) { - return null; - } - throw error; - } - } - async getServiceByLabel( namespace: string, labelSelector: string, diff --git a/e2e-tests/playwright/utils/quay/quay.ts b/e2e-tests/playwright/utils/quay/quay.ts index c5f187c352..fb7dd34227 100644 --- a/e2e-tests/playwright/utils/quay/quay.ts +++ b/e2e-tests/playwright/utils/quay/quay.ts @@ -1,5 +1,5 @@ import { Page } from "@playwright/test"; -import { UI_HELPER_ELEMENTS } from "../../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../../support/page-objects/global-obj"; export class ImageRegistry { static getAllCellsIdentifier() { diff --git a/e2e-tests/playwright/utils/scorecard-response-utils.ts b/e2e-tests/playwright/utils/scorecard-response-utils.ts new file mode 100644 index 0000000000..b423441a5e --- /dev/null +++ b/e2e-tests/playwright/utils/scorecard-response-utils.ts @@ -0,0 +1,203 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export const CUSTOM_SCORECARD_RESPONSE = [ + { + id: "github.open-prs", + status: "success", + metadata: { + title: "Github open PRs", + description: + "Current count of open Pull Requests for a given GitHub repository.", + type: "number", + history: true, + }, + result: { + value: 9, + timestamp: "2025-09-08T09:08:55.629Z", + thresholdResult: { + definition: { + rules: [ + { key: "error", expression: ">=200" }, + { key: "warning", expression: "10-200" }, + { key: "success", expression: "<10" }, + ], + }, + status: "success", + evaluation: "success", + }, + }, + }, + { + id: "jira.open-issues", + status: "success", + metadata: { + title: "Jira open blocking tickets", + description: + "Highlights the number of critical, blocking issues that are currently open in Jira.", + type: "number", + history: true, + }, + result: { + value: 8, + timestamp: "2025-09-08T09:08:55.629Z", + thresholdResult: { + definition: { + rules: [ + { key: "error", expression: ">=50" }, + { key: "warning", expression: "10-50" }, + { key: "success", expression: "<10" }, + ], + }, + status: "success", + evaluation: "success", + }, + }, + }, +]; + +export const EMPTY_SCORECARD_RESPONSE = []; + +export const UNAVAILABLE_METRIC_RESPONSE = [ + { + id: "jira.open-issues", + status: "success", + metadata: { + title: "Jira open blocking tickets", + description: + "Highlights the number of critical, blocking issues that are currently open in Jira.", + type: "number", + history: true, + }, + result: { + value: 54, + timestamp: "2025-09-12T15:28:56.898Z", + thresholdResult: { + definition: { + rules: [ + { + key: "error", + expression: ">50", + }, + { + key: "warning", + expression: "10-50", + }, + { + key: "success", + expression: "<10", + }, + ], + }, + status: "success", + evaluation: "error", + }, + }, + }, + { + id: "github.open-prs", + status: "error", + metadata: { + title: "Github open PRs", + description: + "Current count of open Pull Requests for a given GitHub repository.", + type: "number", + history: true, + }, + error: + "HttpError: API rate limit exceeded for 157.50.94.55. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.) - https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting", + result: { + timestamp: "2025-09-23T12:17:02.496Z", + thresholdResult: { + definition: { + rules: [ + { + key: "success", + expression: "<10", + }, + { + key: "warning", + expression: "10-50", + }, + { + key: "error", + expression: ">50", + }, + ], + }, + status: "error", + error: "Unable to evaluate thresholds, metric value is missing", + }, + }, + }, +]; + +export const INVALID_THRESHOLD_RESPONSE = [ + { + id: "jira.open-issues", + status: "success", + metadata: { + title: "Jira open blocking tickets", + description: + "Highlights the number of critical, blocking issues that are currently open in Jira.", + type: "number", + history: true, + }, + result: { + value: 54, + timestamp: "2025-09-12T15:28:56.898Z", + thresholdResult: { + definition: { + rules: [ + { + key: "error", + expression: ">50", + }, + { + key: "warning", + expression: "10-50", + }, + { + key: "success", + expression: "<10", + }, + ], + }, + status: "success", + evaluation: "error", + }, + }, + }, + { + id: "github.open-prs", + status: "success", + metadata: { + title: "Github open PRs", + description: + "Current count of open Pull Requests for a given GitHub repository.", + type: "number", + history: true, + }, + result: { + value: 40, + timestamp: "2025-09-23T12:27:04.531Z", + thresholdResult: { + status: "error", + error: + "ThresholdConfigFormatError: Invalid threshold annotation 'scorecard.io/github.open-prs.thresholds.rules.warning: 10--15' in entity 'component:default/all-scorecards-service': Invalid threshold expression: \"10--15\".", + }, + }, + }, +]; diff --git a/e2e-tests/playwright/utils/scorecard-utils.ts b/e2e-tests/playwright/utils/scorecard-utils.ts new file mode 100644 index 0000000000..939423ae3b --- /dev/null +++ b/e2e-tests/playwright/utils/scorecard-utils.ts @@ -0,0 +1,49 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Page, expect } from "@playwright/test"; + +export async function waitUntilApiCallSucceeds( + page: Page, + urlPart: string = "/api/scorecard/metrics/catalog/Component/default/rhdh-app", +): Promise { + const response = await page.waitForResponse( + async (res) => { + const urlMatches = res.url().includes(urlPart); + const isSuccess = res.status() === 200; + return urlMatches && isSuccess; + }, + { timeout: 60000 }, + ); + + expect(response.status()).toBe(200); +} + +const scorecardApiRoute = + "**/api/scorecard/metrics/catalog/Component/default/rhdh-app"; + +export async function mockScorecardResponse( + page: Page, + responseData: object, + status = 200, +) { + await page.route(scorecardApiRoute, async (route) => { + await route.fulfill({ + status, + contentType: "application/json", + body: JSON.stringify(responseData), + }); + }); +} diff --git a/e2e-tests/playwright/utils/ui-helper.ts b/e2e-tests/playwright/utils/ui-helper.ts index 1db0085445..1a676ba6d0 100644 --- a/e2e-tests/playwright/utils/ui-helper.ts +++ b/e2e-tests/playwright/utils/ui-helper.ts @@ -1,7 +1,7 @@ import { expect, Locator, Page } from "@playwright/test"; -import { UI_HELPER_ELEMENTS } from "../support/pageObjects/global-obj"; +import { UI_HELPER_ELEMENTS } from "../support/page-objects/global-obj"; import { SidebarTabs } from "./navbar"; -import { SEARCH_OBJECTS_COMPONENTS } from "../support/pageObjects/page-obj"; +import { SEARCH_OBJECTS_COMPONENTS } from "../support/page-objects/page-obj"; export class UIhelper { private page: Page; @@ -65,6 +65,7 @@ export class UIhelper { .first(); if (options?.force) { + // eslint-disable-next-line playwright/no-force-option await button.click({ force: true }); } else { await button.click(); @@ -126,12 +127,17 @@ export class UIhelper { }); if (options.force) { + // eslint-disable-next-line playwright/no-force-option await buttonElement.click({ force: true }); } else { await buttonElement.click(); } } + async clickButtonByLabel(label: string | RegExp) { + await this.page.getByRole("button", { name: label }).first().click(); + } + /** * Conditionally clicks on "Mark all read" if visible, then clicks on "Mark All". * This method handles the two-step process of marking all notifications as read. @@ -153,7 +159,8 @@ export class UIhelper { } } catch (error) { console.log( - "Mark all read functionality not available or already processed", + "Mark all read functionality not available or already processed: ", + error, ); } } @@ -179,7 +186,10 @@ export class UIhelper { } return false; } catch (error) { - console.log(`Element with title "${title}" not found or not clickable`); + console.log( + `Element with title "${title}" not found or not clickable: `, + error, + ); return false; } } @@ -194,7 +204,7 @@ export class UIhelper { if (typeof options === "string") { linkLocator = this.page.locator("a").filter({ hasText: options }).first(); } else if ("href" in options) { - linkLocator = this.page.locator(`a[href="${options.href}"]`); + linkLocator = this.page.locator(`a[href="${options.href}"]`).first(); } else { linkLocator = this.page .locator(`div[aria-label='${options.ariaLabel}'] a`) @@ -213,10 +223,12 @@ export class UIhelper { .click(); } - async goToSettingsPage() { - await expect(this.page.locator("nav[id='global-header']")).toBeVisible(); - await this.openProfileDropdown(); - await this.clickLink({ href: "/settings" }); + async goToPageUrl(url: string, heading?: string) { + await this.page.goto(url); + await expect(this.page).toHaveURL(url); + if (heading) { + await this.verifyHeading(heading); + } } async goToMyProfilePage() { @@ -251,7 +263,7 @@ export class UIhelper { } if (notVisibleCheck) { - await expect(linkLocator).not.toBeVisible(); + await expect(linkLocator).toBeHidden(); } else { await expect(linkLocator).toBeVisible(); } @@ -290,9 +302,14 @@ export class UIhelper { return await this.isElementVisible(locator, timeout); } - async isLinkVisible(text: string): Promise { - const locator = `a:has-text("${text}")`; - return await this.isElementVisible(locator); + async verifyTextVisible(text: string, timeout = 10000): Promise { + const locator = this.page.getByText(text); + await expect(locator).toBeVisible({ timeout }); + } + + async verifyLinkVisible(text: string, timeout = 10000): Promise { + const locator = this.page.locator(`a:has-text("${text}")`); + await expect(locator).toBeVisible({ timeout }); } async waitForSideBarVisible() { @@ -303,7 +320,7 @@ export class UIhelper { const navLink = this.page .locator(`nav a:has-text("${navBarText}")`) .first(); - await navLink.waitFor({ state: "visible" }); + await navLink.waitFor({ state: "visible", timeout: 15_000 }); await navLink.dispatchEvent("click"); } @@ -407,7 +424,7 @@ export class UIhelper { async verifyPartialTextInSelector(selector: string, partialText: string) { try { - const elements = await this.page.locator(selector); + const elements = this.page.locator(selector); const count = await elements.count(); for (let i = 0; i < count; i++) { @@ -502,7 +519,7 @@ export class UIhelper { } async waitForLoginBtnDisappear() { - await this.page.waitForSelector(await this.getLoginBtnSelector(), { + await this.page.waitForSelector(this.getLoginBtnSelector(), { state: "detached", }); } @@ -510,21 +527,22 @@ export class UIhelper { async verifyButtonURL( label: string | RegExp, url: string | RegExp, - options: { locator?: string } = { + options: { locator?: string; exact?: boolean } = { locator: "", + exact: true, }, ) { - const buttonUrl = - options.locator == "" - ? await this.page - .getByRole("button", { name: label }) - .first() - .getAttribute("href") - : await this.page - .locator(options.locator) - .getByRole("button", { name: label }) - .first() - .getAttribute("href"); + // To verify the button URL if it is in a specific locator + const baseLocator = + !options.locator || options.locator === "" + ? this.page + : this.page.locator(options.locator); + + const buttonUrl = await baseLocator + .getByRole("button", { name: label, exact: options.exact }) + .first() + .getAttribute("href"); + expect(buttonUrl).toContain(url); } @@ -654,7 +672,7 @@ export class UIhelper { } async checkCssColor(page: Page, selector: string, expectedColor: string) { - const elements = await page.locator(selector); + const elements = page.locator(selector); const count = await elements.count(); const expectedRgbColor = this.toRgb(expectedColor); @@ -714,38 +732,34 @@ export class UIhelper { await this.page.locator(`button[title="Schedule entity refresh"]`).click(); await this.verifyAlertErrorMessage("Refresh scheduled"); - const moreButton = await this.page - .locator("button[aria-label='more']") - .first(); + const moreButton = this.page.locator("button[aria-label='more']").first(); await moreButton.waitFor({ state: "visible", timeout: 4000 }); await moreButton.waitFor({ state: "attached", timeout: 4000 }); await moreButton.click(); - const unregisterItem = await this.page + const unregisterItem = this.page .locator("li[role='menuitem']") .filter({ hasText: "Unregister entity" }) .first(); await unregisterItem.waitFor({ state: "visible", timeout: 4000 }); await unregisterItem.waitFor({ state: "attached", timeout: 4000 }); - expect(unregisterItem).not.toBeDisabled(); + await expect(unregisterItem).toBeEnabled(); } async clickUnregisterButtonForDisplayedEntity() { - const moreButton = await this.page - .locator("button[aria-label='more']") - .first(); + const moreButton = this.page.locator("button[aria-label='more']").first(); await moreButton.waitFor({ state: "visible" }); await moreButton.waitFor({ state: "attached" }); await moreButton.click(); - const unregisterItem = await this.page + const unregisterItem = this.page .locator("li[role='menuitem']") .filter({ hasText: "Unregister entity" }) .first(); await unregisterItem.waitFor({ state: "visible" }); await unregisterItem.click(); - const deleteButton = await this.page.getByRole("button", { + const deleteButton = this.page.getByRole("button", { name: "Delete Entity", }); await deleteButton.waitFor({ state: "visible" }); diff --git a/e2e-tests/scripts/openshiftci-showcase-e2e-test.sh b/e2e-tests/scripts/openshiftci-showcase-e2e-test.sh deleted file mode 100755 index 89940dc878..0000000000 --- a/e2e-tests/scripts/openshiftci-showcase-e2e-test.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# fail if some commands fails -set -e -# show commands -set -x -echo "Place holder to run showcase-e2e test" diff --git a/e2e-tests/yarn.lock b/e2e-tests/yarn.lock index 2246b0e8d3..b147b20ae1 100644 --- a/e2e-tests/yarn.lock +++ b/e2e-tests/yarn.lock @@ -51,7 +51,7 @@ __metadata: languageName: node linkType: hard -"@azure/arm-network@npm:^34.0.0": +"@azure/arm-network@npm:34.0.0": version: 34.0.0 resolution: "@azure/arm-network@npm:34.0.0" dependencies: @@ -451,7 +451,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": +"@eslint-community/eslint-utils@npm:^4.2.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" dependencies: @@ -462,45 +462,106 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/eslint-utils@npm:^4.7.0": + version: 4.7.0 + resolution: "@eslint-community/eslint-utils@npm:4.7.0" + dependencies: + eslint-visitor-keys: ^3.4.3 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: b177e3b75c0b8d0e5d71f1c532edb7e40b31313db61f0c879f9bf19c3abb2783c6c372b5deb2396dab4432f2946b9972122ac682e77010376c029dfd0149c681 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 0d628680e204bc316d545b4993d3658427ca404ae646ce541fcc65306b8c712c340e5e573e30fb9f85f4855c0c5f6dca9868931f2fcced06417fbe1a0c6cd2d6 languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" +"@eslint/config-array@npm:^0.21.0": + version: 0.21.0 + resolution: "@eslint/config-array@npm:0.21.0" + dependencies: + "@eslint/object-schema": ^2.1.6 + debug: ^4.3.1 + minimatch: ^3.1.2 + checksum: 84d3ae7cb755af94dc158a74389f4c560757b13f2bb908f598f927b87b70a38e8152015ea2e9557c1b4afc5130ee1356f6cad682050d67aae0468bbef98bc3a8 + languageName: node + linkType: hard + +"@eslint/config-helpers@npm:^0.3.1": + version: 0.3.1 + resolution: "@eslint/config-helpers@npm:0.3.1" + checksum: b95c239264078a430761afb344402d517134289a7d8b69a6ff1378ebe5eec9da6ad22b5e6d193b9e02899aeda30817ac47178d5927247092cc6d73a52f8d07c9 + languageName: node + linkType: hard + +"@eslint/core@npm:^0.15.2": + version: 0.15.2 + resolution: "@eslint/core@npm:0.15.2" + dependencies: + "@types/json-schema": ^7.0.15 + checksum: 535fc4e657760851826ceae325a72dde664b99189bd975715de3526db655c66d7a35b72dbb1c7641ab9201ed4e2130f79c5be51f96c820b5407c3766dcf94f23 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^3.3.1": + version: 3.3.1 + resolution: "@eslint/eslintrc@npm:3.3.1" dependencies: ajv: ^6.12.4 debug: ^4.3.2 - espree: ^9.6.0 - globals: ^13.19.0 + espree: ^10.0.1 + globals: ^14.0.0 ignore: ^5.2.0 import-fresh: ^3.2.1 js-yaml: ^4.1.0 minimatch: ^3.1.2 strip-json-comments: ^3.1.1 - checksum: 10957c7592b20ca0089262d8c2a8accbad14b4f6507e35416c32ee6b4dbf9cad67dfb77096bbd405405e9ada2b107f3797fe94362e1c55e0b09d6e90dd149127 + checksum: 8241f998f0857abf5a615072273b90b1244d75c1c45d217c6a8eb444c6e12bbb5506b4879c14fb262eb72b7d8e3d2f0542da2db1a7f414a12496ebb790fb4d62 languageName: node linkType: hard -"@eslint/js@npm:8.57.1": - version: 8.57.1 - resolution: "@eslint/js@npm:8.57.1" - checksum: 2afb77454c06e8316793d2e8e79a0154854d35e6782a1217da274ca60b5044d2c69d6091155234ed0551a1e408f86f09dd4ece02752c59568fa403e60611e880 +"@eslint/js@npm:9.34.0, @eslint/js@npm:^9.34.0": + version: 9.34.0 + resolution: "@eslint/js@npm:9.34.0" + checksum: 933d4ba321b1abc83eecde40eb703871ce00f133eedec54cf928b7fedb61706174dd526997c3f151776922412e3d95cb3634f97ef7b5861b4908f9992f403a63 languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.13.0": - version: 0.13.0 - resolution: "@humanwhocodes/config-array@npm:0.13.0" +"@eslint/object-schema@npm:^2.1.6": + version: 2.1.6 + resolution: "@eslint/object-schema@npm:2.1.6" + checksum: e32e565319f6544d36d3fa69a3e163120722d12d666d1a4525c9a6f02e9b54c29d9b1f03139e25d7e759e08dda8da433590bc23c09db8d511162157ef1b86a4c + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.3.5": + version: 0.3.5 + resolution: "@eslint/plugin-kit@npm:0.3.5" dependencies: - "@humanwhocodes/object-schema": ^2.0.3 - debug: ^4.3.1 - minimatch: ^3.0.5 - checksum: eae69ff9134025dd2924f0b430eb324981494be26f0fddd267a33c28711c4db643242cf9fddf7dadb9d16c96b54b2d2c073e60a56477df86e0173149313bd5d6 + "@eslint/core": ^0.15.2 + levn: ^0.4.1 + checksum: 1808d7e2538335b8e4536ef372840e93468ecc6f4a5bf72ad665795290b6a8a72f51ef4ffd8bcfc601b133a5d5f67b59ab256d945f8c825c5c307aad29efaf86 + languageName: node + linkType: hard + +"@humanfs/core@npm:^0.19.1": + version: 0.19.1 + resolution: "@humanfs/core@npm:0.19.1" + checksum: 611e0545146f55ddfdd5c20239cfb7911f9d0e28258787c4fc1a1f6214250830c9367aaaeace0096ed90b6739bee1e9c52ad5ba8adaf74ab8b449119303babfe + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.6 + resolution: "@humanfs/node@npm:0.16.6" + dependencies: + "@humanfs/core": ^0.19.1 + "@humanwhocodes/retry": ^0.3.0 + checksum: f9cb52bb235f8b9c6fcff43a7e500669a38f8d6ce26593404a9b56365a1644e0ed60c720dc65ff6a696b1f85f3563ab055bb554ec8674f2559085ba840e47710 languageName: node linkType: hard @@ -511,17 +572,24 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.3": - version: 2.0.3 - resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: d3b78f6c5831888c6ecc899df0d03bcc25d46f3ad26a11d7ea52944dc36a35ef543fad965322174238d677a43d5c694434f6607532cff7077062513ad7022631 +"@humanwhocodes/retry@npm:^0.3.0": + version: 0.3.1 + resolution: "@humanwhocodes/retry@npm:0.3.1" + checksum: 7e5517bb51dbea3e02ab6cacef59a8f4b0ca023fc4b0b8cbc40de0ad29f46edd50b897c6e7fba79366a0217e3f48e2da8975056f6c35cfe19d9cc48f1d03c1dd languageName: node linkType: hard -"@ioredis/commands@npm:^1.1.1": - version: 1.2.0 - resolution: "@ioredis/commands@npm:1.2.0" - checksum: 9b20225ba36ef3e5caf69b3c0720597c3016cc9b1e157f519ea388f621dd9037177f84cfe7e25c4c32dad7dd90c70ff9123cd411f747e053cf292193c9c461e2 +"@humanwhocodes/retry@npm:^0.4.2": + version: 0.4.3 + resolution: "@humanwhocodes/retry@npm:0.4.3" + checksum: d423455b9d53cf01f778603404512a4246fb19b83e74fe3e28c70d9a80e9d4ae147d2411628907ca983e91a855a52535859a8bb218050bc3f6dbd7a553b7b442 + languageName: node + linkType: hard + +"@ioredis/commands@npm:1.4.0": + version: 1.4.0 + resolution: "@ioredis/commands@npm:1.4.0" + checksum: c2fca9809f4a5508e9c23cd837fb575c0a6b04351643da08f6b66b3b72a6a89ad183dd2da216add28ea5d5b9141925a3c3e4fff74103225a59f70264da50e5f2 languageName: node linkType: hard @@ -568,6 +636,17 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": ^1.2.1 + "@jridgewell/sourcemap-codec": ^1.4.10 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 + languageName: node + linkType: hard + "@jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.8 resolution: "@jridgewell/gen-mapping@npm:0.3.8" @@ -680,10 +759,10 @@ __metadata: languageName: node linkType: hard -"@microsoft/microsoft-graph-types@npm:2.40.0": - version: 2.40.0 - resolution: "@microsoft/microsoft-graph-types@npm:2.40.0" - checksum: 3892e910baf4fcf2d1bcee4c71683e3707818be6ff1b4b9dbc29b9e2eab942ea0b171b3023d4620213f10d93d03611e6615706a3d1af4ca44028491a0544ccaf +"@microsoft/microsoft-graph-types@npm:2.43.1": + version: 2.43.1 + resolution: "@microsoft/microsoft-graph-types@npm:2.43.1" + checksum: 07e4b03ff48f0dcce763227a3a764aac8f3620e45a52c72e57e7583c6ebe47a2374cdb51b9d215fe72b5f5341e9f3ddd93c5712bb5c0202457f516ba7a32365e languageName: node linkType: hard @@ -704,7 +783,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:^1.2.3": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -1085,14 +1164,14 @@ __metadata: languageName: node linkType: hard -"@playwright/test@npm:1.53.2": - version: 1.53.2 - resolution: "@playwright/test@npm:1.53.2" +"@playwright/test@npm:1.56.0": + version: 1.56.0 + resolution: "@playwright/test@npm:1.56.0" dependencies: - playwright: 1.53.2 + playwright: 1.56.0 bin: playwright: cli.js - checksum: b13cb56e60132ad1b0cfa245a89b203623c43287251e359e164380e6fd3a439435133ece52c6242bc925c96cc7afd15b52e596fd2e20f7c87b95d574a157da15 + checksum: 66e7470d1e015a778e7fa3e88d027f095f07fc57fe00ef5ce3a1c17b7f99a5c85aa13dd3a62734b57849d0558a33103828bfcf5a110e092cff6100d086e35aa0 languageName: node linkType: hard @@ -1103,7 +1182,14 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.12": +"@types/estree@npm:^1.0.6": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: bd93e2e415b6f182ec4da1074e1f36c480f1d26add3e696d54fb30c09bc470897e41361c8fd957bf0985024f8fbf1e6e2aff977d79352ef7eb93a5c6dcff6c11 + languageName: node + linkType: hard + +"@types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 @@ -1119,13 +1205,6 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.5.0": - version: 7.5.8 - resolution: "@types/semver@npm:7.5.8" - checksum: ea6f5276f5b84c55921785a3a27a3cd37afee0111dfe2bcb3e03c31819c197c782598f17f0b150a69d453c9584cd14c4c4d7b9a55d2c5e6cacd4d66fdb3b3663 - languageName: node - linkType: hard - "@types/triple-beam@npm:^1.3.2": version: 1.3.5 resolution: "@types/triple-beam@npm:1.3.5" @@ -1133,126 +1212,277 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.21.0" +"@typescript-eslint/eslint-plugin@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.41.0" dependencies: - "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.21.0 - "@typescript-eslint/type-utils": 6.21.0 - "@typescript-eslint/utils": 6.21.0 - "@typescript-eslint/visitor-keys": 6.21.0 - debug: ^4.3.4 + "@eslint-community/regexpp": ^4.10.0 + "@typescript-eslint/scope-manager": 8.41.0 + "@typescript-eslint/type-utils": 8.41.0 + "@typescript-eslint/utils": 8.41.0 + "@typescript-eslint/visitor-keys": 8.41.0 graphemer: ^1.4.0 - ignore: ^5.2.4 + ignore: ^7.0.0 natural-compare: ^1.4.0 - semver: ^7.5.4 - ts-api-utils: ^1.0.1 + ts-api-utils: ^2.1.0 peerDependencies: - "@typescript-eslint/parser": ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 5ef2c502255e643e98051e87eb682c2a257e87afd8ec3b9f6274277615e1c2caf3131b352244cfb1987b8b2c415645eeacb9113fa841fc4c9b2ac46e8aed6efd + "@typescript-eslint/parser": ^8.41.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 85076134b231fa634aa839d55977e5225c54a4e215b4b01faf4f511a1f953949da0da1e7566e866b84578e7318d54d82f7ab965a7445d73cb19cdbe356e4b8cd languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/parser@npm:6.21.0" +"@typescript-eslint/eslint-plugin@npm:^8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.46.0" + dependencies: + "@eslint-community/regexpp": ^4.10.0 + "@typescript-eslint/scope-manager": 8.46.0 + "@typescript-eslint/type-utils": 8.46.0 + "@typescript-eslint/utils": 8.46.0 + "@typescript-eslint/visitor-keys": 8.46.0 + graphemer: ^1.4.0 + ignore: ^7.0.0 + natural-compare: ^1.4.0 + ts-api-utils: ^2.1.0 + peerDependencies: + "@typescript-eslint/parser": ^8.46.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: b3a33bbdeffeefc5798abde387b440cfbc1c0ec6778ed2fe16238f10adae28193015ecf923f305bf9a67fcb108dced47216c9dbc6778736b6db5a97e71e212af + languageName: node + linkType: hard + +"@typescript-eslint/parser@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/parser@npm:8.41.0" dependencies: - "@typescript-eslint/scope-manager": 6.21.0 - "@typescript-eslint/types": 6.21.0 - "@typescript-eslint/typescript-estree": 6.21.0 - "@typescript-eslint/visitor-keys": 6.21.0 + "@typescript-eslint/scope-manager": 8.41.0 + "@typescript-eslint/types": 8.41.0 + "@typescript-eslint/typescript-estree": 8.41.0 + "@typescript-eslint/visitor-keys": 8.41.0 debug: ^4.3.4 peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 162fe3a867eeeffda7328bce32dae45b52283c68c8cb23258fb9f44971f761991af61f71b8c9fe1aa389e93dfe6386f8509c1273d870736c507d76dd40647b68 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: ae238c20b148da3eea20893b54a65e28d0ab3db2cfaad972b3ad73f08b037714038097827bb3933ef2ec2a55b698f4956f831dd93dd3f85b81acb839ce07d296 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/scope-manager@npm:6.21.0" +"@typescript-eslint/parser@npm:^8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/parser@npm:8.46.0" dependencies: - "@typescript-eslint/types": 6.21.0 - "@typescript-eslint/visitor-keys": 6.21.0 - checksum: 71028b757da9694528c4c3294a96cc80bc7d396e383a405eab3bc224cda7341b88e0fc292120b35d3f31f47beac69f7083196c70616434072fbcd3d3e62d3376 + "@typescript-eslint/scope-manager": 8.46.0 + "@typescript-eslint/types": 8.46.0 + "@typescript-eslint/typescript-estree": 8.46.0 + "@typescript-eslint/visitor-keys": 8.46.0 + debug: ^4.3.4 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 9447250aa770eee131d81475784404b2b07caacf9bae8cef38b9ee639d8225504849a5586b5746b575f2c5dfbc9c612eb742acd8612bb1c425245f324f574613 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/type-utils@npm:6.21.0" +"@typescript-eslint/project-service@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/project-service@npm:8.41.0" dependencies: - "@typescript-eslint/typescript-estree": 6.21.0 - "@typescript-eslint/utils": 6.21.0 + "@typescript-eslint/tsconfig-utils": ^8.41.0 + "@typescript-eslint/types": ^8.41.0 debug: ^4.3.4 - ts-api-utils: ^1.0.1 peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 77025473f4d80acf1fafcce99c5c283e557686a61861febeba9c9913331f8a41e930bf5cd8b7a54db502a57b6eb8ea6d155cbd4f41349ed00e3d7aeb1f477ddc + typescript: ">=4.8.4 <6.0.0" + checksum: f229314b857f585c6ed53cd197770ee88443b785615a91d711d1fcda4f449698b0346d7420c86d11538b505db05fe0f2df3279899384ac131a3c25f58e71c9d6 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/types@npm:6.21.0" - checksum: 9501b47d7403417af95fc1fb72b2038c5ac46feac0e1598a46bcb43e56a606c387e9dcd8a2a0abe174c91b509f2d2a8078b093786219eb9a01ab2fbf9ee7b684 +"@typescript-eslint/project-service@npm:8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/project-service@npm:8.46.0" + dependencies: + "@typescript-eslint/tsconfig-utils": ^8.46.0 + "@typescript-eslint/types": ^8.46.0 + debug: ^4.3.4 + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: ae8365cdbae5c8ee622727295f7cb59c42ccb0a4672d72692f2f31b26a052b7a9e46f58326740ca8d471a7e85998b885858be6c21921d465ce57de1d3ea7355f languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.21.0" +"@typescript-eslint/scope-manager@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/scope-manager@npm:8.41.0" + dependencies: + "@typescript-eslint/types": 8.41.0 + "@typescript-eslint/visitor-keys": 8.41.0 + checksum: 6acadc661e124c81444518819a895d841ea9c85a519b3e27249844c7e1362dd4b42f617e1b5c4812dc3b210ccbdaf7e9fca18c4de49eff9d6120c66fc7b249fc + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/scope-manager@npm:8.46.0" + dependencies: + "@typescript-eslint/types": 8.46.0 + "@typescript-eslint/visitor-keys": 8.46.0 + checksum: 0995be736f153314b7744594b7b5e27e63cf7b00b64b3a8cf23b4f01fc9cc01b9e652e433da438fe93efe63e505d61adb5c25319fe25e9f0ccdfea1ad7848fba + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.41.0, @typescript-eslint/tsconfig-utils@npm:^8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.41.0" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 522d54252f9647d22e46f963df6bafe98aa0572b021e6acf7474c40f1a68afa6753f23a0a125abb1d792a89a1b1cc654d918553a03d08f769139f2f40b0d026c + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.46.0, @typescript-eslint/tsconfig-utils@npm:^8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.0" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: d4516fb18c577a47f614efe6233354efefc582eaa4e915ae3d20c23f3b17e098b254594aa26d9c51eec1116d18665f06d9ed51229600df3ce3daecae83c76865 + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/type-utils@npm:8.41.0" dependencies: - "@typescript-eslint/types": 6.21.0 - "@typescript-eslint/visitor-keys": 6.21.0 + "@typescript-eslint/types": 8.41.0 + "@typescript-eslint/typescript-estree": 8.41.0 + "@typescript-eslint/utils": 8.41.0 debug: ^4.3.4 - globby: ^11.1.0 + ts-api-utils: ^2.1.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 117bef52bb566f3373b806649d290921d9b50cba5c83ee22278c73a399ad13f3abfe5ba1e0d33b229c1e971c0cb7f83e606f8b6c2db4ab0064ed6806cf9b6222 + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/type-utils@npm:8.46.0" + dependencies: + "@typescript-eslint/types": 8.46.0 + "@typescript-eslint/typescript-estree": 8.46.0 + "@typescript-eslint/utils": 8.46.0 + debug: ^4.3.4 + ts-api-utils: ^2.1.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 864f7bc0df053089d09bc757abf4f728f6fc942e162baa727f24cf68d1d79f53ccd1dff151e74b0e43c25dc53d5ce32f916a2218786d365e1027d99c6799d6d9 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:8.41.0, @typescript-eslint/types@npm:^8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/types@npm:8.41.0" + checksum: fec264738c7ee6c79352efb30620c544e47db7ba43523518547cabb08ff14406436b1fbf521606b319a3037ab663a694e91363554f8757e021b87a4cd18e1373 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:8.46.0, @typescript-eslint/types@npm:^8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/types@npm:8.46.0" + checksum: 71b7e0845da160cbd8ef1a5f853a1b8626f5bd00a1db56b75218eb94d5f3433f7815635e70df52118657c57109458f2e0d2bec8dcca0c620af10c66205fe54cd + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.41.0" + dependencies: + "@typescript-eslint/project-service": 8.41.0 + "@typescript-eslint/tsconfig-utils": 8.41.0 + "@typescript-eslint/types": 8.41.0 + "@typescript-eslint/visitor-keys": 8.41.0 + debug: ^4.3.4 + fast-glob: ^3.3.2 is-glob: ^4.0.3 - minimatch: 9.0.3 - semver: ^7.5.4 - ts-api-utils: ^1.0.1 - peerDependenciesMeta: - typescript: - optional: true - checksum: dec02dc107c4a541e14fb0c96148f3764b92117c3b635db3a577b5a56fc48df7a556fa853fb82b07c0663b4bf2c484c9f245c28ba3e17e5cb0918ea4cab2ea21 + minimatch: ^9.0.4 + semver: ^7.6.0 + ts-api-utils: ^2.1.0 + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: d065e693c241f236c3457007134e1927843f1db32c79a4cd5adb03b0fa94b9bf7931773d8851f7b7647d99fc1e4a31d2df9f64e0a7ac39c19cf26f966833b0b0 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/utils@npm:6.21.0" - dependencies: - "@eslint-community/eslint-utils": ^4.4.0 - "@types/json-schema": ^7.0.12 - "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.21.0 - "@typescript-eslint/types": 6.21.0 - "@typescript-eslint/typescript-estree": 6.21.0 - semver: ^7.5.4 +"@typescript-eslint/typescript-estree@npm:8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.46.0" + dependencies: + "@typescript-eslint/project-service": 8.46.0 + "@typescript-eslint/tsconfig-utils": 8.46.0 + "@typescript-eslint/types": 8.46.0 + "@typescript-eslint/visitor-keys": 8.46.0 + debug: ^4.3.4 + fast-glob: ^3.3.2 + is-glob: ^4.0.3 + minimatch: ^9.0.4 + semver: ^7.6.0 + ts-api-utils: ^2.1.0 peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - checksum: b129b3a4aebec8468259f4589985cb59ea808afbfdb9c54f02fad11e17d185e2bf72bb332f7c36ec3c09b31f18fc41368678b076323e6e019d06f74ee93f7bf2 + typescript: ">=4.8.4 <6.0.0" + checksum: 70f5523d266097c96e5de2cf28c86c5bb3c9d4f48ba129a9c13e620733d395008dc809c77f1af19fc4617133c0665bf65a6a688fbf40da29d5a6ebe137ea41ae languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.21.0" +"@typescript-eslint/utils@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/utils@npm:8.41.0" + dependencies: + "@eslint-community/eslint-utils": ^4.7.0 + "@typescript-eslint/scope-manager": 8.41.0 + "@typescript-eslint/types": 8.41.0 + "@typescript-eslint/typescript-estree": 8.41.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 3fa2a09e5f49118878c91a54c564f4576f027eb46590bbf20e43043a82880cf3166d5d70d1505737429a2202e0c1ac20df2ae6b29048bf8fa4a22caf893cae04 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/utils@npm:8.46.0" + dependencies: + "@eslint-community/eslint-utils": ^4.7.0 + "@typescript-eslint/scope-manager": 8.46.0 + "@typescript-eslint/types": 8.46.0 + "@typescript-eslint/typescript-estree": 8.46.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 63c9f4df8f823ef7f83fe2c53f85fd5e278d60240d41414f69c8ecb37061fec74ad34851faf28283042a1a0b983ddca57dbd97a7e653073068c7f22e919f84ea + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.41.0" dependencies: - "@typescript-eslint/types": 6.21.0 - eslint-visitor-keys: ^3.4.1 - checksum: 67c7e6003d5af042d8703d11538fca9d76899f0119130b373402819ae43f0bc90d18656aa7add25a24427ccf1a0efd0804157ba83b0d4e145f06107d7d1b7433 + "@typescript-eslint/types": 8.41.0 + eslint-visitor-keys: ^4.2.1 + checksum: 002bc638a1fd20293c4d69076c6e2925d712e47899dd35aa0ca4428815a08e59f6c16581dfd421abf5a65a29a5ad3a1c6fcc791b7f42b0e5f8c306e35aee0e50 + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.46.0": + version: 8.46.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.46.0" + dependencies: + "@typescript-eslint/types": 8.46.0 + eslint-visitor-keys: ^4.2.1 + checksum: 888adc68bd8d80adb185520f2016b81a934f793db323cd62452027fad2e76a5ab64ed9500c4e5a2be2e5d2458e071776ea86a62e40e32faa4348ca4ab84dddda languageName: node linkType: hard @@ -1267,13 +1497,6 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 4f656b7b4672f2ce6e272f2427d8b0824ed11546a601d8d5412b9d7704e83db38a8d9f402ecdf2b9063fc164af842ad0ec4a55819f621ed7e7ea4d1efcc74524 - languageName: node - linkType: hard - "abbrev@npm:1": version: 1.1.1 resolution: "abbrev@npm:1.1.1" @@ -1281,6 +1504,13 @@ __metadata: languageName: node linkType: hard +"abbrev@npm:1.0.x": + version: 1.0.9 + resolution: "abbrev@npm:1.0.9" + checksum: 46460c897b4ce62cd9b1bd4a853cc46e771a1f1d929f5443f3945a976f8be5388891bf9e5f8a9862baa29587349e16c48596b6a621404d46d3b184fe9bd9fb26 + languageName: node + linkType: hard + "abbrev@npm:^2.0.0": version: 2.0.0 resolution: "abbrev@npm:2.0.0" @@ -1297,12 +1527,12 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.9.0": - version: 8.11.3 - resolution: "acorn@npm:8.11.3" +"acorn@npm:^8.15.0": + version: 8.15.0 + resolution: "acorn@npm:8.15.0" bin: acorn: bin/acorn - checksum: 76d8e7d559512566b43ab4aadc374f11f563f0a9e21626dd59cb2888444e9445923ae9f3699972767f18af61df89cd89f5eaaf772d1327b055b45cb829b4a88c + checksum: 309c6b49aedf1a2e34aaf266de06de04aab6eb097c02375c66fdeb0f64556a6a823540409914fb364d9a11bc30d79d485a2eba29af47992d3490e9886c4391c3 languageName: node linkType: hard @@ -1347,6 +1577,13 @@ __metadata: languageName: node linkType: hard +"amdefine@npm:>=0.0.4": + version: 1.0.1 + resolution: "amdefine@npm:1.0.1" + checksum: 9d4e15b94641643a9385b2841b4cb2bcf4e8e2f741ea4bd475c93ad7bab261ad4ed827a32e9c549b38b98759c4526c173ae4e6dde8caeb75ee5cebedc9863762 + languageName: node + linkType: hard + "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -1471,6 +1708,13 @@ __metadata: languageName: node linkType: hard +"async@npm:1.x": + version: 1.5.2 + resolution: "async@npm:1.5.2" + checksum: fe5d6214d8f15bd51eee5ae8ec5079b228b86d2d595f47b16369dec2e11b3ff75a567bb5f70d12d79006665fbbb7ee0a7ec0e388524eefd454ecbe651c124ebd + languageName: node + linkType: hard + "async@npm:2.6.4": version: 2.6.4 resolution: "async@npm:2.6.4" @@ -1856,7 +2100,7 @@ __metadata: languageName: node linkType: hard -"combined-stream@npm:^1.0.6, combined-stream@npm:~1.0.6": +"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8, combined-stream@npm:~1.0.6": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" dependencies: @@ -1886,15 +2130,6 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:1.6.0": - version: 1.6.0 - resolution: "convert-source-map@npm:1.6.0" - dependencies: - safe-buffer: ~5.1.1 - checksum: c4af323f4d79b53234f187014804fb35abc09b3a8e8bd332ce49d3054f46599bee7c5cadc069e4800f480788f63f09377a20e96806cf42b4bf9673a2096daf57 - languageName: node - linkType: hard - "convert-source-map@npm:^1.7.0": version: 1.9.0 resolution: "convert-source-map@npm:1.9.0" @@ -1916,7 +2151,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -1992,7 +2227,7 @@ __metadata: languageName: node linkType: hard -"deep-is@npm:^0.1.3": +"deep-is@npm:^0.1.3, deep-is@npm:~0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" checksum: edb65dd0d7d1b9c40b2f50219aef30e116cedd6fc79290e740972c132c09106d2e80aa0bc8826673dd5a00222d4179c84b36a790eef63a4c4bca75a37ef90804 @@ -2066,15 +2301,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:^3.0.0": - version: 3.0.0 - resolution: "doctrine@npm:3.0.0" - dependencies: - esutils: ^2.0.2 - checksum: fd7673ca77fe26cd5cba38d816bc72d641f500f1f9b25b83e8ce28827fe2da7ad583a8da26ab6af85f834138cf8dae9f69b0cd6ab925f52ddab1754db44d99ce - languageName: node - linkType: hard - "dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" @@ -2091,30 +2317,34 @@ __metadata: resolution: "e2e-tests@workspace:." dependencies: "@axe-core/playwright": ^4.10.2 - "@azure/arm-network": ^34.0.0 + "@azure/arm-network": 34.0.0 "@azure/identity": 4.9.1 + "@eslint/js": ^9.34.0 "@keycloak/keycloak-admin-client": 25.0.6 "@kubernetes/client-node": 0.22.3 "@microsoft/microsoft-graph-client": 3.0.7 - "@microsoft/microsoft-graph-types": 2.40.0 - "@playwright/test": 1.53.2 + "@microsoft/microsoft-graph-types": 2.43.1 + "@playwright/test": 1.56.0 "@types/node": 22.16.3 - "@typescript-eslint/eslint-plugin": 6.21.0 - "@typescript-eslint/parser": 6.21.0 - eslint: 8.57.1 + "@typescript-eslint/eslint-plugin": ^8.46.0 + "@typescript-eslint/parser": ^8.46.0 + eslint: ^9.34.0 + eslint-plugin-check-file: ^3.3.0 eslint-plugin-filenames: 1.3.2 - ioredis: 5.6.1 + eslint-plugin-playwright: ^2.2.2 + ioredis: 5.8.1 isomorphic-fetch: 3.0.0 js-yaml: 4.1.0 node-fetch: 2.7.0 octokit: 4.1.4 otplib: 12.0.1 prettier: 3.6.2 - sealights-playwright-plugin: ^2.0.113 - typescript: 5.8.3 - uuid: ^11.1.0 + sealights-playwright-plugin: ^2.0.124 + typescript: ^5.9.2 + typescript-eslint: ^8.41.0 + uuid: 11.1.0 winston: 3.14.2 - yaml: ^2.8.0 + yaml: 2.8.1 languageName: unknown linkType: soft @@ -2218,6 +2448,18 @@ __metadata: languageName: node linkType: hard +"es-set-tostringtag@npm:^2.1.0": + version: 2.1.0 + resolution: "es-set-tostringtag@npm:2.1.0" + dependencies: + es-errors: ^1.3.0 + get-intrinsic: ^1.2.6 + has-tostringtag: ^1.0.2 + hasown: ^2.0.2 + checksum: 789f35de4be3dc8d11fdcb91bc26af4ae3e6d602caa93299a8c45cf05d36cc5081454ae2a6d3afa09cceca214b76c046e4f8151e092e6fc7feeb5efb9e794fc6 + languageName: node + linkType: hard + "es6-error@npm:^4.0.1": version: 4.1.1 resolution: "es6-error@npm:4.1.1" @@ -2246,6 +2488,37 @@ __metadata: languageName: node linkType: hard +"escodegen@npm:1.8.x": + version: 1.8.1 + resolution: "escodegen@npm:1.8.1" + dependencies: + esprima: ^2.7.1 + estraverse: ^1.9.1 + esutils: ^2.0.2 + optionator: ^0.8.1 + source-map: ~0.2.0 + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: ./bin/escodegen.js + esgenerate: ./bin/esgenerate.js + checksum: 99f5579dbc309d8f95f8051cce2f85620c073ff1d4f7b58197addee7e81aeb5281dadfbd446a0885b8fb8c0c47ce5c2cdb5f97dbfddccb5126cca5eb9af73992 + languageName: node + linkType: hard + +"eslint-plugin-check-file@npm:^3.3.0": + version: 3.3.0 + resolution: "eslint-plugin-check-file@npm:3.3.0" + dependencies: + is-glob: ^4.0.3 + micromatch: ^4.0.8 + peerDependencies: + eslint: ">=9.0.0" + checksum: 03be924f794c9575ae4a370f9711323fbe8e7513751c39911786a5ea41ebe7a713159dfba49547e3a7098c5e74163925c5121b00b85afe14caea5b1982d3497a + languageName: node + linkType: hard + "eslint-plugin-filenames@npm:1.3.2": version: 1.3.2 resolution: "eslint-plugin-filenames@npm:1.3.2" @@ -2260,79 +2533,109 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-plugin-playwright@npm:^2.2.2": + version: 2.2.2 + resolution: "eslint-plugin-playwright@npm:2.2.2" + dependencies: + globals: ^13.23.0 + peerDependencies: + eslint: ">=8.40.0" + checksum: a64d1078218d12676c3470c3be400c9ec254c440fde1a0eb09d421e29809093afa47bc676d1ec4ee4558d8f01d11551d269d5cf3e7407cce0391cea1a135c325 + languageName: node + linkType: hard + +"eslint-scope@npm:^8.4.0": + version: 8.4.0 + resolution: "eslint-scope@npm:8.4.0" dependencies: esrecurse: ^4.3.0 estraverse: ^5.2.0 - checksum: ec97dbf5fb04b94e8f4c5a91a7f0a6dd3c55e46bfc7bbcd0e3138c3a76977570e02ed89a1810c778dcd72072ff0e9621ba1379b4babe53921d71e2e4486fda3e + checksum: cf88f42cd5e81490d549dc6d350fe01e6fe420f9d9ea34f134bb359b030e3c4ef888d36667632e448937fe52449f7181501df48c08200e3d3b0fee250d05364e languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 36e9ef87fca698b6fd7ca5ca35d7b2b6eeaaf106572e2f7fd31c12d3bfdaccdb587bba6d3621067e5aece31c8c3a348b93922ab8f7b2cbc6aaab5e1d89040c60 languageName: node linkType: hard -"eslint@npm:8.57.1": - version: 8.57.1 - resolution: "eslint@npm:8.57.1" +"eslint-visitor-keys@npm:^4.2.1": + version: 4.2.1 + resolution: "eslint-visitor-keys@npm:4.2.1" + checksum: 3a77e3f99a49109f6fb2c5b7784bc78f9743b834d238cdba4d66c602c6b52f19ed7bcd0a5c5dbbeae3a8689fd785e76c001799f53d2228b278282cf9f699fff5 + languageName: node + linkType: hard + +"eslint@npm:^9.34.0": + version: 9.34.0 + resolution: "eslint@npm:9.34.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 - "@eslint-community/regexpp": ^4.6.1 - "@eslint/eslintrc": ^2.1.4 - "@eslint/js": 8.57.1 - "@humanwhocodes/config-array": ^0.13.0 + "@eslint-community/regexpp": ^4.12.1 + "@eslint/config-array": ^0.21.0 + "@eslint/config-helpers": ^0.3.1 + "@eslint/core": ^0.15.2 + "@eslint/eslintrc": ^3.3.1 + "@eslint/js": 9.34.0 + "@eslint/plugin-kit": ^0.3.5 + "@humanfs/node": ^0.16.6 "@humanwhocodes/module-importer": ^1.0.1 - "@nodelib/fs.walk": ^1.2.8 - "@ungap/structured-clone": ^1.2.0 + "@humanwhocodes/retry": ^0.4.2 + "@types/estree": ^1.0.6 + "@types/json-schema": ^7.0.15 ajv: ^6.12.4 chalk: ^4.0.0 - cross-spawn: ^7.0.2 + cross-spawn: ^7.0.6 debug: ^4.3.2 - doctrine: ^3.0.0 escape-string-regexp: ^4.0.0 - eslint-scope: ^7.2.2 - eslint-visitor-keys: ^3.4.3 - espree: ^9.6.1 - esquery: ^1.4.2 + eslint-scope: ^8.4.0 + eslint-visitor-keys: ^4.2.1 + espree: ^10.4.0 + esquery: ^1.5.0 esutils: ^2.0.2 fast-deep-equal: ^3.1.3 - file-entry-cache: ^6.0.1 + file-entry-cache: ^8.0.0 find-up: ^5.0.0 glob-parent: ^6.0.2 - globals: ^13.19.0 - graphemer: ^1.4.0 ignore: ^5.2.0 imurmurhash: ^0.1.4 is-glob: ^4.0.0 - is-path-inside: ^3.0.3 - js-yaml: ^4.1.0 json-stable-stringify-without-jsonify: ^1.0.1 - levn: ^0.4.1 lodash.merge: ^4.6.2 minimatch: ^3.1.2 natural-compare: ^1.4.0 optionator: ^0.9.3 - strip-ansi: ^6.0.1 - text-table: ^0.2.0 + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true bin: eslint: bin/eslint.js - checksum: e2489bb7f86dd2011967759a09164e65744ef7688c310bc990612fc26953f34cc391872807486b15c06833bdff737726a23e9b4cdba5de144c311377dc41d91b + checksum: 6de97f6197774821a086783e1bd73b9518c4eb8896165e448a8bb2359142c63cad40faa5dc79bcdc28fab20b57e1376ccbb76a6ae081da5e94baa18d2d3b92fe languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" +"espree@npm:^10.0.1, espree@npm:^10.4.0": + version: 10.4.0 + resolution: "espree@npm:10.4.0" dependencies: - acorn: ^8.9.0 + acorn: ^8.15.0 acorn-jsx: ^5.3.2 - eslint-visitor-keys: ^3.4.1 - checksum: eb8c149c7a2a77b3f33a5af80c10875c3abd65450f60b8af6db1bfcfa8f101e21c1e56a561c6dc13b848e18148d43469e7cd208506238554fb5395a9ea5a1ab9 + eslint-visitor-keys: ^4.2.1 + checksum: 5f9d0d7c81c1bca4bfd29a55270067ff9d575adb8c729a5d7f779c2c7b910bfc68ccf8ec19b29844b707440fc159a83868f22c8e87bbf7cbcb225ed067df6c85 + languageName: node + linkType: hard + +"esprima@npm:2.7.x, esprima@npm:^2.7.1": + version: 2.7.3 + resolution: "esprima@npm:2.7.3" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 55584508dca0551885e62c3369bc4a783bd948b43e2f034f05c2a37f3ca398db99f072ab228234e9cab09af8dc8c65d6ca7de3a975f2a296b34d1a3aba7e89f1 languageName: node linkType: hard @@ -2356,12 +2659,12 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2": - version: 1.5.0 - resolution: "esquery@npm:1.5.0" +"esquery@npm:^1.5.0": + version: 1.6.0 + resolution: "esquery@npm:1.6.0" dependencies: estraverse: ^5.1.0 - checksum: aefb0d2596c230118656cd4ec7532d447333a410a48834d80ea648b1e7b5c9bc9ed8b5e33a89cb04e487b60d622f44cf5713bf4abed7c97343edefdc84a35900 + checksum: 08ec4fe446d9ab27186da274d979558557fbdbbd10968fa9758552482720c54152a5640e08b9009e5a30706b66aba510692054d4129d32d0e12e05bbc0b96fb2 languageName: node linkType: hard @@ -2374,6 +2677,13 @@ __metadata: languageName: node linkType: hard +"estraverse@npm:^1.9.1": + version: 1.9.3 + resolution: "estraverse@npm:1.9.3" + checksum: 78fa96317500e7783d48297dbd4c7f8735ddeb970be2981b485639ffa77578d05b8f781332622e436f2e9e533f32923c62c2e6463291e577ceeaf2776ac5e4b5 + languageName: node + linkType: hard + "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" @@ -2443,6 +2753,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:^3.3.2": + version: 3.3.3 + resolution: "fast-glob@npm:3.3.3" + dependencies: + "@nodelib/fs.stat": ^2.0.2 + "@nodelib/fs.walk": ^1.2.3 + glob-parent: ^5.1.2 + merge2: ^1.3.0 + micromatch: ^4.0.8 + checksum: 0704d7b85c0305fd2cef37777337dfa26230fdd072dce9fb5c82a4b03156f3ffb8ed3e636033e65d45d2a5805a4e475825369a27404c0307f2db0c8eb3366fbd + languageName: node + linkType: hard + "fast-json-stable-stringify@npm:^2.0.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" @@ -2450,7 +2773,7 @@ __metadata: languageName: node linkType: hard -"fast-levenshtein@npm:^2.0.6": +"fast-levenshtein@npm:^2.0.6, fast-levenshtein@npm:~2.0.6": version: 2.0.6 resolution: "fast-levenshtein@npm:2.0.6" checksum: 92cfec0a8dfafd9c7a15fba8f2cc29cd0b62b85f056d99ce448bbcd9f708e18ab2764bda4dd5158364f4145a7c72788538994f0d1787b956ef0d1062b0f7c24c @@ -2480,12 +2803,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" dependencies: - flat-cache: ^3.0.4 - checksum: f49701feaa6314c8127c3c2f6173cfefff17612f5ed2daaafc6da13b5c91fd43e3b2a58fd0d63f9f94478a501b167615931e7200e31485e320f74a33885a9c74 + flat-cache: ^4.0.0 + checksum: f67802d3334809048c69b3d458f672e1b6d26daefda701761c81f203b80149c35dea04d78ea4238969dd617678e530876722a0634c43031a0957f10cc3ed190f languageName: node linkType: hard @@ -2539,14 +2862,13 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.2.0 - resolution: "flat-cache@npm:3.2.0" +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" dependencies: flatted: ^3.2.9 - keyv: ^4.5.3 - rimraf: ^3.0.2 - checksum: e7e0f59801e288b54bee5cb9681e9ee21ee28ef309f886b312c9d08415b79fc0f24ac842f84356ce80f47d6a53de62197ce0e6e148dc42d5db005992e2a756ec + keyv: ^4.5.4 + checksum: 899fc86bf6df093547d76e7bfaeb900824b869d7d457d02e9b8aae24836f0a99fbad79328cfd6415ee8908f180699bf259dc7614f793447cb14f707caf5996f6 languageName: node linkType: hard @@ -2611,6 +2933,20 @@ __metadata: languageName: node linkType: hard +"form-data@npm:~2.5.5": + version: 2.5.5 + resolution: "form-data@npm:2.5.5" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 + mime-types: ^2.1.35 + safe-buffer: ^5.2.1 + checksum: ba6d8467f959c9bf36a52e423256c1e8055a8e650416760f54fa5db261529c3de698a4ce8378dd4fdb71b44be190906d6b73446556cc74e58de8bda01d09e9e7 + languageName: node + linkType: hard + "fromentries@npm:^1.2.0": version: 1.3.2 resolution: "fromentries@npm:1.3.2" @@ -2683,7 +3019,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.3.0": +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.3.0": version: 1.3.0 resolution: "get-intrinsic@npm:1.3.0" dependencies: @@ -2745,19 +3081,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:8.1.0": - version: 8.1.0 - resolution: "glob@npm:8.1.0" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^5.0.1 - once: ^1.3.0 - checksum: 92fbea3221a7d12075f26f0227abac435de868dd0736a17170663783296d0dd8d3d532a5672b4488a439bf5d7fb85cdd07c11185d6cd39184f0385cbdfb86a47 - languageName: node - linkType: hard - "glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": version: 10.4.5 resolution: "glob@npm:10.4.5" @@ -2774,6 +3097,19 @@ __metadata: languageName: node linkType: hard +"glob@npm:^5.0.15": + version: 5.0.15 + resolution: "glob@npm:5.0.15" + dependencies: + inflight: ^1.0.4 + inherits: 2 + minimatch: 2 || 3 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: f9742448303460672607e569457f1b57e486a79a985e269b69465834d2075b243378225f65dc54c09fcd4b75e4fb34442aec88f33f8c65fa4abccc8ee2dc2f5d + languageName: node + linkType: hard + "glob@npm:^7.0.3, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -2795,7 +3131,7 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0": +"globals@npm:^13.23.0": version: 13.24.0 resolution: "globals@npm:13.24.0" dependencies: @@ -2804,6 +3140,13 @@ __metadata: languageName: node linkType: hard +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 534b8216736a5425737f59f6e6a5c7f386254560c9f41d24a9227d60ee3ad4a9e82c5b85def0e212e9d92162f83a92544be4c7fd4c902cb913736c10e08237ac + languageName: node + linkType: hard + "globby@npm:^11.1.0": version: 11.1.0 resolution: "globby@npm:11.1.0" @@ -2839,6 +3182,24 @@ __metadata: languageName: node linkType: hard +"handlebars@npm:^4.0.1": + version: 4.7.8 + resolution: "handlebars@npm:4.7.8" + dependencies: + minimist: ^1.2.5 + neo-async: ^2.6.2 + source-map: ^0.6.1 + uglify-js: ^3.1.4 + wordwrap: ^1.0.0 + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: 00e68bb5c183fd7b8b63322e6234b5ac8fbb960d712cb3f25587d559c2951d9642df83c04a1172c918c41bcfc81bfbd7a7718bbce93b893e0135fc99edea93ff + languageName: node + linkType: hard + "har-schema@npm:^2.0.0": version: 2.0.0 resolution: "har-schema@npm:2.0.0" @@ -2856,6 +3217,13 @@ __metadata: languageName: node linkType: hard +"has-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "has-flag@npm:1.0.0" + checksum: ce3f8ae978e70f16e4bbe17d3f0f6d6c0a3dd3b62a23f97c91d0fda9ed8e305e13baf95cc5bee4463b9f25ac9f5255de113165c5fb285e01b8065b2ac079b301 + languageName: node + linkType: hard + "has-flag@npm:^3.0.0": version: 3.0.0 resolution: "has-flag@npm:3.0.0" @@ -2975,13 +3343,20 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.2.0, ignore@npm:^5.2.4": +"ignore@npm:^5.2.0": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 2acfd32a573260ea522ea0bfeff880af426d68f6831f973129e2ba7363f422923cf53aab62f8369cbf4667c7b25b6f8a3761b34ecdb284ea18e87a5262a865be languageName: node linkType: hard +"ignore@npm:^7.0.0": + version: 7.0.5 + resolution: "ignore@npm:7.0.5" + checksum: d0862bf64d3d58bf34d5fb0a9f725bec9ca5ce8cd1aecc8f28034269e8f69b8009ffd79ca3eda96962a6a444687781cd5efdb8c7c8ddc0a6996e36d31c217f14 + languageName: node + linkType: hard + "import-fresh@npm:^3.2.1": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" @@ -3023,11 +3398,11 @@ __metadata: languageName: node linkType: hard -"ioredis@npm:5.6.1": - version: 5.6.1 - resolution: "ioredis@npm:5.6.1" +"ioredis@npm:5.8.1": + version: 5.8.1 + resolution: "ioredis@npm:5.8.1" dependencies: - "@ioredis/commands": ^1.1.1 + "@ioredis/commands": 1.4.0 cluster-key-slot: ^1.1.0 debug: ^4.3.4 denque: ^2.1.0 @@ -3036,7 +3411,7 @@ __metadata: redis-errors: ^1.2.0 redis-parser: ^3.0.0 standard-as-callback: ^2.1.0 - checksum: 89100a97b2210fed2aca45daf902adee8aa2294e56f817742651c86234a3efa56f82aa5aa762a94f5fbf806942f259ef5e628f626d1841d20d5cbb163fc8bd3f + checksum: 85170b39ceace90d4ea104d4943397b3b1a6c3cf593ca5276a92d7e7373899e2c72e6b6d6ec2172dafba4ed2a29237b509c187b78333f90d87aa574b114971f8 languageName: node linkType: hard @@ -3150,13 +3525,6 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.3": - version: 3.0.3 - resolution: "is-path-inside@npm:3.0.3" - checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 - languageName: node - linkType: hard - "is-regex@npm:^1.2.1": version: 1.2.1 resolution: "is-regex@npm:1.2.1" @@ -3323,7 +3691,7 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-source-maps@npm:^4.0.0": +"istanbul-lib-source-maps@npm:^4.0.0, istanbul-lib-source-maps@npm:^4.0.1": version: 4.0.1 resolution: "istanbul-lib-source-maps@npm:4.0.1" dependencies: @@ -3344,6 +3712,30 @@ __metadata: languageName: node linkType: hard +"istanbul@npm:0.4.5": + version: 0.4.5 + resolution: "istanbul@npm:0.4.5" + dependencies: + abbrev: 1.0.x + async: 1.x + escodegen: 1.8.x + esprima: 2.7.x + glob: ^5.0.15 + handlebars: ^4.0.1 + js-yaml: 3.x + mkdirp: 0.5.x + nopt: 3.x + once: 1.x + resolve: 1.1.x + supports-color: ^3.1.0 + which: ^1.1.1 + wordwrap: ^1.0.0 + bin: + istanbul: ./lib/cli.js + checksum: 14d4ab73c015c4bd49b904b1cb6c984c74e6a382b9104ec1877f14d500f6a2940e5dd7058e2b7f06fc0b58e6b5dd89017fcf5215a1a03840e1a889d93c5e4197 + languageName: node + linkType: hard + "jackspeak@npm:^3.1.2": version: 3.4.3 resolution: "jackspeak@npm:3.4.3" @@ -3371,26 +3763,26 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:4.1.0, js-yaml@npm:^4.1.0": - version: 4.1.0 - resolution: "js-yaml@npm:4.1.0" +"js-yaml@npm:3.x, js-yaml@npm:^3.13.1": + version: 3.14.1 + resolution: "js-yaml@npm:3.14.1" dependencies: - argparse: ^2.0.1 + argparse: ^1.0.7 + esprima: ^4.0.0 bin: js-yaml: bin/js-yaml.js - checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a + checksum: bef146085f472d44dee30ec34e5cf36bf89164f5d585435a3d3da89e52622dff0b188a580e4ad091c3341889e14cb88cac6e4deb16dc5b1e9623bb0601fc255c languageName: node linkType: hard -"js-yaml@npm:^3.13.1": - version: 3.14.1 - resolution: "js-yaml@npm:3.14.1" +"js-yaml@npm:4.1.0, js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" dependencies: - argparse: ^1.0.7 - esprima: ^4.0.0 + argparse: ^2.0.1 bin: js-yaml: bin/js-yaml.js - checksum: bef146085f472d44dee30ec34e5cf36bf89164f5d585435a3d3da89e52622dff0b188a580e4ad091c3341889e14cb88cac6e4deb16dc5b1e9623bb0601fc255c + checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a languageName: node linkType: hard @@ -3556,7 +3948,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": +"keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -3582,10 +3974,13 @@ __metadata: languageName: node linkType: hard -"lightcookie@npm:1.0.24": - version: 1.0.24 - resolution: "lightcookie@npm:1.0.24" - checksum: b30d4a495488ac345ffc850e5f3d2d3b344a683091680f9d0c919e42ac76f5facddf79d180b85f42b7a27f3878c374a1db94441de17fd0595c5542eda3034303 +"levn@npm:~0.3.0": + version: 0.3.0 + resolution: "levn@npm:0.3.0" + dependencies: + prelude-ls: ~1.1.2 + type-check: ~0.3.2 + checksum: 0d084a524231a8246bb10fec48cdbb35282099f6954838604f3c7fc66f2e16fa66fd9cc2f3f20a541a113c4dafdf181e822c887c8a319c9195444e6c64ac395e languageName: node linkType: hard @@ -3854,7 +4249,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:4.0.8, micromatch@npm:^4.0.4": +"micromatch@npm:4.0.8, micromatch@npm:^4.0.4, micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -3871,7 +4266,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:~2.1.19": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.35, mime-types@npm:~2.1.19": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -3880,16 +4275,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:9.0.3": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: ^2.0.1 - checksum: 253487976bf485b612f16bf57463520a14f512662e592e95c571afdab1442a6a6864b6c88f248ce6fc4ff0b6de04ac7aa6c8bb51e868e99d1d65eb0658a708b5 - languageName: node - linkType: hard - -"minimatch@npm:^3.0.3, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:2 || 3, minimatch@npm:^3.0.3, minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -3898,15 +4284,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.1": - version: 5.1.6 - resolution: "minimatch@npm:5.1.6" - dependencies: - brace-expansion: ^2.0.1 - checksum: 7564208ef81d7065a370f788d337cd80a689e981042cb9a1d0e6580b6c6a8c9279eba80010516e258835a988363f99f54a6f711a315089b8b42694f5da9d0d77 - languageName: node - linkType: hard - "minimatch@npm:^9.0.4": version: 9.0.5 resolution: "minimatch@npm:9.0.5" @@ -3916,7 +4293,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.5": +"minimist@npm:^1.2.5, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -4028,6 +4405,17 @@ __metadata: languageName: node linkType: hard +"mkdirp@npm:0.5.x": + version: 0.5.6 + resolution: "mkdirp@npm:0.5.6" + dependencies: + minimist: ^1.2.6 + bin: + mkdirp: bin/cmd.js + checksum: 0c91b721bb12c3f9af4b77ebf73604baf350e64d80df91754dc509491ae93bf238581e59c7188360cec7cb62fc4100959245a42cfe01834efedc5e9d068376c2 + languageName: node + linkType: hard + "mkdirp@npm:^1.0.3": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" @@ -4067,6 +4455,13 @@ __metadata: languageName: node linkType: hard +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 + languageName: node + linkType: hard + "node-fetch@npm:2.7.0, node-fetch@npm:^2.6.1": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" @@ -4135,6 +4530,17 @@ __metadata: languageName: node linkType: hard +"nopt@npm:3.x": + version: 3.0.6 + resolution: "nopt@npm:3.0.6" + dependencies: + abbrev: 1 + bin: + nopt: ./bin/nopt.js + checksum: 7f8579029a0d7cb3341c6b1610b31e363f708b7aaaaf3580e3ec5ae8528d1f3a79d350d8bfa331776e6c6703a5a148b72edd9b9b4c1dd55874d8e70e963d1e20 + languageName: node + linkType: hard + "nopt@npm:^7.0.0": version: 7.2.1 resolution: "nopt@npm:7.2.1" @@ -4223,7 +4629,7 @@ __metadata: languageName: node linkType: hard -"once@npm:^1.3.0": +"once@npm:1.x, once@npm:^1.3.0": version: 1.4.0 resolution: "once@npm:1.4.0" dependencies: @@ -4263,6 +4669,20 @@ __metadata: languageName: node linkType: hard +"optionator@npm:^0.8.1": + version: 0.8.3 + resolution: "optionator@npm:0.8.3" + dependencies: + deep-is: ~0.1.3 + fast-levenshtein: ~2.0.6 + levn: ~0.3.0 + prelude-ls: ~1.1.2 + type-check: ~0.3.2 + word-wrap: ~1.2.3 + checksum: b8695ddf3d593203e25ab0900e265d860038486c943ff8b774f596a310f8ceebdb30c6832407a8198ba3ec9debe1abe1f51d4aad94843612db3b76d690c61d34 + languageName: node + linkType: hard + "optionator@npm:^0.9.3": version: 0.9.3 resolution: "optionator@npm:0.9.3" @@ -4445,27 +4865,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.53.2": - version: 1.53.2 - resolution: "playwright-core@npm:1.53.2" +"playwright-core@npm:1.56.0": + version: 1.56.0 + resolution: "playwright-core@npm:1.56.0" bin: playwright-core: cli.js - checksum: 01530abe93a094482e5cc171e195001bd351c1b75430fb8820e17a2cfc6d67e34e0e59871dd738e1754cd2720fb0c797acb10295bcdc092a268cd297ae4bb3bd + checksum: 29240317dc8ddcfa389899ac9dbce8a6f451e85b50c9ee105282c72d7a4cc37dad274b18037c8021d88e1317ebd5a779d56e3dc15aa358a5a8a9de87762918ef languageName: node linkType: hard -"playwright@npm:1.53.2": - version: 1.53.2 - resolution: "playwright@npm:1.53.2" +"playwright@npm:1.56.0": + version: 1.56.0 + resolution: "playwright@npm:1.56.0" dependencies: fsevents: 2.3.2 - playwright-core: 1.53.2 + playwright-core: 1.56.0 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: f5a1cb319eb8f1c30d4f934bbc0c48a3cb0c796286bbb008c82cb2b0666a318c6f910ed5db6cf44f68bac64e6d42485e834306b8bed08f6385ff348337b23c61 + checksum: 1756504fb60338dc18d8887866b3ef079b24e150c54052ba6a94099c6fc8fa018ebbe9aa93e618b703cfa357fd55193f990d080dbb173529c93a0e3df49f1d01 languageName: node linkType: hard @@ -4483,6 +4903,13 @@ __metadata: languageName: node linkType: hard +"prelude-ls@npm:~1.1.2": + version: 1.1.2 + resolution: "prelude-ls@npm:1.1.2" + checksum: c4867c87488e4a0c233e158e4d0d5565b609b105d75e4c05dc760840475f06b731332eb93cc8c9cecb840aa8ec323ca3c9a56ad7820ad2e63f0261dadcb154e4 + languageName: node + linkType: hard + "prettier@npm:3.6.2": version: 3.6.2 resolution: "prettier@npm:3.6.2" @@ -4693,6 +5120,20 @@ __metadata: languageName: node linkType: hard +"resolve@npm:1.1.x": + version: 1.1.7 + resolution: "resolve@npm:1.1.7" + checksum: afd20873fbde7641c9125efe3f940c2a99f6b1f90f1b7b743e744bdaac1cb105b2e4e0317bcc052ed7e31d57afa86b394a4dc9a1b33a297977be134fdf0250ab + languageName: node + linkType: hard + +"resolve@patch:resolve@1.1.x#~builtin": + version: 1.1.7 + resolution: "resolve@patch:resolve@npm%3A1.1.7#~builtin::version=1.1.7&hash=3bafbf" + checksum: e9dbca78600ae56835c43a09f1276876c883e4b4bbd43e2683fa140671519d2bdebeb1c1576ca87c8c508ae2987b3ec481645ac5d3054b0f23254cfc1ce49942 + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -4714,7 +5155,7 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:3.0.2, rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": +"rimraf@npm:3.0.2, rimraf@npm:^3.0.0": version: 3.0.2 resolution: "rimraf@npm:3.0.2" dependencies: @@ -4752,20 +5193,13 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 languageName: node linkType: hard -"safe-buffer@npm:~5.1.1": - version: 5.1.2 - resolution: "safe-buffer@npm:5.1.2" - checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c - languageName: node - linkType: hard - "safe-regex-test@npm:^1.1.0": version: 1.1.0 resolution: "safe-regex-test@npm:1.1.0" @@ -4791,12 +5225,12 @@ __metadata: languageName: node linkType: hard -"sealights-playwright-plugin@npm:^2.0.113": - version: 2.0.113 - resolution: "sealights-playwright-plugin@npm:2.0.113" +"sealights-playwright-plugin@npm:^2.0.124": + version: 2.0.127 + resolution: "sealights-playwright-plugin@npm:2.0.127" dependencies: - slnodejs: 6.1.948 - checksum: de24f02a0135af3faee83c3d3fb08fc8c29978f8cc47146a44895e87de413879c9047f83994e7aa696b68b35b4dd10fc2eda726ec2b2df73f53754429af1d0b1 + slnodejs: 6.1.1101 + checksum: 9a6e5dbd3a9c557152231777466efc72b97fa6fe0cd61e7ea1f70e6ddc41c89a9c7d809cab54a05096e6aca7432f27b37d26261c0ff3657a9087f8582bc6bd85 languageName: node linkType: hard @@ -4827,7 +5261,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.5.3": +"semver@npm:^7.5.3, semver@npm:^7.6.0": version: 7.7.2 resolution: "semver@npm:7.7.2" bin: @@ -4903,6 +5337,13 @@ __metadata: languageName: node linkType: hard +"sl-convert-source-map@npm:^1.0.1": + version: 1.0.1 + resolution: "sl-convert-source-map@npm:1.0.1" + checksum: 9438f8458766cbde027c34f4b3541e69f342bfca7e97ae54f7b284e755cef0f97e5a0b41c958d072425fc1d0ce75ab0d9c0515199367f6331b0a65bcc4d9723c + languageName: node + linkType: hard + "sl-esprima-ast-utils@npm:0.0.7": version: 0.0.7 resolution: "sl-esprima-ast-utils@npm:0.0.7" @@ -4914,22 +5355,24 @@ __metadata: languageName: node linkType: hard -"sl-istanbul-lib-instrument@npm:6.0.2": - version: 6.0.2 - resolution: "sl-istanbul-lib-instrument@npm:6.0.2" +"sl-istanbul-lib-instrument@npm:6.0.7": + version: 6.0.7 + resolution: "sl-istanbul-lib-instrument@npm:6.0.7" dependencies: "@babel/core": ^7.23.9 "@babel/parser": ^7.23.9 "@istanbuljs/schema": ^0.1.3 istanbul-lib-coverage: ^3.2.0 semver: ^7.5.4 - checksum: 4946394a7ce95654c7051549d3e6348ca9f16e75194631b037781e2353186b76416e2888592821ed75f95434aede2e193d4f133bfe82b1f64156e4c605601fbc + source-map: 0.6.1 + uuid: 3.1.0 + checksum: 059ff3859bf1440c33b1e8a5778acd2b3460745cc8ea1b08133f6ed460559515df8eccc1c82d03f1c0275fa3655fd472d7c72058f7592d93c88132b3cff08fae languageName: node linkType: hard -"sl-request@npm:1.0.5": - version: 1.0.5 - resolution: "sl-request@npm:1.0.5" +"sl-request@npm:1.0.6": + version: 1.0.6 + resolution: "sl-request@npm:1.0.6" dependencies: aws-sign2: ~0.7.0 aws4: ^1.8.0 @@ -4937,7 +5380,7 @@ __metadata: combined-stream: ~1.0.6 extend: ~3.0.2 forever-agent: ~0.6.1 - form-data: ~2.3.2 + form-data: ~2.5.5 har-validator: ^5.1.3 http-signature: ~1.2.0 is-typedarray: ~1.0.0 @@ -4951,7 +5394,7 @@ __metadata: tough-cookie: 4.1.3 tunnel-agent: ^0.6.0 uuid: ^3.3.2 - checksum: dcfb675db475c507b058f4502dc78698671e717d9e742e1573dc96db380ec64cc728bd3343ee6bac1c65db052c0be4564a1ce821bbfc15c2c735b48161d7e24d + checksum: 5c57c616534fbc2152d7a8eb91a32f5e8e3a5426ab1132922f1acad8328f1caa153aca46e170c286467478de260f83f75aff126aef6f05dc56e2b841ad665830 languageName: node linkType: hard @@ -4973,25 +5416,26 @@ __metadata: languageName: node linkType: hard -"slnodejs@npm:6.1.948": - version: 6.1.948 - resolution: "slnodejs@npm:6.1.948" +"slnodejs@npm:6.1.1101": + version: 6.1.1101 + resolution: "slnodejs@npm:6.1.1101" dependencies: "@babel/generator": 7.18.9 "@babel/parser": 7.18.9 + "@jridgewell/gen-mapping": 0.3.5 ast-traverse: 0.1.1 ast-types: 0.15.1 async: 2.6.4 chalk: 2.4.1 cli-progress: 3.11.2 commander: 4.1.0 - convert-source-map: 1.6.0 fileset: 2.0.3 - glob: 8.1.0 + globby: ^11.1.0 ignore: 5.2.0 + istanbul: 0.4.5 istanbul-lib-instrument: 3.0.0 + istanbul-lib-source-maps: ^4.0.1 jwt-decode: 3.1.2 - lightcookie: 1.0.24 lodash.clonedeep: ^4.5.0 lodash.filter: ^4.6.0 lodash.flatmap: ^4.5.0 @@ -5006,9 +5450,10 @@ __metadata: read-json-sync: 1.1.1 rimraf: 3.0.2 shell-quote: 1.7.3 + sl-convert-source-map: ^1.0.1 sl-esprima-ast-utils: 0.0.7 - sl-istanbul-lib-instrument: 6.0.2 - sl-request: 1.0.5 + sl-istanbul-lib-instrument: 6.0.7 + sl-request: 1.0.6 source-map: 0.6.1 table: 6.7.1 triple-beam: ~1.3.0 @@ -5017,7 +5462,7 @@ __metadata: winston: 3.8.0 bin: slnodejs: lib/cli.js - checksum: c60bb74eaa4f0bae19519a2b893fa31140bc7a97eb9334e7280b738780c2bbde69e4b422490de752c4737ce55bbf3f71e9da8e9cd43a8e61ce0ec97c4b704ce7 + checksum: 8d0eda89e921325a73fe922cb07bd2d871dd7bac02a23419d8c71bc92857d0c5c5d754e3084969d75792686033995f92edda28b354e2316d2ecd73efe5105347 languageName: node linkType: hard @@ -5056,6 +5501,15 @@ __metadata: languageName: node linkType: hard +"source-map@npm:~0.2.0": + version: 0.2.0 + resolution: "source-map@npm:0.2.0" + dependencies: + amdefine: ">=0.0.4" + checksum: 95fe800c3a93f8c0b9516c033bfc75f2678e27d2e6c0b23ae222f5ddc4afa0a39bd0be15d1c0a1e766d388f3761cc854a053a4330f49242e6045e1a4f9dc0e26 + languageName: node + linkType: hard + "spawn-wrap@npm:^2.0.0": version: 2.0.0 resolution: "spawn-wrap@npm:2.0.0" @@ -5198,6 +5652,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^3.1.0": + version: 3.2.3 + resolution: "supports-color@npm:3.2.3" + dependencies: + has-flag: ^1.0.0 + checksum: 56afc05fa87d00100d90148c4d0a6e20a0af0d56dca5c54d4d40b2553ee737dab0ca4e8b53c4471afc035227b5b44dfa4824747a7f01ad733173536f7da6fbbb + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -5276,13 +5739,6 @@ __metadata: languageName: node linkType: hard -"text-table@npm:^0.2.0": - version: 0.2.0 - resolution: "text-table@npm:0.2.0" - checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a - languageName: node - linkType: hard - "thirty-two@npm:^1.0.2": version: 1.0.2 resolution: "thirty-two@npm:1.0.2" @@ -5356,12 +5812,12 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.0.1": - version: 1.3.0 - resolution: "ts-api-utils@npm:1.3.0" +"ts-api-utils@npm:^2.1.0": + version: 2.1.0 + resolution: "ts-api-utils@npm:2.1.0" peerDependencies: - typescript: ">=4.2.0" - checksum: c746ddabfdffbf16cb0b0db32bb287236a19e583057f8649ee7c49995bb776e1d3ef384685181c11a1a480369e022ca97512cb08c517b2d2bd82c83754c97012 + typescript: ">=4.8.4" + checksum: 5b1ef89105654d93d67582308bd8dfe4bbf6874fccbcaa729b08fbb00a940fd4c691ca6d0d2b18c3c70878d9a7e503421b7cc473dbc3d0d54258b86401d4b15d languageName: node linkType: hard @@ -5397,6 +5853,15 @@ __metadata: languageName: node linkType: hard +"type-check@npm:~0.3.2": + version: 0.3.2 + resolution: "type-check@npm:0.3.2" + dependencies: + prelude-ls: ~1.1.2 + checksum: dd3b1495642731bc0e1fc40abe5e977e0263005551ac83342ecb6f4f89551d106b368ec32ad3fb2da19b3bd7b2d1f64330da2ea9176d8ddbfe389fb286eb5124 + languageName: node + linkType: hard + "type-fest@npm:^0.20.2": version: 0.20.2 resolution: "type-fest@npm:0.20.2" @@ -5420,23 +5885,47 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.8.3": - version: 5.8.3 - resolution: "typescript@npm:5.8.3" +"typescript-eslint@npm:^8.41.0": + version: 8.41.0 + resolution: "typescript-eslint@npm:8.41.0" + dependencies: + "@typescript-eslint/eslint-plugin": 8.41.0 + "@typescript-eslint/parser": 8.41.0 + "@typescript-eslint/typescript-estree": 8.41.0 + "@typescript-eslint/utils": 8.41.0 + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 9205dd0a150991d1b3efb08e8f6b46c04bae73f8221b969a51b59e738c66a422e8811c3cb34c0065ad2cc92b58f9eab311cc2ed2f3f9b1b34108a4c60749bce4 + languageName: node + linkType: hard + +"typescript@npm:^5.9.2": + version: 5.9.2 + resolution: "typescript@npm:5.9.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: cb1d081c889a288b962d3c8ae18d337ad6ee88a8e81ae0103fa1fecbe923737f3ba1dbdb3e6d8b776c72bc73bfa6d8d850c0306eed1a51377d2fccdfd75d92c4 + checksum: f619cf6773cfe31409279711afd68cdf0859780006c50bc2a7a0c3227f85dea89a3b97248846326f3a17dad72ea90ec27cf61a8387772c680b2252fd02d8497b languageName: node linkType: hard -"typescript@patch:typescript@5.8.3#~builtin": - version: 5.8.3 - resolution: "typescript@patch:typescript@npm%3A5.8.3#~builtin::version=5.8.3&hash=5786d5" +"typescript@patch:typescript@^5.9.2#~builtin": + version: 5.9.2 + resolution: "typescript@patch:typescript@npm%3A5.9.2#~builtin::version=5.9.2&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: f1743b6850976b3debf7cbd53d2bc0b67e75d47eb6410db564c8bb475e92a8a48f8a3fcd14d89cf93426835281c31a8f8a94dad90be4dc899279a898532ba97f + checksum: f2327af06fce458b53e02df26b880528636c333bce22e557ff6723cdd0576a2cec75daed37eeb8d330b94fef22be4f19b06d8922793ada5d322b8197efd9391e + languageName: node + linkType: hard + +"uglify-js@npm:^3.1.4": + version: 3.19.3 + resolution: "uglify-js@npm:3.19.3" + bin: + uglifyjs: bin/uglifyjs + checksum: 7ed6272fba562eb6a3149cfd13cda662f115847865c03099e3995a0e7a910eba37b82d4fccf9e88271bb2bcbe505bb374967450f433c17fa27aa36d94a8d0553 languageName: node linkType: hard @@ -5554,6 +6043,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:11.1.0": + version: 11.1.0 + resolution: "uuid@npm:11.1.0" + bin: + uuid: dist/esm/bin/uuid + checksum: 840f19758543c4631e58a29439e51b5b669d5f34b4dd2700b6a1d15c5708c7a6e0c3e2c8c4a2eae761a3a7caa7e9884d00c86c02622ba91137bd3deade6b4b4a + languageName: node + linkType: hard + "uuid@npm:3.1.0": version: 3.1.0 resolution: "uuid@npm:3.1.0" @@ -5563,15 +6061,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^11.1.0": - version: 11.1.0 - resolution: "uuid@npm:11.1.0" - bin: - uuid: dist/esm/bin/uuid - checksum: 840f19758543c4631e58a29439e51b5b669d5f34b4dd2700b6a1d15c5708c7a6e0c3e2c8c4a2eae761a3a7caa7e9884d00c86c02622ba91137bd3deade6b4b4a - languageName: node - linkType: hard - "uuid@npm:^3.3.2": version: 3.4.0 resolution: "uuid@npm:3.4.0" @@ -5647,6 +6136,17 @@ __metadata: languageName: node linkType: hard +"which@npm:^1.1.1": + version: 1.3.1 + resolution: "which@npm:1.3.1" + dependencies: + isexe: ^2.0.0 + bin: + which: ./bin/which + checksum: f2e185c6242244b8426c9df1510e86629192d93c1a986a7d2a591f2c24869e7ffd03d6dac07ca863b2e4c06f59a4cc9916c585b72ee9fa1aa609d0124df15e04 + languageName: node + linkType: hard + "which@npm:^2.0.1": version: 2.0.2 resolution: "which@npm:2.0.2" @@ -5728,6 +6228,20 @@ __metadata: languageName: node linkType: hard +"word-wrap@npm:~1.2.3": + version: 1.2.5 + resolution: "word-wrap@npm:1.2.5" + checksum: f93ba3586fc181f94afdaff3a6fef27920b4b6d9eaefed0f428f8e07adea2a7f54a5f2830ce59406c8416f033f86902b91eb824072354645eea687dff3691ccb + languageName: node + linkType: hard + +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 2a44b2788165d0a3de71fd517d4880a8e20ea3a82c080ce46e294f0b68b69a2e49cff5f99c600e275c698a90d12c5ea32aff06c311f0db2eb3f1201f3e7b2a04 + languageName: node + linkType: hard + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" @@ -5823,12 +6337,12 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.8.0": - version: 2.8.0 - resolution: "yaml@npm:2.8.0" +"yaml@npm:2.8.1": + version: 2.8.1 + resolution: "yaml@npm:2.8.1" bin: yaml: bin.mjs - checksum: 66f103ca5a2f02dac0526895cc7ae7626d91aa8c43aad6fdcff15edf68b1199be4012140b390063877913441aaa5288fdf57eca30e06268a8282dd741525e626 + checksum: 35b46150d48bc1da2fd5b1521a48a4fa36d68deaabe496f3c3fa9646d5796b6b974f3930a02c4b5aee6c85c860d7d7f79009416724465e835f40b87898c36de4 languageName: node linkType: hard diff --git a/package.json b/package.json index e639f12df0..b1bf8f24b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.7.0", + "version": "1.8.0", "private": true, "engines": { "node": "22" @@ -37,23 +37,26 @@ ] }, "devDependencies": { - "@backstage/cli": "0.32.1", - "@backstage/frontend-test-utils": "^0.3.2", - "@ianvs/prettier-plugin-sort-imports": "4.4.2", - "@manypkg/cli": "0.24.0", + "@backstage/cli": "0.34.1", + "@backstage/frontend-test-utils": "0.3.5", + "@ianvs/prettier-plugin-sort-imports": "4.7.0", + "@manypkg/cli": "0.25.1", "glob": "11.0.3", "husky": "8.0.3", + "jsdom": "^26.1.0", "lint-staged": "15.5.2", "node-gyp": "10.3.1", "sherif": "1.6.1", - "turbo": "2.5.4" + "turbo": "2.5.8" }, "resolutions": { "@types/react": "18.3.23", "@types/react-dom": "18.3.7", "@aws-sdk/util-utf8-browser": "npm:@smithy/util-utf8@~2", "@kubernetes/client-node@npm:0.20.0/jsonpath-plus": "^10.3.0", - "@backstage/backend-dynamic-feature-service@0.7.0": "patch:@backstage/backend-dynamic-feature-service@npm%3A0.7.0#./.yarn/patches/@backstage-backend-dynamic-feature-service-npm-0.7.0-d75453687b.patch" + "@backstage/plugin-permission-backend": "0.7.3", + "@backstage/plugin-catalog-react": "1.20.1", + "@backstage/plugin-auth-node": "0.6.6" }, "jest": { "testTimeout": 20000 diff --git a/packages/app-next/.eslintrc.js b/packages/app-next/.eslintrc.js new file mode 100644 index 0000000000..6f6668b53d --- /dev/null +++ b/packages/app-next/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, { + rules: { + '@backstage/no-top-level-material-ui-4-imports': 'error', + }, +}); diff --git a/packages/app-next/README.md b/packages/app-next/README.md new file mode 100644 index 0000000000..cb857b50a0 --- /dev/null +++ b/packages/app-next/README.md @@ -0,0 +1,42 @@ +# app-next + +## Overview + +This package contains the Red Hat Developer Hub (RHDH) frontend application built using Backstage's new frontend system architecture. The `app-next` package leverages Backstage's new frontend system, which introduces a more modular and extensible architecture compared to the legacy frontend system. This new system is built around the concepts of extensions, plugins, and utility APIs, providing better composability and customization options. + +## Development + +### Primary Development Workflow + +The recommended way to run the new frontend system is using the `backend start:next` command: + +```bash +# from the root of the repo +yarn workspace backend start:next +``` + +### Standalone Development + +You can also run the frontend application independently for development: + +```bash +# from the root of the repo +yarn workspace app-next start +``` + +### Other Available Commands + +- `yarn build` - Build the application for production +- `yarn test` - Run the test suite +- `yarn lint` - Run linting checks +- `yarn clean` - Clean build artifacts + +## Architecture + +This application is built using Backstage's [new frontend system](https://backstage.io/docs/frontend-system/architecture/index), which provides: + +- **Extension-based architecture**: Modular components that can be composed together +- **Plugin system**: Reusable functionality packages +- **Utility APIs**: Shared services and functionality +- **Route management**: Dynamic routing system for plugin navigation +- **Theming and customization**: Flexible styling and branding options diff --git a/packages/app-next/package.json b/packages/app-next/package.json new file mode 100644 index 0000000000..96a93821ad --- /dev/null +++ b/packages/app-next/package.json @@ -0,0 +1,94 @@ +{ + "name": "app-next", + "version": "0.0.23", + "private": true, + "bundled": true, + "backstage": { + "role": "frontend" + }, + "repository": { + "type": "git", + "url": "https://github.com/redhat-developer/rhdh", + "directory": "packages/app-next" + }, + "license": "Apache-2.0", + "files": [ + "dist" + ], + "scripts": { + "build": "EXPERIMENTAL_MODULE_FEDERATION=true backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "start": "backstage-cli package start --config ../../app-config.yaml", + "test": "backstage-cli package test" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "dependencies": { + "@backstage/app-defaults": "1.6.5", + "@backstage/catalog-model": "1.7.5", + "@backstage/cli": "0.34.1", + "@backstage/config": "1.3.3", + "@backstage/core-app-api": "1.18.0", + "@backstage/core-compat-api": "0.5.1", + "@backstage/core-components": "0.17.5", + "@backstage/core-plugin-api": "1.10.9", + "@backstage/frontend-app-api": "0.12.0", + "@backstage/frontend-defaults": "0.3.0", + "@backstage/frontend-dynamic-feature-loader": "0.1.4", + "@backstage/frontend-plugin-api": "0.11.0", + "@backstage/integration-react": "1.2.9", + "@backstage/plugin-app": "0.2.0", + "@backstage/plugin-app-visualizer": "0.1.22", + "@backstage/plugin-auth-react": "0.1.18", + "@backstage/plugin-catalog": "1.31.2", + "@backstage/plugin-catalog-common": "1.1.5", + "@backstage/plugin-catalog-graph": "0.4.22", + "@backstage/plugin-catalog-import": "0.13.4", + "@backstage/plugin-catalog-react": "1.20.1", + "@backstage/plugin-catalog-unprocessed-entities": "0.2.20", + "@backstage/plugin-home": "0.8.11", + "@backstage/plugin-permission-react": "0.4.36", + "@backstage/plugin-scaffolder": "1.34.0", + "@backstage/plugin-scaffolder-react": "1.19.0", + "@backstage/plugin-search": "1.4.29", + "@backstage/plugin-search-common": "1.2.19", + "@backstage/plugin-search-react": "1.9.3", + "@backstage/plugin-user-settings": "0.8.25", + "@backstage/theme": "0.6.8", + "@backstage/ui": "0.7.0", + "@material-ui/core": "4.12.4", + "@material-ui/icons": "4.11.3", + "@material-ui/lab": "4.0.0-alpha.61", + "@octokit/rest": "19.0.13", + "history": "5.0.0", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-router": "6.3.0", + "react-router-dom": "6.30.1", + "react-use": "17.6.0", + "zen-observable": "0.10.0" + }, + "devDependencies": { + "@backstage/test-utils": "1.7.11", + "@testing-library/dom": "9.3.4", + "@testing-library/jest-dom": "6.9.1", + "@testing-library/react": "14.3.1", + "@testing-library/user-event": "14.6.1", + "@types/jquery": "3.3.34", + "@types/react": "18.3.23", + "@types/react-dom": "18.3.7", + "@types/zen-observable": "0.8.0", + "cross-env": "7.0.3" + } +} diff --git a/packages/app-next/public/apple-touch-icon.png b/packages/app-next/public/apple-touch-icon.png new file mode 100644 index 0000000000..c4aaa2605f Binary files /dev/null and b/packages/app-next/public/apple-touch-icon.png differ diff --git a/packages/app-next/public/favicon-96x96.png b/packages/app-next/public/favicon-96x96.png new file mode 100644 index 0000000000..7b87ff4321 Binary files /dev/null and b/packages/app-next/public/favicon-96x96.png differ diff --git a/packages/app-next/public/favicon.ico b/packages/app-next/public/favicon.ico new file mode 100644 index 0000000000..c023bea835 Binary files /dev/null and b/packages/app-next/public/favicon.ico differ diff --git a/packages/app-next/public/favicon.svg b/packages/app-next/public/favicon.svg new file mode 100644 index 0000000000..e72991eab0 --- /dev/null +++ b/packages/app-next/public/favicon.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/app-next/public/index.html b/packages/app-next/public/index.html new file mode 100644 index 0000000000..ecd3a3275d --- /dev/null +++ b/packages/app-next/public/index.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + <%= config.getString('app.title') %> + + + +
+ + diff --git a/packages/app-next/public/robots.txt b/packages/app-next/public/robots.txt new file mode 100644 index 0000000000..7d329b1db3 --- /dev/null +++ b/packages/app-next/public/robots.txt @@ -0,0 +1 @@ +User-agent: * diff --git a/packages/app-next/public/site.webmanifest b/packages/app-next/public/site.webmanifest new file mode 100644 index 0000000000..d9cf52622b --- /dev/null +++ b/packages/app-next/public/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "Developer Hub", + "short_name": "Developer Hub", + "icons": [ + { + "src": "/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file diff --git a/packages/app-next/public/web-app-manifest-192x192.png b/packages/app-next/public/web-app-manifest-192x192.png new file mode 100644 index 0000000000..71b490f7f7 Binary files /dev/null and b/packages/app-next/public/web-app-manifest-192x192.png differ diff --git a/packages/app-next/public/web-app-manifest-512x512.png b/packages/app-next/public/web-app-manifest-512x512.png new file mode 100644 index 0000000000..9c045c0dee Binary files /dev/null and b/packages/app-next/public/web-app-manifest-512x512.png differ diff --git a/packages/app-next/src/App.test.tsx b/packages/app-next/src/App.test.tsx new file mode 100644 index 0000000000..d00e40d327 --- /dev/null +++ b/packages/app-next/src/App.test.tsx @@ -0,0 +1,33 @@ +import { renderWithEffects } from '@backstage/test-utils'; + +jest.setTimeout(30_000); + +describe('App', () => { + it('should render', async () => { + process.env = { + NODE_ENV: 'test', + APP_CONFIG: [ + { + data: { + app: { + title: 'Test', + support: { url: 'http://localhost:7007/support' }, + }, + backend: { baseUrl: 'http://localhost:7007' }, + lighthouse: { + baseUrl: 'http://localhost:3003', + }, + techdocs: { + storageUrl: 'http://localhost:7007/api/techdocs/static/docs', + }, + }, + context: 'test', + }, + ] as any, + }; + + const { default: app } = await import('./App'); + const rendered = await renderWithEffects(app); + expect(rendered.baseElement).toBeInTheDocument(); + }); +}); diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx new file mode 100644 index 0000000000..9b6797121f --- /dev/null +++ b/packages/app-next/src/App.tsx @@ -0,0 +1,22 @@ +import { createApp } from '@backstage/frontend-defaults'; +import appVisualizerPlugin from '@backstage/plugin-app-visualizer'; +import catalogPlugin from '@backstage/plugin-catalog/alpha'; +import homePlugin from '@backstage/plugin-home/alpha'; +import scaffolderPlugin from '@backstage/plugin-scaffolder/alpha'; +import searchPlugin from '@backstage/plugin-search/alpha'; +import userSettingsPlugin from '@backstage/plugin-user-settings/alpha'; +import { dynamicFrontendFeaturesLoader } from '@backstage/frontend-dynamic-feature-loader'; + +const app = createApp({ + features: [ + appVisualizerPlugin, + catalogPlugin, + scaffolderPlugin, + searchPlugin, + homePlugin, + userSettingsPlugin, + dynamicFrontendFeaturesLoader() + ], +}); + +export default app.createRoot(); diff --git a/packages/app-next/src/index.tsx b/packages/app-next/src/index.tsx new file mode 100644 index 0000000000..ece7196ce0 --- /dev/null +++ b/packages/app-next/src/index.tsx @@ -0,0 +1,6 @@ +import '@backstage/cli/asset-types'; +import ReactDOM from 'react-dom/client'; +import app from './App'; +import '@backstage/ui/css/styles.css'; + +ReactDOM.createRoot(document.getElementById('root')!).render(app); diff --git a/packages/app-next/src/setupTests.ts b/packages/app-next/src/setupTests.ts new file mode 100644 index 0000000000..8f2609b7b3 --- /dev/null +++ b/packages/app-next/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/packages/app/config.d.ts b/packages/app/config.d.ts index 4597ac604e..97506684bd 100644 --- a/packages/app/config.d.ts +++ b/packages/app/config.d.ts @@ -95,6 +95,16 @@ export interface Config { * @visibility frontend */ title: string; + /** + * Optional translation key for the title. + * @visibility frontend + */ + titleKey?: string; + /** + * The roles associated with the quickstart. + * @visibility frontend + */ + roles?: Array; /** * Optional icon for quickstart. * @visibility frontend @@ -105,6 +115,11 @@ export interface Config { * @visibility frontend */ description: string; + /** + * Optional translation key for the description. + * @visibility frontend + */ + descriptionKey?: string; /** * Optional action item for quickstart. * @visibility frontend @@ -115,6 +130,11 @@ export interface Config { * @visibility frontend */ text: string; + /** + * Optional translation key for the action text. + * @visibility frontend + */ + textKey?: string; /** * Action item link. * @visibility frontend @@ -238,6 +258,11 @@ export interface Config { icon: string; importName?: string; }[]; + translationResources?: { + module?: string; + importName: string; + ref?: string; + }[]; }; }; }; @@ -253,12 +278,68 @@ export interface Config { includeTransitiveGroupOwnership?: boolean; /** - * Allows you to customize RHDH Metadata card + * Allows you to customize RHDH Metadata card information * @deepVisibility frontend */ buildInfo?: { + /** + * Allows setting a title for the build information card + * @visibility frontend + */ title: string; + /** + * Optional translation key for the title. + * @visibility frontend + */ + titleKey?: string; + /** + * Allows setting a content for the build information card + * @visibility frontend + */ card: { [key: string]: string }; - full?: boolean; + /** + * Allows setting if the default build information (RHDH Version, Backstage Version, etc.) should be overridden + * Contents will be overridden if not set to false + * @default true + * @visibility frontend + */ + overrideBuildInfo?: boolean; + }; + + /** + * Internationalization (i18n) settings for the app + * Allows configuring supported languages + * @deepVisibility frontend + */ + i18n?: { + /** + * Allows listing the languages the app will support + * @visibility frontend + */ + locales: string[]; + /** + * Allows setting a default language for the app + * Will be set to `en` if not specified + * @default en + * @visibility frontend + */ + defaultLocale?: string; + /** + * Allows listing of paths to JSON files that contain translation overrides. + * These overrides let you replace or extend the default translations provided by plugins. + * @visibility frontend + */ + overrides?: string[]; + }; + /** + * Configuration options for your user settings. + * @deepVisibility frontend + */ + userSettings?: { + /** + * The persistence mode for user settings. + * @visibility frontend + */ + persistence: 'browser' | 'database'; }; } diff --git a/packages/app/package.json b/packages/app/package.json index d039390084..8dc89f5bc0 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -8,7 +8,7 @@ }, "scripts": { "start": "janus-cli package start", - "build": "janus-cli package build", + "build": "janus-cli package build && node ../../scripts/generate-index-template.mjs", "clean": "backstage-cli package clean", "test": "backstage-cli package test --passWithNoTests --coverage", "lint:check": "backstage-cli package lint", @@ -18,34 +18,36 @@ "prettier:fix": "prettier --ignore-unknown --write ." }, "dependencies": { - "@backstage-community/plugin-rbac-common": "1.18.0", - "@backstage/app-defaults": "1.6.2", - "@backstage/catalog-model": "1.7.4", - "@backstage/config": "1.3.2", - "@backstage/core-app-api": "1.17.0", - "@backstage/core-components": "0.17.2", - "@backstage/core-plugin-api": "1.10.7", - "@backstage/integration-react": "1.2.7", - "@backstage/plugin-api-docs": "0.12.7", - "@backstage/plugin-catalog": "1.30.0", - "@backstage/plugin-catalog-common": "1.1.4", - "@backstage/plugin-catalog-graph": "0.4.19", - "@backstage/plugin-catalog-import": "0.13.0", - "@backstage/plugin-org": "0.6.39", - "@backstage/plugin-permission-react": "0.4.34", - "@backstage/plugin-scaffolder": "1.31.0", - "@backstage/plugin-scaffolder-react": "1.16.0", - "@backstage/plugin-search": "1.4.26", - "@backstage/plugin-search-react": "1.9.0", - "@backstage/plugin-user-settings": "0.8.22", - "@backstage/theme": "0.6.6", + "@backstage-community/plugin-rbac-common": "1.20.0", + "@backstage/app-defaults": "1.6.5", + "@backstage/catalog-model": "1.7.5", + "@backstage/config": "1.3.3", + "@backstage/core-app-api": "1.18.0", + "@backstage/core-components": "0.17.5", + "@backstage/core-plugin-api": "1.10.9", + "@backstage/integration-react": "1.2.9", + "@backstage/plugin-api-docs": "0.12.10", + "@backstage/plugin-catalog": "1.31.2", + "@backstage/plugin-catalog-common": "1.1.5", + "@backstage/plugin-catalog-graph": "0.4.22", + "@backstage/plugin-catalog-import": "0.13.4", + "@backstage/plugin-catalog-react": "1.20.1", + "@backstage/plugin-org": "0.6.43", + "@backstage/plugin-permission-react": "0.4.36", + "@backstage/plugin-scaffolder": "1.34.0", + "@backstage/plugin-scaffolder-react": "1.19.0", + "@backstage/plugin-search": "1.4.29", + "@backstage/plugin-search-react": "1.9.3", + "@backstage/plugin-user-settings": "0.8.25", + "@backstage/theme": "0.6.8", + "@backstage/ui": "0.7.0", "@emotion/react": "11.14.0", "@emotion/styled": "11.14.1", - "@internal/plugin-dynamic-plugins-info": "*", "@mui/icons-material": "5.18.0", "@mui/material": "5.18.0", "@mui/styled-engine": "5.18.0", - "@red-hat-developer-hub/backstage-plugin-theme": "0.9.1", + "@red-hat-developer-hub/backstage-plugin-theme": "0.10.1", + "@red-hat-developer-hub/backstage-plugin-translations": "0.0.2", "@red-hat-developer-hub/plugin-utils": "1.0.0", "@scalprum/core": "0.8.3", "@scalprum/react-core": "0.9.5", @@ -54,15 +56,15 @@ "react-dom": "18.3.1", "react-router-dom": "6.30.1", "react-use": "17.6.0", - "tss-react": "4.9.18" + "tss-react": "4.9.19" }, "devDependencies": { - "@backstage/cli": "0.32.1", - "@backstage/test-utils": "1.7.8", + "@backstage/cli": "0.34.1", + "@backstage/test-utils": "1.7.11", "@janus-idp/cli": "3.6.1", - "@scalprum/react-test-utils": "0.2.6", + "@scalprum/react-test-utils": "0.2.7", "@testing-library/dom": "9.3.4", - "@testing-library/jest-dom": "6.6.3", + "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "14.3.1", "@testing-library/react-hooks": "8.0.1", "@testing-library/user-event": "14.6.1", @@ -70,7 +72,7 @@ "@types/react": "18.3.23", "@types/react-dom": "18.3.7", "prettier": "3.6.2", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "browserslist": { "production": [ diff --git a/packages/app/public/learning-paths/data.json b/packages/app/public/learning-paths/data.json index b7d72d3c11..617d65e278 100644 --- a/packages/app/public/learning-paths/data.json +++ b/packages/app/public/learning-paths/data.json @@ -152,9 +152,9 @@ { "paths": 3, "minutes": 30, - "description": "In this learning path, you will set up options for your Jupyter notebook server and select your PyTorch preferences,\u00a0 then explore the dataset you'll use to create your model. Finally, you will learn how to build, train, and run your PyTorch model.", + "description": "Learn how to create and train PyTorch models using Red Hat OpenShift AI platform. This hands-on tutorial covers setting up PyTorch workbenches, developing machine learning models, and leveraging GPU acceleration for efficient training.", "label": "How to create a PyTorch model", - "url": "https://developers.redhat.com/learn/openshift-data-science/how-create-pytorch-model" + "url": "https://developers.redhat.com/articles/2024/05/02/model-training-red-hat-openshift-ai#model_training" }, { "paths": 3, diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index d8f46ca9a5..6be8d0c837 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -1,14 +1,9 @@ import GlobalStyles from '@mui/material/GlobalStyles'; import { apis } from './apis'; -import { StaticPlugins } from './components/DynamicRoot/DynamicRoot'; import ScalprumRoot from './components/DynamicRoot/ScalprumRoot'; import { DefaultMainMenuItems } from './consts'; -// Statically integrated frontend plugins -const { dynamicPluginsInfoPlugin, ...dynamicPluginsInfoPluginModule } = - await import('@internal/plugin-dynamic-plugins-info'); - // The base UI configuration, these values can be overridden by values // specified in external configuration files const baseFrontendConfig = { @@ -17,54 +12,11 @@ const baseFrontendConfig = { dynamicPlugins: { frontend: { 'default.main-menu-items': DefaultMainMenuItems, - // please keep this in sync with plugins/dynamic-plugins-info/app-config.janus-idp.yaml - 'internal.plugin-dynamic-plugins-info': { - appIcons: [ - { name: 'pluginsInfoIcon', importName: 'PluginsInfoIcon' }, - { name: 'adminIcon', importName: 'AdminIcon' }, - ], - dynamicRoutes: [ - { - path: '/extensions', - importName: 'DynamicPluginsInfoPage', - menuItem: { text: 'Plugins', icon: 'pluginsInfoIcon' }, - }, - ], - mountPoints: [ - { - mountPoint: 'internal.plugins/tab', - importName: 'DynamicPluginsInfoContent', - config: { - path: 'installed', - title: 'Installed', - }, - }, - ], - menuItems: { - admin: { - title: 'Administration', - icon: 'adminIcon', - }, - extensions: { - parent: 'admin', - title: 'Extensions', - icon: 'pluginsInfoIcon', - }, - }, - }, }, }, }, }; -// The map of static plugins by package name -const staticPlugins: StaticPlugins = { - 'internal.plugin-dynamic-plugins-info': { - plugin: dynamicPluginsInfoPlugin, - module: dynamicPluginsInfoPluginModule, - }, -}; - const AppRoot = () => ( <> @@ -72,7 +24,6 @@ const AppRoot = () => ( apis={apis} afterInit={() => import('./components/AppBase')} baseFrontendConfig={baseFrontendConfig} - plugins={staticPlugins} /> ); diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index 4d304edac3..125c7dbd56 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -1,17 +1,26 @@ -import { OAuth2 } from '@backstage/core-app-api'; +import { OAuth2, WebStorage } from '@backstage/core-app-api'; import { AnyApiFactory, + bitbucketAuthApiRef, configApiRef, createApiFactory, discoveryApiRef, + errorApiRef, + fetchApiRef, + githubAuthApiRef, + gitlabAuthApiRef, identityApiRef, + microsoftAuthApiRef, oauthRequestApiRef, + storageApiRef, } from '@backstage/core-plugin-api'; import { ScmAuth, + scmAuthApiRef, ScmIntegrationsApi, scmIntegrationsApiRef, } from '@backstage/integration-react'; +import { UserSettingsStorage } from '@backstage/plugin-user-settings'; import { auth0AuthApiRef, @@ -24,12 +33,57 @@ import { } from './api/LearningPathApiClient'; export const apis: AnyApiFactory[] = [ + createApiFactory({ + api: storageApiRef, + deps: { + discoveryApi: discoveryApiRef, + errorApi: errorApiRef, + fetchApi: fetchApiRef, + identityApi: identityApiRef, + configApi: configApiRef, + }, + factory: deps => { + const persistence = + deps.configApi.getOptionalString('userSettings.persistence') ?? + 'database'; + return persistence === 'browser' + ? WebStorage.create(deps) + : UserSettingsStorage.create(deps); + }, + }), createApiFactory({ api: scmIntegrationsApiRef, deps: { configApi: configApiRef }, factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), }), - ScmAuth.createDefaultApiFactory(), + createApiFactory({ + api: scmAuthApiRef, + deps: { + github: githubAuthApiRef, + gitlab: gitlabAuthApiRef, + azure: microsoftAuthApiRef, + bitbucket: bitbucketAuthApiRef, + configApi: configApiRef, + }, + factory: ({ github, gitlab, azure, bitbucket, configApi }) => { + const providers = [ + { key: 'github', ref: github, factory: ScmAuth.forGithub }, + { key: 'gitlab', ref: gitlab, factory: ScmAuth.forGitlab }, + { key: 'azure', ref: azure, factory: ScmAuth.forAzure }, + { key: 'bitbucket', ref: bitbucket, factory: ScmAuth.forBitbucket }, + ]; + + const scmAuths = providers.flatMap(({ key, ref, factory }) => { + const configs = configApi.getOptionalConfigArray(`integrations.${key}`); + if (!configs?.length) { + return [factory(ref)]; + } + return configs.map(c => factory(ref, { host: c.getString('host') })); + }); + + return ScmAuth.merge(...scmAuths); + }, + }), createApiFactory({ api: learningPathApiRef, deps: { diff --git a/packages/app/src/bootstrap.tsx b/packages/app/src/bootstrap.tsx index 0d3cae1d0d..4671ef93b1 100644 --- a/packages/app/src/bootstrap.tsx +++ b/packages/app/src/bootstrap.tsx @@ -1,5 +1,7 @@ import ReactDOM from 'react-dom/client'; +import '@backstage/ui/css/styles.css'; + import App from './App'; ReactDOM.createRoot(document.getElementById('root')!).render(); diff --git a/packages/app/src/build-metadata.json b/packages/app/src/build-metadata.json index 336c4f2e0a..27c9b0b7d9 100644 --- a/packages/app/src/build-metadata.json +++ b/packages/app/src/build-metadata.json @@ -1,8 +1,9 @@ { "title": "RHDH Metadata", + "titleKey": "app.userSettings.infoCard.title", "card": { - "RHDH Version": "1.7.0", - "Backstage Version": "1.39.1", - "Last Commit": "repo @ 2025-06-05T17:33:46Z" + "RHDH Version": "1.8.0", + "Backstage Version": "1.42.5", + "Last Commit": "repo @ 2025-09-03T18:03:57Z" } } \ No newline at end of file diff --git a/packages/app/src/components/AppBase/AppBase.tsx b/packages/app/src/components/AppBase/AppBase.tsx index 3ad65fb0c8..a73e3ec109 100644 --- a/packages/app/src/components/AppBase/AppBase.tsx +++ b/packages/app/src/components/AppBase/AppBase.tsx @@ -24,6 +24,7 @@ import DynamicRootContext from '@red-hat-developer-hub/plugin-utils'; import getDynamicRootConfig from '../../utils/dynamicUI/getDynamicRootConfig'; import { entityPage } from '../catalog/EntityPage'; +import { CustomCatalogFilters } from '../catalog/filters/CustomCatalogFilters'; import { LearningPaths } from '../learningPaths/LearningPathsPage'; import { Root } from '../Root'; import { ApplicationListener } from '../Root/ApplicationListener'; @@ -86,7 +87,11 @@ const AppBase = () => { + } + /> } /> { scaffolderFieldExtensions } /> + ); diff --git a/packages/app/src/components/DynamicRoot/DynamicRoot.tsx b/packages/app/src/components/DynamicRoot/DynamicRoot.tsx index be35d0329d..4e394dccf8 100644 --- a/packages/app/src/components/DynamicRoot/DynamicRoot.tsx +++ b/packages/app/src/components/DynamicRoot/DynamicRoot.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-shadow */ -import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { createApp } from '@backstage/app-defaults'; import { BackstageApp, MultipleAnalyticsApi } from '@backstage/core-app-api'; @@ -16,8 +16,14 @@ import { IdentityApi, identityApiRef, } from '@backstage/core-plugin-api'; +import { + appLanguageApiRef, + translationApiRef, + TranslationResource, +} from '@backstage/core-plugin-api/alpha'; import { useThemes } from '@red-hat-developer-hub/backstage-plugin-theme'; +import { I18nextTranslationApi } from '@red-hat-developer-hub/backstage-plugin-translations'; import DynamicRootContext, { ComponentRegistry, DynamicRootConfig, @@ -32,6 +38,7 @@ import DynamicRootContext, { import { AppsConfig } from '@scalprum/core'; import { useScalprum } from '@scalprum/react-core'; +import { TranslationConfig } from '../../types/types'; import bindAppRoutes from '../../utils/dynamicUI/bindAppRoutes'; import extractDynamicConfig, { configIfToCallable, @@ -39,7 +46,10 @@ import extractDynamicConfig, { DynamicRoute, } from '../../utils/dynamicUI/extractDynamicConfig'; import initializeRemotePlugins from '../../utils/dynamicUI/initializeRemotePlugins'; -import { catalogTranslations } from '../catalog/translations/catalog'; +import { getDefaultLanguage } from '../../utils/language/language'; +import { fetchOverrideTranslations } from '../../utils/translations/fetchOverrideTranslations'; +import { staticTranslationConfigs } from '../../utils/translations/staticTranslationConfigs'; +import { processAllTranslationResources } from '../../utils/translations/translationResourceProcessor'; import { MenuIcon } from '../Root/MenuIcon'; import CommonIcons from './CommonIcons'; import defaultAppComponents from './defaultAppComponents'; @@ -59,7 +69,8 @@ export type RemotePlugins = { | ((config: DynamicRootConfig) => React.ReactNode); } | AnyApiFactory - | AnalyticsApiClass; + | AnalyticsApiClass + | TranslationResource; }; }; }; @@ -89,6 +100,8 @@ export const DynamicRoot = ({ dynamicPlugins, staticPluginStore = {}, scalprumConfig, + translationConfig, + baseUrl, }: { afterInit: () => Promise<{ default: React.ComponentType }>; // Static APIs @@ -96,6 +109,8 @@ export const DynamicRoot = ({ dynamicPlugins: DynamicPluginConfig; staticPluginStore?: StaticPlugins; scalprumConfig: AppsConfig; + baseUrl: string; + translationConfig?: TranslationConfig; }) => { const app = useRef(); const [ChildComponent, setChildComponent] = useState< @@ -127,6 +142,7 @@ export const DynamicRoot = ({ techdocsAddons, themes: pluginThemes, signInPages, + translationResources, } = extractDynamicConfig(dynamicPlugins); const requiredModules = [ ...pluginModules.map(({ scope, module }) => ({ @@ -169,6 +185,10 @@ export const DynamicRoot = ({ scope, module, })), + ...(translationResources?.map(({ scope, module }) => ({ + scope, + module, + })) ?? []), ]; const staticPlugins = Object.keys(staticPluginStore).reduce( @@ -423,14 +443,14 @@ export const DynamicRoot = ({ }, []); const entityTabOverrides = entityTabs.reduce( - (acc, { path, title, mountPoint, scope, priority }) => { + (acc, { path, title, titleKey, mountPoint, scope, priority }) => { if (acc[path]) { // eslint-disable-next-line no-console console.warn( `Plugin ${scope} is not configured properly: a tab has already been configured for "${path}", ignoring entry with title: "${title}" and mountPoint: "${mountPoint}"`, ); } else { - acc[path] = { title, mountPoint, priority }; + acc[path] = { title, titleKey, mountPoint, priority }; } return acc; }, @@ -522,6 +542,31 @@ export const DynamicRoot = ({ ) .find(candidate => candidate !== undefined); + let overrideTranslations: Record< + string, + Record> + > = {}; + + overrideTranslations = await fetchOverrideTranslations(baseUrl); + + // Process dynamic translation resources + const dynamicTranslationConfigs = + translationResources?.map(({ scope, module, importName, ref }) => ({ + scope, + module, + importName, + ref, + })) || []; + + // Process static translation resources using imported configuration + const { allResources: allTranslationResources, allRefs: translationRefs } = + processAllTranslationResources( + dynamicTranslationConfigs, + staticTranslationConfigs, + allPlugins, + overrideTranslations, + ); + if (!app.current) { const filteredStaticThemes = themes.filter( theme => @@ -532,12 +577,26 @@ export const DynamicRoot = ({ const filteredStaticApis = staticApis.filter( api => !remoteApis.some(remoteApi => remoteApi.api.id === api.api.id), ); + app.current = createApp({ __experimentalTranslations: { - availableLanguages: ['en'], - resources: [catalogTranslations], + availableLanguages: translationConfig?.locales ?? ['en'], + defaultLanguage: getDefaultLanguage(translationConfig), }, - apis: [...filteredStaticApis, ...remoteApis, ...multipleAnalyticsApi], + apis: [ + ...filteredStaticApis, + ...remoteApis, + ...multipleAnalyticsApi, + createApiFactory({ + api: translationApiRef, + deps: { languageApi: appLanguageApiRef }, + factory: ({ languageApi }) => + I18nextTranslationApi.create({ + languageApi, + resources: allTranslationResources, + }) as any, + }), + ], bindRoutes({ bind }) { bindAppRoutes(bind, resolvedRouteBindingTargets, routeBindings); }, @@ -567,7 +626,7 @@ export const DynamicRoot = ({ dynamicRootConfig.scaffolderFieldExtensions = scaffolderFieldExtensionComponents; dynamicRootConfig.techdocsAddons = techdocsAddonComponents; - + dynamicRootConfig.translationResources = allTranslationResources; // make the dynamic UI configuration available to DynamicRootContext consumers setComponentRegistry({ AppProvider: app.current.getProvider(), @@ -579,6 +638,7 @@ export const DynamicRoot = ({ providerSettings, scaffolderFieldExtensions: scaffolderFieldExtensionComponents, techdocsAddons: techdocsAddonComponents, + translationRefs, }); afterInit().then(({ default: Component }) => { setChildComponent(() => Component); @@ -592,6 +652,8 @@ export const DynamicRoot = ({ staticApis, staticPluginStore, themes, + translationConfig, + baseUrl, ]); useEffect(() => { diff --git a/packages/app/src/components/DynamicRoot/ScalprumRoot.tsx b/packages/app/src/components/DynamicRoot/ScalprumRoot.tsx index 562efc4c44..8bbe9b100c 100644 --- a/packages/app/src/components/DynamicRoot/ScalprumRoot.tsx +++ b/packages/app/src/components/DynamicRoot/ScalprumRoot.tsx @@ -10,6 +10,7 @@ import { DynamicRootConfig } from '@red-hat-developer-hub/plugin-utils'; import { AppsConfig } from '@scalprum/core'; import { ScalprumProvider } from '@scalprum/react-core'; +import { TranslationConfig } from '../../types/types'; import { DynamicPluginConfig } from '../../utils/dynamicUI/extractDynamicConfig'; import overrideBaseUrlConfigs from '../../utils/dynamicUI/overrideBaseUrlConfigs'; import { DynamicRoot, StaticPlugins } from './DynamicRoot'; @@ -36,6 +37,7 @@ const ScalprumRoot = ({ dynamicPlugins: DynamicPluginConfig; baseUrl: string; scalprumConfig?: AppsConfig; + translationConfig?: TranslationConfig; }> => { const appConfig = overrideBaseUrlConfigs(await defaultConfigLoader()); const reader = ConfigReader.fromConfigs([ @@ -44,32 +46,40 @@ const ScalprumRoot = ({ ]); const baseUrl = reader.getString('backend.baseUrl'); const dynamicPlugins = reader.get('dynamicPlugins'); + let scalprumConfig: AppsConfig = {}; + let translationConfig: TranslationConfig | undefined = undefined; try { - const scalprumConfig: AppsConfig = await fetch( - `${baseUrl}/api/scalprum/plugins`, - ).then(r => r.json()); - return { - dynamicPlugins, - baseUrl, - scalprumConfig, - }; + scalprumConfig = await fetch(`${baseUrl}/api/scalprum/plugins`).then( + r => r.json(), + ); } catch (err) { // eslint-disable-next-line no-console console.warn( `Failed to fetch scalprum configuration: ${JSON.stringify(err)}`, ); - return { - dynamicPlugins, - baseUrl, - scalprumConfig: {}, - }; } + try { + translationConfig = reader.get('i18n'); + } catch (err) { + // eslint-disable-next-line no-console + console.warn( + `Failed to load i18n configuration: either not provided or invalid. + ${JSON.stringify(err)}`, + ); + } + return { + dynamicPlugins, + baseUrl, + scalprumConfig, + translationConfig, + }; }, ); if (loading && !value) { return ; } - const { dynamicPlugins, baseUrl, scalprumConfig } = value || {}; + const { dynamicPlugins, baseUrl, scalprumConfig, translationConfig } = + value || {}; const scalprumApiHolder = { dynamicRootConfig: { dynamicRoutes: [], @@ -79,6 +89,7 @@ const ScalprumRoot = ({ scaffolderFieldExtensions: [], techdocsAddons: [], providerSettings: [], + translationRefs: [], } as DynamicRootConfig, }; return ( @@ -105,6 +116,8 @@ const ScalprumRoot = ({ dynamicPlugins={dynamicPlugins ?? {}} staticPluginStore={plugins} scalprumConfig={scalprumConfig ?? {}} + translationConfig={translationConfig} + baseUrl={baseUrl as string} /> ); diff --git a/packages/app/src/components/ErrorPages/ErrorPage.tsx b/packages/app/src/components/ErrorPages/ErrorPage.tsx index 709de8bee3..e427c61c27 100644 --- a/packages/app/src/components/ErrorPages/ErrorPage.tsx +++ b/packages/app/src/components/ErrorPages/ErrorPage.tsx @@ -1,21 +1,20 @@ +import { ComponentProps } from 'react'; + +import { + CopyTextButton, + type ErrorPage as BsErrorPage, +} from '@backstage/core-components'; + import Box, { BoxProps } from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; +import { ContactSupportButton } from './errorButtons/ContactSupportButton'; +import { GoBackButton } from './errorButtons/GoBackButton'; import { CollaborationIllustration } from './illustrations/collaboration/collaboration'; -interface ErrorPageProps { - /** The title to display. */ - title: React.ReactNode | string; - /** The message to display. */ - message: React.ReactNode | string; - /** Additional actions to display below the message. */ - actions?: React.ReactNode; - /** Additional content to display below the message and above the actions. */ - children?: React.ReactNode; - /** The component to use for the illustration. */ - Illustration?: React.ComponentType>; -} +/** Private type duplicated from `@backstage/core-components` */ +export type ErrorPageProps = ComponentProps; const ErrorPageGutters = { xs: 3, @@ -24,17 +23,34 @@ const ErrorPageGutters = { xl: 12, }; +const getIllustrationForStatus = (status?: string) => { + switch (status) { + default: + return CollaborationIllustration; + } +}; + +const IllustrationForStatus = ({ + status, + ...props +}: { status?: string } & BoxProps<'img'>) => { + const Illustration = getIllustrationForStatus(status); + return ; +}; + export const ErrorPage = ({ - title, - message, - actions, - Illustration = CollaborationIllustration, - children, + status, + statusMessage, + additionalInfo, + supportUrl, + stack, }: ErrorPageProps) => ( theme.palette.background.default, + borderRadius: theme => theme.shape.borderRadius, // When quickstart drawer is open, adjust margin '.quickstart-drawer-open &': { transition: 'margin-right 0.3s ease', @@ -63,19 +79,46 @@ export const ErrorPage = ({ }} > - {title} + {status} {statusMessage} - {message} + {additionalInfo} - {children} -
{actions}
+ {stack && ( + theme.palette.background.paper, + position: 'relative', + padding: 2, + borderRadius: 2, + }} + > + + {stack} + + + + + + )} + + + {status === '404' && } + +
- ( - - 404 We couldn't find that page - - } - message="The page you are looking for might have been removed, had its name - changed, or is temporarily unavailable." - actions={ - - - - - } - > - {children} - -); +export const NotFoundErrorPage: AppComponents['NotFoundErrorPage'] = () => { + const { t } = useTranslation(); + + return ( + + ); +}; diff --git a/packages/app/src/components/ErrorPages/errorButtons/ContactSupportButton.tsx b/packages/app/src/components/ErrorPages/errorButtons/ContactSupportButton.tsx index f16e195563..13a6ba8030 100644 --- a/packages/app/src/components/ErrorPages/errorButtons/ContactSupportButton.tsx +++ b/packages/app/src/components/ErrorPages/errorButtons/ContactSupportButton.tsx @@ -3,9 +3,17 @@ import { configApiRef, useApi } from '@backstage/core-plugin-api'; import Launch from '@mui/icons-material/Launch'; import Button from '@mui/material/Button'; -export const ContactSupportButton = () => { +import { useTranslation } from '../../../hooks/useTranslation'; + +export const ContactSupportButton = ({ + supportUrl, +}: { + supportUrl?: string; +}) => { const configApi = useApi(configApiRef); - const supportUrl = + const { t } = useTranslation(); + const finalSupportUrl = + supportUrl ?? configApi.getOptionalString('app.support.url') ?? 'https://access.redhat.com/documentation/red_hat_developer_hub'; @@ -14,12 +22,12 @@ export const ContactSupportButton = () => { variant="text" color="primary" component="a" - href={supportUrl} + href={finalSupportUrl} target="_blank" rel="noopener noreferrer" endIcon={} > - Contact support + {t('app.errors.contactSupport')} ); }; diff --git a/packages/app/src/components/ErrorPages/errorButtons/GoBackButton.tsx b/packages/app/src/components/ErrorPages/errorButtons/GoBackButton.tsx index c34bc0afe4..c367ff052e 100644 --- a/packages/app/src/components/ErrorPages/errorButtons/GoBackButton.tsx +++ b/packages/app/src/components/ErrorPages/errorButtons/GoBackButton.tsx @@ -2,8 +2,11 @@ import { useNavigate } from 'react-router-dom'; import Button from '@mui/material/Button'; +import { useTranslation } from '../../../hooks/useTranslation'; + export const GoBackButton = () => { const navigate = useNavigate(); + const { t } = useTranslation(); return window.history.length > 2 ? ( ) : null; }; diff --git a/packages/app/src/components/Root/ApplicationHeaders.tsx b/packages/app/src/components/Root/ApplicationHeaders.tsx index 122c736bc0..a752fec018 100644 --- a/packages/app/src/components/Root/ApplicationHeaders.tsx +++ b/packages/app/src/components/Root/ApplicationHeaders.tsx @@ -1,4 +1,10 @@ -import React, { useContext, useMemo } from 'react'; +import { + ComponentType, + CSSProperties, + PropsWithChildren, + useContext, + useMemo, +} from 'react'; import { ErrorBoundary } from '@backstage/core-components'; @@ -11,14 +17,14 @@ type Position = 'above-main-content' | 'above-sidebar'; type ApplicationHeaderMountPointConfig = MountPointConfigBase & { position: Position; - layout?: React.CSSProperties; + layout?: CSSProperties; }; type ApplicationHeaderMountPoint = MountPoint & { - Component: React.ComponentType< - React.PropsWithChildren<{ + Component: ComponentType< + PropsWithChildren<{ position: Position; - layout?: React.CSSProperties; + layout?: CSSProperties; }> >; config?: ApplicationHeaderMountPointConfig; diff --git a/packages/app/src/components/Root/ApplicationListener.tsx b/packages/app/src/components/Root/ApplicationListener.tsx index 0f0a0834e6..af3157a5de 100644 --- a/packages/app/src/components/Root/ApplicationListener.tsx +++ b/packages/app/src/components/Root/ApplicationListener.tsx @@ -1,12 +1,12 @@ -import React, { ErrorInfo, useContext } from 'react'; +import { Component, ComponentType, ErrorInfo, useContext } from 'react'; import { ErrorPanel } from '@backstage/core-components'; import DynamicRootContext from '@red-hat-developer-hub/plugin-utils'; -class ErrorBoundary extends React.Component< +class ErrorBoundary extends Component< { - Component: React.ComponentType<{}>; + Component: ComponentType<{}>; }, { error: any } > { @@ -20,37 +20,37 @@ class ErrorBoundary extends React.Component< } componentDidCatch(error: Error, errorInfo: ErrorInfo) { - const { Component } = this.props; - const name = Component.displayName ?? Component.name ?? 'Component'; + const { Component: Comp } = this.props; + const name = Comp.displayName ?? Comp.name ?? 'Component'; // eslint-disable-next-line no-console console.error(`Error in application/listener ${name}: ${error.message}`, { error, errorInfo, - Component, + Component: Comp, }); } render() { - const { Component } = this.props; + const { Component: Comp } = this.props; const { error } = this.state; if (error) { - const name = Component.displayName ?? Component.name ?? 'Component'; + const name = Comp.displayName ?? Comp.name ?? 'Component'; const title = `Error in application/listener ${name}: ${error.message}`; return ; } - return ; + return ; } } export const ApplicationListener = () => { const { mountPoints } = useContext(DynamicRootContext); const listeners = mountPoints['application/listener'] ?? []; - return listeners.map(({ Component }, index) => { + return listeners.map(({ Component: Comp }, index) => { return ( ); }); diff --git a/packages/app/src/components/Root/ApplicationProvider.tsx b/packages/app/src/components/Root/ApplicationProvider.tsx index 0b36adb0bd..35e9e79092 100644 --- a/packages/app/src/components/Root/ApplicationProvider.tsx +++ b/packages/app/src/components/Root/ApplicationProvider.tsx @@ -1,13 +1,21 @@ -import React, { ErrorInfo } from 'react'; +import { + Component, + ComponentType, + ErrorInfo, + PropsWithChildren, + ReactNode, + useContext, + useMemo, +} from 'react'; import { ErrorPanel } from '@backstage/core-components'; import DynamicRootContext from '@red-hat-developer-hub/plugin-utils'; -class ErrorBoundary extends React.Component< +class ErrorBoundary extends Component< { - Component: React.ComponentType<{ children?: React.ReactNode }>; - children: React.ReactNode; + Component: ComponentType<{ children?: ReactNode }>; + children: ReactNode; }, { error: any } > { @@ -21,21 +29,21 @@ class ErrorBoundary extends React.Component< } componentDidCatch(error: Error, errorInfo: ErrorInfo) { - const { Component } = this.props; - const name = Component.displayName ?? Component.name ?? 'Component'; + const { Component: Comp } = this.props; + const name = Comp.displayName ?? Comp.name ?? 'Component'; // eslint-disable-next-line no-console console.error(`Error in application/provider ${name}: ${error.message}`, { error, errorInfo, - Component, + Component: Comp, }); } render() { - const { Component, children } = this.props; + const { Component: Comp, children } = this.props; const { error } = this.state; if (error) { - const name = Component.displayName ?? Component.name ?? 'Component'; + const name = Comp.displayName ?? Comp.name ?? 'Component'; const title = `Error in application/provider ${name}: ${error.message}`; return ( <> @@ -44,27 +52,25 @@ class ErrorBoundary extends React.Component< ); } - return {children}; + return {children}; } } -export const ApplicationProvider = ({ - children, -}: React.PropsWithChildren<{}>) => { - const { mountPoints } = React.useContext(DynamicRootContext); - const providers = React.useMemo( +export const ApplicationProvider = ({ children }: PropsWithChildren<{}>) => { + const { mountPoints } = useContext(DynamicRootContext); + const providers = useMemo( () => mountPoints['application/provider'] ?? [], [mountPoints], ); if (providers.length === 0) { return children; } - return providers.reduceRight((acc, { Component }, index) => { + return providers.reduceRight((acc, { Component: Comp }, index) => { return ( {acc} diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index 5fa8138716..0eeb360f6c 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -18,13 +18,15 @@ import { SidebarSpace, } from '@backstage/core-components'; import { configApiRef, useApi } from '@backstage/core-plugin-api'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { MyGroupsSidebarItem } from '@backstage/plugin-org'; import { usePermission } from '@backstage/plugin-permission-react'; import { SidebarSearchModal } from '@backstage/plugin-search'; +import { searchTranslationRef } from '@backstage/plugin-search/alpha'; import { Settings as SidebarSettings } from '@backstage/plugin-user-settings'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; import { policyEntityCreatePermission } from '@backstage-community/plugin-rbac-common'; -import { AdminIcon } from '@internal/plugin-dynamic-plugins-info'; import AccountCircleOutlinedIcon from '@mui/icons-material/AccountCircleOutlined'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import ExpandMore from '@mui/icons-material/ExpandMore'; @@ -40,6 +42,8 @@ import DynamicRootContext, { ResolvedMenuItem, } from '@red-hat-developer-hub/plugin-utils'; +import { useLanguagePreference } from '../../hooks/useLanguagePreference'; +import { useTranslation } from '../../hooks/useTranslation'; import { ApplicationHeaders } from './ApplicationHeaders'; import { MenuIcon } from './MenuIcon'; import { SidebarLogo } from './SidebarLogo'; @@ -190,17 +194,24 @@ const renderExpandIcon = (expand: boolean) => { ); }; -const getMenuItem = (menuItem: ResolvedMenuItem, isNestedMenuItem = false) => { +const getMenuItem = ( + menuItem: ResolvedMenuItem, + isNestedMenuItem = false, + getMenuText: (item: ResolvedMenuItem) => string, +) => { const menuItemStyle = { paddingLeft: isNestedMenuItem ? '2rem' : '', }; + const translatedText = getMenuText(menuItem); return menuItem.name === 'default.my-group' ? ( ) : ( @@ -208,7 +219,7 @@ const getMenuItem = (menuItem: ResolvedMenuItem, isNestedMenuItem = false) => { key={menuItem.name} icon={renderIcon(menuItem.icon ?? '')} to={menuItem.to ?? ''} - text={menuItem.title} + text={translatedText} style={menuItemStyle} /> ); @@ -245,6 +256,9 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { const [aboveMainContentHeaderHeight, setAboveMainContentHeaderHeight] = useState(0); + const { t: searchT } = useTranslationRef(searchTranslationRef); + const { t: userSettingsT } = useTranslationRef(userSettingsTranslationRef); + useLayoutEffect(() => { if (!aboveSidebarHeaderRef.current) return () => {}; @@ -297,6 +311,15 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { permission: policyEntityCreatePermission, resourceRef: undefined, }); + useLanguagePreference(); + const { t } = useTranslation(); + + const getMenuText = (menuItem: ResolvedMenuItem) => { + if (menuItem.titleKey) { + return t(menuItem.titleKey as any, {}); + } + return menuItem.title; + }; const handleClick = (itemName: string) => { setOpenItems(prevOpenItems => ({ @@ -333,7 +356,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { null} - text={child.title} + text={getMenuText(child)} to={child.to ?? ''} /> )} @@ -377,12 +400,12 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { }} > {child.children && child.children.length === 0 ? ( - getMenuItem(child, true) + getMenuItem(child, true, getMenuText) ) : ( <> handleClick(child.name)} > {child.children!.length > 0 && @@ -407,8 +430,8 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { : menuItems.filter(mi => !mi.name.startsWith('default.')); menuItemArray = isBottomMenuSection - ? menuItemArray.filter(mi => mi.name === 'admin') - : menuItemArray.filter(mi => mi.name !== 'admin'); + ? menuItemArray.filter(mi => mi.name.includes('admin')) + : menuItemArray.filter(mi => !mi.name.includes('admin')); if (isBottomMenuSection && !canDisplayRBACMenuItem && !loadingPermission) { menuItemArray[0].children = menuItemArray[0].children?.filter( @@ -421,12 +444,13 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { const isOpen = openItems[menuItem.name] || false; return ( - {menuItem.children!.length === 0 && getMenuItem(menuItem)} + {menuItem.children!.length === 0 && + getMenuItem(menuItem, false, getMenuText)} {menuItem.children!.length > 0 && ( handleClick(menuItem.name)} > {menuItem.children!.length > 0 && renderExpandIcon(isOpen)} @@ -462,7 +486,11 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { {showLogo && } {showSearch ? ( <> - } to="/search"> + } + to="/search" + > @@ -470,7 +498,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { ) : ( )} - }> + }> {/* Global nav, not org-specific */} {renderMenuItems(true, false)} {/* End global nav */} @@ -495,8 +523,8 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { {showAdministration && ( <> - }> - {renderMenuItems(false, true)} + + {renderMenuItems(true, true)} )} @@ -504,7 +532,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => { <> } > diff --git a/packages/app/src/components/Root/SidebarLogo.test.tsx b/packages/app/src/components/Root/SidebarLogo.test.tsx index 6e836190aa..0336a1a0cf 100644 --- a/packages/app/src/components/Root/SidebarLogo.test.tsx +++ b/packages/app/src/components/Root/SidebarLogo.test.tsx @@ -6,6 +6,7 @@ import { useApi } from '@backstage/core-plugin-api'; import { render } from '@testing-library/react'; import { useAppBarThemedConfig } from '../../hooks/useThemedConfig'; +import { useTranslation } from '../../hooks/useTranslation'; import { SidebarLogo } from './SidebarLogo'; jest.mock('@backstage/core-components', () => ({ @@ -23,7 +24,24 @@ jest.mock('../../hooks/useThemedConfig', () => ({ useAppBarThemedConfig: jest.fn(), })); +jest.mock('../../hooks/useTranslation', () => ({ + useTranslation: jest.fn(), +})); + describe('SidebarLogo', () => { + beforeEach(() => { + // Mock translation function for all tests + (useTranslation as any).mockReturnValue({ + t: jest.fn((key: string) => { + const translations: Record = { + 'sidebar.home': 'Home', + 'sidebar.homeLogo': 'Home logo', + }; + return translations[key] || key; + }), + }); + }); + it('when sidebar is open renders the component with full logo base64 provided by config', () => { (useApi as any).mockReturnValue({ getOptional: jest.fn().mockReturnValue('fullLogoWidth'), @@ -39,7 +57,11 @@ describe('SidebarLogo', () => { const fullLogo = getByTestId('home-logo'); expect(fullLogo).toBeInTheDocument(); - expect(fullLogo).toHaveAttribute('src', 'fullLogoBase64URI'); // Check the expected attribute value + expect(fullLogo).toHaveAttribute('src', 'fullLogoBase64URI'); + expect(fullLogo).toHaveAttribute('alt', 'Home logo'); + + const logoLink = fullLogo.closest('a'); + expect(logoLink).toHaveAttribute('aria-label', 'Home'); }); it('when sidebar is open renders the component with default full logo if config is undefined', () => { @@ -75,6 +97,10 @@ describe('SidebarLogo', () => { const fullLogo = getByTestId('home-logo'); expect(fullLogo).toBeInTheDocument(); expect(fullLogo).toHaveAttribute('src', 'iconLogoBase64URI'); + expect(fullLogo).toHaveAttribute('alt', 'Home logo'); + + const logoLink = fullLogo.closest('a'); + expect(logoLink).toHaveAttribute('aria-label', 'Home'); }); it('when sidebar is closed renders the component with icon logo from default if not provided with config', () => { diff --git a/packages/app/src/components/Root/SidebarLogo.tsx b/packages/app/src/components/Root/SidebarLogo.tsx index fa0e196fe8..899ca3244c 100644 --- a/packages/app/src/components/Root/SidebarLogo.tsx +++ b/packages/app/src/components/Root/SidebarLogo.tsx @@ -6,6 +6,7 @@ import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { makeStyles } from 'tss-react/mui'; import { useAppBarThemedConfig } from '../../hooks/useThemedConfig'; +import { useTranslation } from '../../hooks/useTranslation'; import { LogoFull } from './LogoFull'; import { LogoIcon } from './LogoIcon'; @@ -19,18 +20,15 @@ const LogoRender = ({ base64Logo, DefaultLogo, width, + altText, }: { base64Logo: string | undefined; DefaultLogo: ComponentType>; width: string | number; + altText: string; }) => { return base64Logo ? ( - Home logo + {altText} ) : ( ); @@ -40,6 +38,7 @@ export const SidebarLogo = () => { const { classes } = useStyles(); const { isOpen } = useSidebarOpenState(); + const { t } = useTranslation(); const configApi = useApi(configApiRef); const logoFullBase64URI = useAppBarThemedConfig('app.branding.fullLogo'); @@ -52,18 +51,20 @@ export const SidebarLogo = () => { return (
- + {isOpen ? ( ) : ( )} diff --git a/packages/app/src/components/SignInPage/SignInPage.tsx b/packages/app/src/components/SignInPage/SignInPage.tsx index dbd9f58718..6727b96329 100644 --- a/packages/app/src/components/SignInPage/SignInPage.tsx +++ b/packages/app/src/components/SignInPage/SignInPage.tsx @@ -19,151 +19,161 @@ import { } from '@backstage/core-plugin-api'; import { auth0AuthApiRef, oidcAuthApiRef, samlAuthApiRef } from '../../api'; +import { useTranslation } from '../../hooks/useTranslation'; const DEFAULT_PROVIDER = 'github'; /** + * Creates provider configurations with translated strings + * + * t - Translation function. + * Map of provider configurations. + * * Key: * string - Provider name. * * Value: * SignInProviderConfig - Local sign-in provider configuration. * string - Proxy sign-in provider configuration. - */ -const PROVIDERS = new Map([ - [ - 'auth0', - { - id: 'auth0-auth-provider', - title: 'Auth0', - message: 'Sign in using Auth0', - apiRef: auth0AuthApiRef, - }, - ], - [ - 'atlassian', - { - id: 'atlassian-auth-provider', - title: 'Atlassian', - message: 'Sign in using Atlassian', - apiRef: atlassianAuthApiRef, - }, - ], - [ - 'microsoft', - { - id: 'microsoft-auth-provider', - title: 'Microsoft', - message: 'Sign in using Microsoft', - apiRef: microsoftAuthApiRef, - }, - ], - ['azure-easyauth', 'azure-easyauth'], - [ - 'bitbucket', - { - id: 'bitbucket-auth-provider', - title: 'Bitbucket', - message: 'Sign in using Bitbucket', - apiRef: bitbucketAuthApiRef, - }, - ], - [ - 'bitbucketServer', - { - id: 'bitbucket-server-auth-provider', - title: 'Bitbucket Server', - message: 'Sign in using Bitbucket Server', - apiRef: bitbucketServerAuthApiRef, - }, - ], - ['cfaccess', 'cfaccess'], - [ - 'github', - { - id: 'github-auth-provider', - title: 'GitHub', - message: 'Sign in using GitHub', - apiRef: githubAuthApiRef, - }, - ], - [ - 'gitlab', - { - id: 'gitlab-auth-provider', - title: 'GitLab', - message: 'Sign in using GitLab', - apiRef: gitlabAuthApiRef, - }, - ], - [ - 'google', - { - id: 'google-auth-provider', - title: 'Google', - message: 'Sign in using Google', - apiRef: googleAuthApiRef, - }, - ], - ['gcp-iap', 'gcp-iap'], - [ - 'oidc', - { - id: 'oidc-auth-provider', - title: 'OIDC', - message: 'Sign in using OIDC', - apiRef: oidcAuthApiRef, - }, - ], - [ - 'okta', - { - id: 'okta-auth-provider', - title: 'Okta', - message: 'Sign in using Okta', - apiRef: oktaAuthApiRef, - }, - ], - ['oauth2Proxy', 'oauth2Proxy'], - [ - 'onelogin', - { - id: 'onelogin-auth-provider', - title: 'OneLogin', - message: 'Sign in using OneLogin', - apiRef: oneloginAuthApiRef, - }, - ], - [ - 'saml', - { - id: 'saml-auth-provider', - title: 'SAML', - message: 'Sign in using SAML', - apiRef: samlAuthApiRef, - }, - ], -]); + * */ +const createProviders = (t: (key: string, params?: any) => string) => + new Map([ + [ + 'auth0', + { + id: 'auth0-auth-provider', + title: t('signIn.providers.auth0.title'), + message: t('signIn.providers.auth0.message'), + apiRef: auth0AuthApiRef, + }, + ], + [ + 'atlassian', + { + id: 'atlassian-auth-provider', + title: t('signIn.providers.atlassian.title'), + message: t('signIn.providers.atlassian.message'), + apiRef: atlassianAuthApiRef, + }, + ], + [ + 'microsoft', + { + id: 'microsoft-auth-provider', + title: t('signIn.providers.microsoft.title'), + message: t('signIn.providers.microsoft.message'), + apiRef: microsoftAuthApiRef, + }, + ], + ['azure-easyauth', 'azure-easyauth'], + [ + 'bitbucket', + { + id: 'bitbucket-auth-provider', + title: t('signIn.providers.bitbucket.title'), + message: t('signIn.providers.bitbucket.message'), + apiRef: bitbucketAuthApiRef, + }, + ], + [ + 'bitbucketServer', + { + id: 'bitbucket-server-auth-provider', + title: t('signIn.providers.bitbucketServer.title'), + message: t('signIn.providers.bitbucketServer.message'), + apiRef: bitbucketServerAuthApiRef, + }, + ], + ['cfaccess', 'cfaccess'], + [ + 'github', + { + id: 'github-auth-provider', + title: t('signIn.providers.github.title'), + message: t('signIn.providers.github.message'), + apiRef: githubAuthApiRef, + }, + ], + [ + 'gitlab', + { + id: 'gitlab-auth-provider', + title: t('signIn.providers.gitlab.title'), + message: t('signIn.providers.gitlab.message'), + apiRef: gitlabAuthApiRef, + }, + ], + [ + 'google', + { + id: 'google-auth-provider', + title: t('signIn.providers.google.title'), + message: t('signIn.providers.google.message'), + apiRef: googleAuthApiRef, + }, + ], + ['gcp-iap', 'gcp-iap'], + [ + 'oidc', + { + id: 'oidc-auth-provider', + title: t('signIn.providers.oidc.title'), + message: t('signIn.providers.oidc.message'), + apiRef: oidcAuthApiRef, + }, + ], + [ + 'okta', + { + id: 'okta-auth-provider', + title: t('signIn.providers.okta.title'), + message: t('signIn.providers.okta.message'), + apiRef: oktaAuthApiRef, + }, + ], + ['oauth2Proxy', 'oauth2Proxy'], + [ + 'onelogin', + { + id: 'onelogin-auth-provider', + title: t('signIn.providers.onelogin.title'), + message: t('signIn.providers.onelogin.message'), + apiRef: oneloginAuthApiRef, + }, + ], + [ + 'saml', + { + id: 'saml-auth-provider', + title: t('signIn.providers.saml.title'), + message: t('signIn.providers.saml.message'), + apiRef: samlAuthApiRef, + }, + ], + ]); export function SignInPage(props: SignInPageProps): React.JSX.Element { const configApi = useApi(configApiRef); + const { t } = useTranslation(); const isDevEnv = configApi.getString('auth.environment') === 'development'; const provider = configApi.getOptionalString('signInPage') ?? DEFAULT_PROVIDER; + + const providers = createProviders(t); const providerConfig = - PROVIDERS.get(provider) ?? PROVIDERS.get(DEFAULT_PROVIDER)!; + providers.get(provider) ?? providers.get(DEFAULT_PROVIDER)!; if (typeof providerConfig === 'object') { - const providers = isDevEnv + const providerList = isDevEnv ? (['guest', providerConfig] satisfies ['guest', SignInProviderConfig]) : [providerConfig]; return ( ); } diff --git a/packages/app/src/components/UserSettings/GeneralPage.tsx b/packages/app/src/components/UserSettings/GeneralPage.tsx index a8e2452258..b4d424041f 100644 --- a/packages/app/src/components/UserSettings/GeneralPage.tsx +++ b/packages/app/src/components/UserSettings/GeneralPage.tsx @@ -8,19 +8,21 @@ import Grid from '@mui/material/Grid'; import { InfoCard } from './InfoCard'; -export const GeneralPage = () => ( - - - +export const GeneralPage = () => { + return ( + + + + + + + + + + + + + - - - - - - - - - - -); + ); +}; diff --git a/packages/app/src/components/UserSettings/InfoCard.test.tsx b/packages/app/src/components/UserSettings/InfoCard.test.tsx index d5e853d342..21fb515c5a 100644 --- a/packages/app/src/components/UserSettings/InfoCard.test.tsx +++ b/packages/app/src/components/UserSettings/InfoCard.test.tsx @@ -78,7 +78,7 @@ describe('InfoCard', () => { 'Authentication provider': 'Github', RBAC: 'disabled', }, - full: false, + overrideBuildInfo: false, }, }, }); @@ -107,7 +107,7 @@ describe('InfoCard', () => { 'Authentication provider': 'Github', RBAC: 'disabled', }, - full: true, + overrideBuildInfo: true, }, }, }); diff --git a/packages/app/src/components/UserSettings/InfoCard.tsx b/packages/app/src/components/UserSettings/InfoCard.tsx index a57141464a..470c5b12eb 100644 --- a/packages/app/src/components/UserSettings/InfoCard.tsx +++ b/packages/app/src/components/UserSettings/InfoCard.tsx @@ -12,10 +12,12 @@ import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import buildMetadata from '../../build-metadata.json'; +import { useTranslation } from '../../hooks/useTranslation'; import { BuildInfo } from '../../types/types'; export const InfoCard = () => { const config = useApi(configApiRef); + const { t } = useTranslation(); const buildInfo: BuildInfo | undefined = config.getOptional('buildInfo'); const [showBuildInformation, setShowBuildInformation] = useState( @@ -36,11 +38,32 @@ export const InfoCard = () => { } }; - const title = buildInfo?.title ?? buildMetadata.title; + const getTitle = () => { + const defaultTitle = buildInfo?.title ?? buildMetadata?.title; + + // If titleKey is provided, use translation + if (buildInfo?.titleKey) { + return t(buildInfo.titleKey as any, { + defaultValue: defaultTitle, + }); + } + // If no title but titleKey in metadata, use that translation + if (!buildInfo?.title && buildMetadata?.titleKey) { + return t(buildMetadata.titleKey as any, { + defaultValue: buildMetadata?.title, + }); + } + + // Fall back to title or default + return defaultTitle; + }; + + const title = getTitle(); let clipboardText = title; const buildDetails = Object.entries( - buildInfo?.full === false // append build versions to the object only when buildInfo.full === false + buildInfo?.full === false || // make it backward compatible with previous `full` config option + buildInfo?.overrideBuildInfo === false ? { ...buildInfo?.card, ...buildMetadata?.card } : (buildInfo?.card ?? buildMetadata?.card), ).map(([key, value]) => `${key}: ${value}`); @@ -104,11 +127,15 @@ export const InfoCard = () => { > diff --git a/packages/app/src/components/catalog/EntityPage/ContextMenuAwareEntityLayout.tsx b/packages/app/src/components/catalog/EntityPage/ContextMenuAwareEntityLayout.tsx index 44fb57af46..0c217319d6 100644 --- a/packages/app/src/components/catalog/EntityPage/ContextMenuAwareEntityLayout.tsx +++ b/packages/app/src/components/catalog/EntityPage/ContextMenuAwareEntityLayout.tsx @@ -1,4 +1,10 @@ -import React, { ReactNode, useMemo, useState } from 'react'; +import { + ComponentType, + PropsWithChildren, + ReactNode, + useMemo, + useState, +} from 'react'; import { EntityLayout } from '@backstage/plugin-catalog'; @@ -11,7 +17,7 @@ export const ContextMenuAwareEntityLayout = (props: { children?: ReactNode; }) => { const contextMenuElements = - getMountPointData>>( + getMountPointData>>( `entity.context.menu`, ); diff --git a/packages/app/src/components/catalog/EntityPage/DiagramTabContent.tsx b/packages/app/src/components/catalog/EntityPage/DiagramTabContent.tsx index a61ef4e82d..3dbeee51cf 100644 --- a/packages/app/src/components/catalog/EntityPage/DiagramTabContent.tsx +++ b/packages/app/src/components/catalog/EntityPage/DiagramTabContent.tsx @@ -14,30 +14,35 @@ import { EntityCatalogGraphCard, } from '@backstage/plugin-catalog-graph'; +import { useTranslation } from '../../../hooks/useTranslation'; import Grid from '../Grid'; -export const DiagramTabContent = () => ( - - - - - - - -); +export const DiagramTabContent = () => { + const { t } = useTranslation(); + + return ( + + + + + + + + ); +}; diff --git a/packages/app/src/components/catalog/EntityPage/DynamicEntityTab.tsx b/packages/app/src/components/catalog/EntityPage/DynamicEntityTab.tsx index 430923e448..b28c9fe2e8 100644 --- a/packages/app/src/components/catalog/EntityPage/DynamicEntityTab.tsx +++ b/packages/app/src/components/catalog/EntityPage/DynamicEntityTab.tsx @@ -1,17 +1,44 @@ +import { forwardRef } from 'react'; + import { Entity } from '@backstage/catalog-model'; +import { Link } from '@backstage/core-components'; import { ApiHolder } from '@backstage/core-plugin-api'; import { EntityLayout, EntitySwitch } from '@backstage/plugin-catalog'; import Box from '@mui/material/Box'; import { DynamicRootConfig } from '@red-hat-developer-hub/plugin-utils'; +import { useTranslation } from '../../../hooks/useTranslation'; import getDynamicRootConfig from '../../../utils/dynamicUI/getDynamicRootConfig'; import getMountPointData from '../../../utils/dynamicUI/getMountPointData'; +import { getTranslatedTextWithFallback } from '../../../utils/translations'; import Grid from '../Grid'; +const TranslatedTab = forwardRef< + any, + { + title?: string; + titleKey?: string; + path?: string; + children?: React.ReactNode; + [key: string]: any; + } +>((props, ref) => { + const { title, titleKey, path, children, ...otherProps } = props; + const { t } = useTranslation(); + + const translatedText = getTranslatedTextWithFallback(t, titleKey, title); + return ( + + {translatedText} + + ); +}); + export type DynamicEntityTabProps = { path: string; title: string; + titleKey?: string; mountPoint: string; if?: (entity: Entity) => boolean; children?: React.ReactNode; @@ -30,6 +57,7 @@ export type DynamicEntityTabProps = { export const dynamicEntityTab = ({ path, title, + titleKey, mountPoint, children, if: condition, @@ -38,6 +66,12 @@ export const dynamicEntityTab = ({ key={`${path}`} path={path} title={title} + tabProps={{ + component: TranslatedTab, + title: title, + titleKey: titleKey, + path: path, + }} if={entity => (condition ? errorWrappedCondition( diff --git a/packages/app/src/components/catalog/EntityPage/defaultTabs.tsx b/packages/app/src/components/catalog/EntityPage/defaultTabs.tsx index fda8653c69..c3e4875bfd 100644 --- a/packages/app/src/components/catalog/EntityPage/defaultTabs.tsx +++ b/packages/app/src/components/catalog/EntityPage/defaultTabs.tsx @@ -18,62 +18,77 @@ export const defaultTabs: Record< > = { '/': { title: 'Overview', + titleKey: 'catalog.entityPage.overview.title', mountPoint: 'entity.page.overview', }, '/topology': { title: 'Topology', + titleKey: 'catalog.entityPage.topology.title', mountPoint: 'entity.page.topology', }, '/issues': { title: 'Issues', + titleKey: 'catalog.entityPage.issues.title', mountPoint: 'entity.page.issues', }, '/pr': { title: 'Pull/Merge Requests', + titleKey: 'catalog.entityPage.pullRequests.title', mountPoint: 'entity.page.pull-requests', }, '/ci': { title: 'CI', + titleKey: 'catalog.entityPage.ci.title', mountPoint: 'entity.page.ci', }, '/cd': { title: 'CD', + titleKey: 'catalog.entityPage.cd.title', mountPoint: 'entity.page.cd', }, '/kubernetes': { title: 'Kubernetes', + titleKey: 'catalog.entityPage.kubernetes.title', mountPoint: 'entity.page.kubernetes', }, '/image-registry': { title: 'Image Registry', + titleKey: 'catalog.entityPage.imageRegistry.title', mountPoint: 'entity.page.image-registry', }, '/monitoring': { title: 'Monitoring', + titleKey: 'catalog.entityPage.monitoring.title', mountPoint: 'entity.page.monitoring', }, '/lighthouse': { title: 'Lighthouse', + titleKey: 'catalog.entityPage.lighthouse.title', mountPoint: 'entity.page.lighthouse', }, '/api': { title: 'Api', + titleKey: 'catalog.entityPage.api.title', mountPoint: 'entity.page.api', }, '/dependencies': { title: 'Dependencies', + titleKey: 'catalog.entityPage.dependencies.title', mountPoint: 'entity.page.dependencies', }, '/docs': { title: 'Docs', + titleKey: 'catalog.entityPage.docs.title', mountPoint: 'entity.page.docs', }, '/definition': { title: 'Definition', + titleKey: 'catalog.entityPage.definition.title', mountPoint: 'entity.page.definition', }, '/system': { title: 'Diagram', + titleKey: 'catalog.entityPage.diagram.title', mountPoint: 'entity.page.diagram', }, }; diff --git a/packages/app/src/components/catalog/filters/CustomCatalogFilters.tsx b/packages/app/src/components/catalog/filters/CustomCatalogFilters.tsx new file mode 100644 index 0000000000..a2afe453bd --- /dev/null +++ b/packages/app/src/components/catalog/filters/CustomCatalogFilters.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +import { + EntityKindPicker, + EntityLifecyclePicker, + EntityNamespacePicker, + EntityOwnerPicker, + EntityProcessingStatusPicker, + EntityTypePicker, + UserListPicker, +} from '@backstage/plugin-catalog-react'; + +import { CustomEntityTagPicker } from './CustomEntityTagPicker'; + +/** + * Custom filters component that provides enhanced tag filtering with OR logic + */ +export const CustomCatalogFilters = () => { + return ( + <> + + + + + + + + + + ); +}; diff --git a/packages/app/src/components/catalog/filters/CustomEntityTagPicker.test.ts b/packages/app/src/components/catalog/filters/CustomEntityTagPicker.test.ts new file mode 100644 index 0000000000..2c65463228 --- /dev/null +++ b/packages/app/src/components/catalog/filters/CustomEntityTagPicker.test.ts @@ -0,0 +1,153 @@ +import { Entity } from '@backstage/catalog-model'; + +import { CustomEntityTagFilter } from './CustomEntityTagPicker'; + +describe('CustomEntityTagFilter', () => { + const createMockEntity = (tags: string[] = []): Entity => ({ + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + tags, + }, + }); + + describe('constructor', () => { + it('should initialize with values', () => { + const filter = new CustomEntityTagFilter(['tag1', 'tag2']); + expect(filter.values).toEqual(['tag1', 'tag2']); + }); + + it('should initialize with empty array', () => { + const filter = new CustomEntityTagFilter([]); + expect(filter.values).toEqual([]); + }); + }); + + describe('filterEntity', () => { + it('should return true when no filter values are set (show all)', () => { + const filter = new CustomEntityTagFilter([]); + const entity = createMockEntity(['tag1', 'tag2']); + + expect(filter.filterEntity(entity)).toBe(true); + }); + + it('should return true when entity has any of the selected tags (OR logic)', () => { + const filter = new CustomEntityTagFilter(['tag1', 'tag3']); + const entity = createMockEntity(['tag1', 'tag2']); + + expect(filter.filterEntity(entity)).toBe(true); + }); + + it('should return false when entity has none of the selected tags', () => { + const filter = new CustomEntityTagFilter(['tag3', 'tag4']); + const entity = createMockEntity(['tag1', 'tag2']); + + expect(filter.filterEntity(entity)).toBe(false); + }); + + it('should return false when entity has no tags but filter has values', () => { + const filter = new CustomEntityTagFilter(['tag1', 'tag2']); + const entity = createMockEntity([]); + + expect(filter.filterEntity(entity)).toBe(false); + }); + + it('should return false when entity has no tags metadata', () => { + const filter = new CustomEntityTagFilter(['tag1', 'tag2']); + const entity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + // no tags property + }, + }; + + expect(filter.filterEntity(entity)).toBe(false); + }); + + it('should handle single tag selection', () => { + const filter = new CustomEntityTagFilter(['tag1']); + const entity = createMockEntity(['tag1', 'tag2', 'tag3']); + + expect(filter.filterEntity(entity)).toBe(true); + }); + + it('should handle multiple matching tags (OR logic verification)', () => { + const filter = new CustomEntityTagFilter(['tag1', 'tag2']); + const entityWithBothTags = createMockEntity(['tag1', 'tag2', 'tag3']); + const entityWithOneTag = createMockEntity(['tag2', 'tag4']); + const entityWithNoMatchingTags = createMockEntity(['tag5', 'tag6']); + + // Should return true for entities with ANY matching tags + expect(filter.filterEntity(entityWithBothTags)).toBe(true); + expect(filter.filterEntity(entityWithOneTag)).toBe(true); + expect(filter.filterEntity(entityWithNoMatchingTags)).toBe(false); + }); + + it('should be case sensitive', () => { + const filter = new CustomEntityTagFilter(['Tag1']); + const entity = createMockEntity(['tag1']); + + expect(filter.filterEntity(entity)).toBe(false); + }); + }); + + describe('toQueryValue', () => { + it('should return the filter values', () => { + const values = ['tag1', 'tag2', 'tag3']; + const filter = new CustomEntityTagFilter(values); + + expect(filter.toQueryValue()).toEqual(values); + }); + + it('should return empty array when no values', () => { + const filter = new CustomEntityTagFilter([]); + + expect(filter.toQueryValue()).toEqual([]); + }); + }); + + describe('getCatalogFilters', () => { + it('should return catalog filters with metadata.tags key', () => { + const values = ['tag1', 'tag2']; + const filter = new CustomEntityTagFilter(values); + + expect(filter.getCatalogFilters()).toEqual({ + 'metadata.tags': values, + }); + }); + + it('should return catalog filters with empty array', () => { + const filter = new CustomEntityTagFilter([]); + + expect(filter.getCatalogFilters()).toEqual({ + 'metadata.tags': [], + }); + }); + }); + + describe('OR logic verification (vs AND logic)', () => { + it('should demonstrate OR logic behavior', () => { + // This test specifically verifies OR logic vs AND logic + const filter = new CustomEntityTagFilter(['frontend', 'backend']); + + // Entity with only 'frontend' tag should match (OR logic) + const frontendOnlyEntity = createMockEntity(['frontend']); + expect(filter.filterEntity(frontendOnlyEntity)).toBe(true); + + // Entity with only 'backend' tag should match (OR logic) + const backendOnlyEntity = createMockEntity(['backend']); + expect(filter.filterEntity(backendOnlyEntity)).toBe(true); + + // Entity with both tags should match + const bothTagsEntity = createMockEntity(['frontend', 'backend']); + expect(filter.filterEntity(bothTagsEntity)).toBe(true); + + // Entity with neither tag should not match + const noMatchEntity = createMockEntity(['database', 'api']); + expect(filter.filterEntity(noMatchEntity)).toBe(false); + }); + }); +}); diff --git a/packages/app/src/components/catalog/filters/CustomEntityTagPicker.tsx b/packages/app/src/components/catalog/filters/CustomEntityTagPicker.tsx new file mode 100644 index 0000000000..c463df7eba --- /dev/null +++ b/packages/app/src/components/catalog/filters/CustomEntityTagPicker.tsx @@ -0,0 +1,68 @@ +import React from 'react'; + +import { Entity } from '@backstage/catalog-model'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { EntityAutocompletePicker } from '@backstage/plugin-catalog-react'; +import { catalogReactTranslationRef } from '@backstage/plugin-catalog-react/alpha'; + +// Custom EntityTagFilter with OR logic instead of AND logic +export class CustomEntityTagFilter { + readonly values: string[]; + + constructor(values: string[]) { + this.values = values; + } + + filterEntity(entity: Entity): boolean { + if (!this.values.length) { + return true; + } + + const tags = entity.metadata?.tags || []; + if (!tags.length) { + return false; + } + + // OR logic: return true if entity has ANY of the selected tags + return this.values.some(value => tags.includes(value)); + } + + toQueryValue(): string[] { + return this.values; + } + + getCatalogFilters(): Record { + return { + 'metadata.tags': this.values, + }; + } +} + +interface CustomEntityTagPickerProps { + showCounts?: boolean; + initialFilter?: string[]; +} + +/** + * Custom Entity Tag Picker with OR logic for multiple tag selections + * Uses the same EntityAutocompletePicker as the original but with custom filter logic + */ +const CustomEntityTagPicker: React.FC = ({ + showCounts = false, + initialFilter = [], +}) => { + const { t } = useTranslationRef(catalogReactTranslationRef); + + return ( + + ); +}; + +export { CustomEntityTagPicker }; diff --git a/packages/app/src/components/learningPaths/LearningPathsPage.tsx b/packages/app/src/components/learningPaths/LearningPathsPage.tsx index eaa75dcfad..04332cb7f6 100644 --- a/packages/app/src/components/learningPaths/LearningPathsPage.tsx +++ b/packages/app/src/components/learningPaths/LearningPathsPage.tsx @@ -9,6 +9,7 @@ import { makeStyles } from 'tss-react/mui'; import { ErrorReport } from '../../common'; import { useLearningPathData } from '../../hooks/useLearningPathData'; +import { useTranslation } from '../../hooks/useTranslation'; import { LearningPathLink } from '../../types/types'; const useStyles = makeStyles()({ @@ -37,6 +38,7 @@ const learningPathLengthInfo = (path: LearningPathLink) => { const LearningPathCards = () => { const { classes } = useStyles(); + const { t } = useTranslation(); const { data, error, isLoading } = useLearningPathData(); @@ -46,13 +48,19 @@ const LearningPathCards = () => { if (!data) { return ( - + ); } if (!isLoading && !data && error) { return ( - + ); } @@ -76,10 +84,12 @@ const LearningPathCards = () => { }; export const LearningPaths = () => { + const { t } = useTranslation(); + return ( -
+
diff --git a/packages/app/src/components/search/SearchPage.tsx b/packages/app/src/components/search/SearchPage.tsx index 076b5e5f15..f175cb6b54 100644 --- a/packages/app/src/components/search/SearchPage.tsx +++ b/packages/app/src/components/search/SearchPage.tsx @@ -12,6 +12,7 @@ import Grid from '@mui/material/Grid'; import Paper from '@mui/material/Paper'; import { makeStyles } from 'tss-react/mui'; +import { useTranslation } from '../../hooks/useTranslation'; import getMountPointData from '../../utils/dynamicUI/getMountPointData'; import { MenuIcon } from '../Root/MenuIcon'; @@ -35,10 +36,11 @@ const useStyles = makeStyles()(theme => ({ export const SearchPage = () => { const { classes } = useStyles(); + const { t } = useTranslation(); return ( -
+
@@ -54,12 +56,12 @@ export const SearchPage = () => { , }, ...getMountPointData< @@ -82,20 +84,29 @@ export const SearchPage = () => { /> {...getMountPointData( 'search.page.filters', ).map(({ Component, config }, idx) => { return ( - + ); })} @@ -113,7 +124,7 @@ export const SearchPage = () => { return ( } /> ); diff --git a/packages/app/src/consts.ts b/packages/app/src/consts.ts index 8594bebaa5..827cf0abff 100644 --- a/packages/app/src/consts.ts +++ b/packages/app/src/consts.ts @@ -2,35 +2,41 @@ export const DefaultMainMenuItems = { menuItems: { 'default.home': { title: 'Home', + titleKey: 'menuItem.home', icon: 'home', to: '/', priority: 100, }, 'default.my-group': { title: 'My Group', + titleKey: 'menuItem.myGroup', icon: 'group', priority: 90, }, 'default.catalog': { title: 'Catalog', + titleKey: 'menuItem.catalog', icon: 'category', to: 'catalog', priority: 80, }, 'default.apis': { title: 'APIs', + titleKey: 'menuItem.apis', icon: 'extension', to: 'api-docs', priority: 70, }, 'default.learning-path': { title: 'Learning Paths', + titleKey: 'menuItem.learningPaths', icon: 'school', to: 'learning-paths', priority: 60, }, 'default.create': { title: 'Self-service', + titleKey: 'menuItem.selfService', icon: 'add', to: 'create', priority: 50, diff --git a/packages/app/src/hooks/useLanguagePreference.test.ts b/packages/app/src/hooks/useLanguagePreference.test.ts new file mode 100644 index 0000000000..a1c6b5a13c --- /dev/null +++ b/packages/app/src/hooks/useLanguagePreference.test.ts @@ -0,0 +1,330 @@ +import { useAsync } from 'react-use'; +import useObservable from 'react-use/esm/useObservable'; + +import { + configApiRef, + identityApiRef, + storageApiRef, + useApi, +} from '@backstage/core-plugin-api'; +import { appLanguageApiRef } from '@backstage/core-plugin-api/alpha'; + +import { renderHook, waitFor } from '@testing-library/react'; + +import { useLanguagePreference } from './useLanguagePreference'; + +const mockLanguageApi = { + language$: jest.fn(), + getLanguage: jest.fn(), + setLanguage: jest.fn(), +}; +const mockStorageApi = { + forBucket: jest.fn(() => ({ + snapshot: jest.fn(), + observe$: jest.fn(), + set: jest.fn(), + })), +}; +const mockIdentityApi = { + getBackstageIdentity: jest.fn(), +}; +const mockConfigApi = { + getOptionalString: jest.fn(), + getOptionalConfig: jest.fn(), +}; + +// Mock hooks +jest.mock('@backstage/core-plugin-api', () => ({ + useApi: jest.fn(), + configApiRef: { id: 'config' }, + identityApiRef: { id: 'identity' }, + storageApiRef: { id: 'storage' }, +})); + +jest.mock('@backstage/core-plugin-api/alpha', () => ({ + appLanguageApiRef: { id: 'appLanguage' }, +})); + +jest.mock('react-use', () => ({ + useAsync: jest.fn(), +})); + +jest.mock('react-use/esm/useObservable', () => ({ + __esModule: true, + default: jest.fn(), +})); + +describe('useLanguagePreference', () => { + beforeEach(() => { + jest.clearAllMocks(); + + (useApi as jest.Mock).mockImplementation((ref: any) => { + if (ref === appLanguageApiRef) return mockLanguageApi; + if (ref === storageApiRef) return mockStorageApi; + if (ref === identityApiRef) return mockIdentityApi; + if (ref === configApiRef) return mockConfigApi; + return undefined; + }); + + // default mocks + (useAsync as jest.Mock).mockReturnValue({ + value: { userEntityRef: 'user:default/test' }, + loading: false, + }); + (useObservable as jest.Mock).mockReturnValue({ language: 'en' }); + + mockLanguageApi.getLanguage.mockReturnValue({ + language: 'en', + }); + mockConfigApi.getOptionalString.mockImplementation((key: string) => { + if (key === 'userSettings.persistence') return 'database'; + return undefined; + }); + mockConfigApi.getOptionalConfig.mockImplementation((key: string) => { + if (key === 'i18n') { + return { + getStringArray: jest.fn(() => ['en']), + getOptional: jest.fn(() => undefined), + }; + } + return undefined; + }); + (mockStorageApi.forBucket as jest.Mock).mockImplementation(() => ({ + snapshot: jest.fn(() => ({ value: 'en' })), + observe$: jest.fn(() => ({ + subscribe: jest.fn(() => ({ unsubscribe: jest.fn() })), + })), + set: jest.fn().mockResolvedValue(undefined), + })); + }); + + it('should return current language', () => { + const { result } = renderHook(() => useLanguagePreference()); + expect(result.current).toBe('en'); + }); + + it('should not sync if user is guest', () => { + (useAsync as jest.Mock).mockReturnValue({ + value: { userEntityRef: 'user:development/guest' }, + loading: false, + }); + + renderHook(() => useLanguagePreference()); + + expect(mockStorageApi.forBucket().observe$).not.toHaveBeenCalled(); + expect(mockStorageApi.forBucket().set).not.toHaveBeenCalled(); + }); + + it('should not sync if still loading identity', () => { + (useAsync as jest.Mock).mockReturnValue({ + value: undefined, + loading: true, + }); + + renderHook(() => useLanguagePreference()); + + expect(mockStorageApi.forBucket().observe$).not.toHaveBeenCalled(); + expect(mockStorageApi.forBucket().set).not.toHaveBeenCalled(); + }); + + it('should not sync when persistence is set to browser', () => { + mockConfigApi.getOptionalString.mockImplementation((key: string) => { + if (key === 'userSettings.persistence') return 'browser'; + return undefined; + }); + + renderHook(() => useLanguagePreference()); + + expect(mockStorageApi.forBucket().observe$).not.toHaveBeenCalled(); + expect(mockStorageApi.forBucket().set).not.toHaveBeenCalled(); + }); + + it('should warn on invalid persistence configuration', () => { + const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(); + + mockConfigApi.getOptionalString.mockImplementation((key: string) => { + if (key === 'userSettings.persistence') return 'invalid-value'; + return undefined; + }); + + renderHook(() => useLanguagePreference()); + + expect(consoleSpy).toHaveBeenCalledWith( + 'useLanguagePreference: Invalid userSettings.persistence value: "invalid-value". Expected "database" or "browser". Defaulting to database.', + ); + + consoleSpy.mockRestore(); + }); + + it('should sync when persistence is explicitly set to database', () => { + const observeMock = jest.fn(() => ({ + subscribe: jest.fn(() => ({ unsubscribe: jest.fn() })), + })); + + mockConfigApi.getOptionalString.mockImplementation((key: string) => { + if (key === 'userSettings.persistence') return 'database'; + return undefined; + }); + + (mockStorageApi.forBucket as jest.Mock).mockImplementation(() => ({ + snapshot: jest.fn(() => ({ value: 'en' })), + observe$: observeMock, + set: jest.fn(), + })); + + renderHook(() => useLanguagePreference()); + + expect(observeMock).toHaveBeenCalled(); + }); + + it('should not sync on first hydration after refresh', () => { + (useObservable as jest.Mock).mockReturnValue({ language: 'fr' }); + + renderHook(() => useLanguagePreference()); + + // Should not sync on first render due to hydration guard + expect(mockStorageApi.forBucket().set).not.toHaveBeenCalled(); + }); + + it('should sync after hydration on subsequent language changes', async () => { + const setFn = jest.fn().mockResolvedValue(undefined); + (mockStorageApi.forBucket as jest.Mock).mockImplementation(() => ({ + snapshot: jest.fn(() => ({ value: 'en' })), + observe$: jest.fn(() => ({ + subscribe: jest.fn(() => ({ unsubscribe: jest.fn() })), + })), + set: setFn, + })); + + // Use rerender to test hydration within the same hook instance + const { rerender } = renderHook( + ({ lang }) => { + (useObservable as jest.Mock).mockReturnValue({ language: lang }); + return useLanguagePreference(); + }, + { initialProps: { lang: 'fr' } }, + ); + + // Should not sync on first render due to hydration guard + expect(setFn).not.toHaveBeenCalled(); + + // Clear and test second render - should sync after hydration + setFn.mockClear(); + rerender({ lang: 'de' }); + + await waitFor( + () => { + expect(setFn).toHaveBeenCalledWith('language', 'de'); + }, + { timeout: 2000 }, + ); + }); + + it('should not sync if language value is undefined', () => { + (useObservable as jest.Mock).mockReturnValue({ language: undefined }); + + renderHook(() => useLanguagePreference()); + + expect(mockStorageApi.forBucket().set).not.toHaveBeenCalled(); + }); + + it('should handle storage set errors gracefully', async () => { + const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(); + const setFn = jest.fn().mockRejectedValue(new Error('Storage error')); + + (mockStorageApi.forBucket as jest.Mock).mockImplementation(() => ({ + snapshot: jest.fn(() => ({ value: 'en' })), + observe$: jest.fn(() => ({ + subscribe: jest.fn(() => ({ unsubscribe: jest.fn() })), + })), + set: setFn, + })); + + const { rerender } = renderHook( + ({ lang }) => { + (useObservable as jest.Mock).mockReturnValue({ language: lang }); + return useLanguagePreference(); + }, + { initialProps: { lang: 'fr' } }, + ); + + // Trigger sync after hydration + rerender({ lang: 'de' }); + + await waitFor( + () => { + expect(consoleSpy).toHaveBeenCalledWith( + 'useLanguagePreference: Failed to store language in user-settings storage', + expect.any(Error), + ); + }, + { timeout: 2000 }, + ); + + consoleSpy.mockRestore(); + }); + + it('should unsubscribe from storage observable on unmount', () => { + const unsubscribeFn = jest.fn(); + (mockStorageApi.forBucket as jest.Mock).mockImplementation(() => ({ + snapshot: jest.fn(() => ({ value: 'en' })), + observe$: jest.fn(() => ({ + subscribe: jest.fn(() => ({ unsubscribe: unsubscribeFn })), + })), + set: jest.fn(), + })); + + const { unmount } = renderHook(() => useLanguagePreference()); + + unmount(); + + expect(unsubscribeFn).toHaveBeenCalled(); + }); + + it('should not call setLanguage if stored value equals current language', () => { + (mockStorageApi.forBucket as jest.Mock).mockImplementation(() => ({ + snapshot: jest.fn(() => ({ value: 'en' })), + observe$: jest.fn(() => ({ + subscribe: (cb: any) => { + cb({ value: 'en' }); // Same as current language + return { unsubscribe: jest.fn() }; + }, + })), + set: jest.fn(), + })); + + renderHook(() => useLanguagePreference()); + + expect(mockLanguageApi.setLanguage).not.toHaveBeenCalled(); + }); + + it('should prevent sync loop when update comes from user settings', async () => { + const setFn = jest.fn(); + + (mockStorageApi.forBucket as jest.Mock).mockImplementation(() => ({ + snapshot: jest.fn(() => ({ value: 'en' })), + observe$: jest.fn(() => ({ + subscribe: (cb: any) => { + // Simulate storage update + cb({ value: 'fr' }); + return { unsubscribe: jest.fn() }; + }, + })), + set: setFn, + })); + + // Mock languageApi.setLanguage to trigger a language change + mockLanguageApi.setLanguage.mockImplementation(newLang => { + (useObservable as jest.Mock).mockReturnValue({ language: newLang }); + }); + + const { rerender } = renderHook(() => useLanguagePreference()); + + // Trigger the effect that would normally cause a sync loop + rerender(); + + // Should not call set because the update came from user settings + await new Promise(resolve => setTimeout(resolve, 100)); + expect(setFn).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/app/src/hooks/useLanguagePreference.ts b/packages/app/src/hooks/useLanguagePreference.ts new file mode 100644 index 0000000000..627565486a --- /dev/null +++ b/packages/app/src/hooks/useLanguagePreference.ts @@ -0,0 +1,153 @@ +import { useEffect, useRef } from 'react'; +import { useAsync } from 'react-use'; +import useObservable from 'react-use/esm/useObservable'; + +import { + configApiRef, + identityApiRef, + storageApiRef, + useApi, +} from '@backstage/core-plugin-api'; +import { appLanguageApiRef } from '@backstage/core-plugin-api/alpha'; + +import { TranslationConfig } from '../types/types'; +import { getDefaultLanguage } from '../utils/language/language'; + +const BUCKET = 'userSettings'; +const KEY = 'language'; +const GUEST_USER_REF = 'user:development/guest'; + +/** + * Hook that provides bidirectional synchronization of language preferences + * between the app's language API and user storage when database persistence is enabled. + * + * Features: + * - Persists language changes to user storage (database only) + * - Restores language preferences on page load + * - Prevents sync for guest users + * - Includes safeguards against sync loops and hydration issues + * + * @returns The current language preference (string or undefined) + */ +export const useLanguagePreference = (): string | undefined => { + const languageApi = useApi(appLanguageApiRef); + const storageApi = useApi(storageApiRef); + const identityApi = useApi(identityApiRef); + const configApi = useApi(configApiRef); + + const { value, loading } = useAsync(() => identityApi.getBackstageIdentity()); + const isGuestUser = value?.userEntityRef === GUEST_USER_REF; + const persistence = + configApi.getOptionalString('userSettings.persistence') ?? 'database'; + const config = configApi.getOptionalConfig('i18n'); + + const translationConfig: TranslationConfig = { + locales: config?.getStringArray('locales') ?? ['en'], + defaultLocale: config?.getOptional('defaultLocale'), + }; + + const isDatabasePersistence = persistence === 'database'; + + // Validate persistence configuration + if (persistence !== 'database' && persistence !== 'browser') { + // eslint-disable-next-line no-console + console.warn( + `useLanguagePreference: Invalid userSettings.persistence value: "${persistence}". Expected "database" or "browser". Defaulting to database.`, + ); + } + + const shouldSync = !loading && !isGuestUser && isDatabasePersistence; + + const language = useObservable(languageApi.language$(), { + language: languageApi.getLanguage().language, + })?.language; + + const lastUpdateFromUserSettings = useRef(false); + const hydrated = useRef(false); + const mounted = useRef(true); + + const defaultLanguage = getDefaultLanguage(translationConfig); + + // User settings → language api + useEffect(() => { + if (!shouldSync) { + return () => {}; // Return empty cleanup function + } + + let subscription: { unsubscribe: () => void } | null = null; + + const storage = storageApi.forBucket(BUCKET); + try { + subscription = storage.observe$(KEY).subscribe(stored => { + if (mounted.current && stored.presence === 'absent') { + languageApi.setLanguage(defaultLanguage); + storage.set(KEY, defaultLanguage); + } + if ( + mounted.current && + stored?.value && + stored.value !== languageApi.getLanguage().language + ) { + lastUpdateFromUserSettings.current = true; + languageApi.setLanguage(stored.value); + } + }); + } catch (error) { + // eslint-disable-next-line no-console + console.warn( + 'useLanguagePreference: Failed to set up language storage subscription:', + error, + ); + } + + return () => { + if (subscription) { + try { + subscription.unsubscribe(); + } catch (error) { + // eslint-disable-next-line no-console + console.warn( + 'useLanguagePreference: Failed to unsubscribe from language storage:', + error, + ); + } + } + }; + }, [storageApi, shouldSync, languageApi, defaultLanguage]); + + // Cleanup mounted flag on unmount + useEffect(() => { + return () => { + mounted.current = false; + }; + }, []); + + // Language Api → user settings storage + useEffect(() => { + if (!shouldSync || !language) return; + + if (!hydrated.current) { + // First time after refresh, don’t sync back + hydrated.current = true; + return; + } + + if (lastUpdateFromUserSettings.current) { + lastUpdateFromUserSettings.current = false; + return; + } + + storageApi + .forBucket(BUCKET) + .set(KEY, language) + .catch(e => { + // eslint-disable-next-line no-console + console.warn( + 'useLanguagePreference: Failed to store language in user-settings storage', + e, + ); + }); + }, [language, shouldSync, storageApi]); + + return language; +}; diff --git a/packages/app/src/hooks/useTranslation.ts b/packages/app/src/hooks/useTranslation.ts new file mode 100644 index 0000000000..09eb4ea858 --- /dev/null +++ b/packages/app/src/hooks/useTranslation.ts @@ -0,0 +1,26 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + TranslationFunction, + useTranslationRef, +} from '@backstage/core-plugin-api/alpha'; + +import { rhdhTranslationRef } from '../translations/rhdh/ref'; + +export const useTranslation = (): { + t: TranslationFunction; +} => useTranslationRef(rhdhTranslationRef); diff --git a/packages/app/src/translations/catalog-import/catalog-import-en.ts b/packages/app/src/translations/catalog-import/catalog-import-en.ts new file mode 100644 index 0000000000..32441d459e --- /dev/null +++ b/packages/app/src/translations/catalog-import/catalog-import-en.ts @@ -0,0 +1,13 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { catalogImportTranslationRef } from '@backstage/plugin-catalog-import/alpha'; + +const en = createTranslationMessages({ + ref: catalogImportTranslationRef, + full: false, // False means that this is a partial translation + messages: { + 'defaultImportPage.headerTitle': 'Import an existing Git repository', + 'importInfoCard.title': 'Import an existing Git repository', + }, +}); + +export default en; diff --git a/packages/app/src/translations/catalog-import/catalog-import.ts b/packages/app/src/translations/catalog-import/catalog-import.ts new file mode 100644 index 0000000000..4a8c401815 --- /dev/null +++ b/packages/app/src/translations/catalog-import/catalog-import.ts @@ -0,0 +1,9 @@ +import { createTranslationResource } from '@backstage/core-plugin-api/alpha'; +import { catalogImportTranslationRef } from '@backstage/plugin-catalog-import/alpha'; + +export const catalogImportTranslations = createTranslationResource({ + ref: catalogImportTranslationRef, + translations: { + en: () => import('./catalog-import-en'), + }, +}); diff --git a/packages/app/src/translations/core-components/core-components-en.ts b/packages/app/src/translations/core-components/core-components-en.ts new file mode 100644 index 0000000000..5d47416c7a --- /dev/null +++ b/packages/app/src/translations/core-components/core-components-en.ts @@ -0,0 +1,55 @@ +import { coreComponentsTranslationRef } from '@backstage/core-components/alpha'; +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; + +const en = createTranslationMessages({ + ref: coreComponentsTranslationRef, + full: false, // False means that this is a partial translation + messages: { + // This is a workaround that ensures that multiple translations + // of the shared core-components are present that was added over time. + // See: + // https://issues.redhat.com/browse/RHDHBUGS-1235 + // https://issues.redhat.com/browse/RHDHBUGS-1976 + // + // For example, the 'table.header.actions' key was introduced in + // @backstage/core-component 0.17.3 (part of Backstage 1.40.0) + // and wasn't there in 0.17.2 (part of Backstage 1.39.0). + // + // See: + // https://github.com/backstage/backstage/blob/v1.39.0/packages/core-components/src/translation.ts#L87-L107 + // https://github.com/backstage/backstage/blob/v1.40.0/packages/core-components/src/translation.ts#L87-L110 + // https://github.com/backstage/versions/blob/main/v1/releases/1.39.0/manifest.json#L80-L83 + // https://github.com/backstage/versions/blob/main/v1/releases/1.40.0/manifest.json#L80-L83 + // + // This here is a workaround that ensures that at least these translations + // are available also if different plugins brings their own version of @backstage/core-components. + // + // In the future we should make sure that translations of multiple versions of the + // @backstage/core-components library are merged properly and are shipped with RHDH. + // We track that change here: https://issues.redhat.com/browse/RHIDP-8836 + // + // Added in Backstage 1.37 + 'table.filter.placeholder': 'All results', + 'table.body.emptyDataSourceMessage': 'No records to display', + 'table.pagination.firstTooltip': 'First Page', + 'table.pagination.labelDisplayedRows': '{from}-{to} of {count}', + 'table.pagination.labelRowsSelect': 'rows', + 'table.pagination.lastTooltip': 'Last Page', + 'table.pagination.nextTooltip': 'Next Page', + 'table.pagination.previousTooltip': 'Previous Page', + 'table.toolbar.search': 'Filter', + + // Changed in Backstage 1.38 + 'alertDisplay.message_one': '({{ count }} newer message)', + 'alertDisplay.message_other': '({{ count }} newer messages)', + + // Added in Backstage 1.40 + 'table.header.actions': 'Actions', + + // Added in Backstage 1.41 + 'oauthRequestDialog.message': + 'Sign-in to allow {{appTitle}} access to {{provider}} APIs and identities.', + } as any, +}); + +export default en; diff --git a/packages/app/src/translations/core-components/core-components.ts b/packages/app/src/translations/core-components/core-components.ts new file mode 100644 index 0000000000..5bf8720e70 --- /dev/null +++ b/packages/app/src/translations/core-components/core-components.ts @@ -0,0 +1,9 @@ +import { coreComponentsTranslationRef } from '@backstage/core-components/alpha'; +import { createTranslationResource } from '@backstage/core-plugin-api/alpha'; + +export const coreComponentsTranslations = createTranslationResource({ + ref: coreComponentsTranslationRef, + translations: { + en: () => import('./core-components-en'), + }, +}); diff --git a/packages/app/src/translations/rhdh/de.ts b/packages/app/src/translations/rhdh/de.ts new file mode 100644 index 0000000000..df27fbdfc7 --- /dev/null +++ b/packages/app/src/translations/rhdh/de.ts @@ -0,0 +1,122 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; + +import { rhdhTranslationRef } from './ref'; + +export default createTranslationMessages({ + ref: rhdhTranslationRef, + full: true, // False means that this is a partial translation + messages: { + // Default main menu items from consts.ts + 'menuItem.home': 'Startseite', + 'menuItem.myGroup': 'Meine Gruppe', + 'menuItem.catalog': 'Katalog', + 'menuItem.apis': 'APIs', + 'menuItem.learningPaths': 'Lernpfade', + 'menuItem.selfService': 'Self-Service', + 'menuItem.userSettings': 'Benutzereinstellungen', + 'menuItem.administration': 'Administration', + 'menuItem.extensions': 'Erweiterungen', + + // dynamic-plugins.default.main-menu-items + 'menuItem.clusters': 'Cluster', + 'menuItem.rbac': 'RBAC', + 'menuItem.bulkImport': 'Massenimport', + 'menuItem.docs': 'Dokumentation', + 'menuItem.lighthouse': 'Lighthouse', + 'menuItem.techRadar': 'Tech-Radar', + 'menuItem.orchestrator': 'Orchestrator', + 'menuItem.adoptionInsights': 'Einführungseinblicke', + + 'catalog.entityPage.overview.title': 'Übersicht', + 'catalog.entityPage.topology.title': 'Topologie', + 'catalog.entityPage.issues.title': 'Issues', + 'catalog.entityPage.pullRequests.title': 'Pull/Merge Requests', + 'catalog.entityPage.ci.title': 'CI', + 'catalog.entityPage.cd.title': 'CD', + 'catalog.entityPage.kubernetes.title': 'Kubernetes', + 'catalog.entityPage.imageRegistry.title': 'Image Registry', + 'catalog.entityPage.monitoring.title': 'Überwachung', + 'catalog.entityPage.lighthouse.title': 'Lighthouse', + 'catalog.entityPage.api.title': 'API', + 'catalog.entityPage.dependencies.title': 'Abhängigkeiten', + 'catalog.entityPage.docs.title': 'Dokumentation', + 'catalog.entityPage.definition.title': 'Definition', + 'catalog.entityPage.diagram.title': 'Systemdiagramm', + 'catalog.entityPage.workflows.title': 'Workflows', + + 'sidebar.menu': 'Menü', + 'sidebar.home': 'Startseite', + 'sidebar.homeLogo': 'Startseite-Logo', + + // SignIn page translations + 'signIn.page.title': 'Anmeldeverfahren auswählen', + 'signIn.providers.auth0.title': 'Auth0', + 'signIn.providers.auth0.message': 'Mit Auth0 anmelden', + 'signIn.providers.atlassian.title': 'Atlassian', + 'signIn.providers.atlassian.message': 'Mit Atlassian anmelden', + 'signIn.providers.microsoft.title': 'Microsoft', + 'signIn.providers.microsoft.message': 'Mit Microsoft anmelden', + 'signIn.providers.bitbucket.title': 'Bitbucket', + 'signIn.providers.bitbucket.message': 'Mit Bitbucket anmelden', + 'signIn.providers.bitbucketServer.title': 'Bitbucket Server', + 'signIn.providers.bitbucketServer.message': 'Mit Bitbucket Server anmelden', + 'signIn.providers.github.title': 'GitHub', + 'signIn.providers.github.message': 'Mit GitHub anmelden', + 'signIn.providers.gitlab.title': 'GitLab', + 'signIn.providers.gitlab.message': 'Mit GitLab anmelden', + 'signIn.providers.google.title': 'Google', + 'signIn.providers.google.message': 'Mit Google anmelden', + 'signIn.providers.oidc.title': 'OIDC', + 'signIn.providers.oidc.message': 'Mit OIDC anmelden', + 'signIn.providers.okta.title': 'Okta', + 'signIn.providers.okta.message': 'Mit Okta anmelden', + 'signIn.providers.onelogin.title': 'OneLogin', + 'signIn.providers.onelogin.message': 'Mit OneLogin anmelden', + 'signIn.providers.saml.title': 'SAML', + 'signIn.providers.saml.message': 'Mit SAML anmelden', + + // App translations + 'app.scaffolder.title': 'Self-Service', + 'app.search.title': 'Suchen', + 'app.search.resultType': 'Ergebnistyp', + 'app.search.softwareCatalog': 'Software-Katalog', + 'app.search.filters.kind': 'Art', + 'app.search.filters.lifecycle': 'Lebenszyklus', + 'app.search.filters.component': 'Komponente', + 'app.search.filters.template': 'Vorlage', + 'app.search.filters.experimental': 'experimentell', + 'app.search.filters.production': 'produktionsreif', + 'app.learningPaths.title': 'Lernpfade', + 'app.learningPaths.error.title': 'Daten konnten nicht abgerufen werden.', + 'app.learningPaths.error.unknownError': 'Unbekannter Fehler', + 'app.userSettings.infoCard.title': 'RHDH-Metadaten', + 'app.userSettings.infoCard.metadataCopied': + 'Metadaten in die Zwischenablage kopiert', + 'app.userSettings.infoCard.copyMetadata': + 'Metadaten in die Zwischenablage kopieren', + 'app.userSettings.infoCard.showLess': 'Weniger anzeigen', + 'app.userSettings.infoCard.showMore': 'Mehr anzeigen', + 'app.errors.contactSupport': 'Support kontaktieren', + 'app.errors.goBack': 'Zurück', + 'app.errors.notFound.message': 'Diese Seite konnten wir nicht finden', + 'app.errors.notFound.additionalInfo': + 'Die gesuchte Seite wurde möglicherweise entfernt, umbenannt oder ist vorübergehend nicht verfügbar.', + 'app.table.createdAt': 'Erstellt am', + }, +}); diff --git a/packages/app/src/translations/rhdh/es.ts b/packages/app/src/translations/rhdh/es.ts new file mode 100644 index 0000000000..010dad8b6a --- /dev/null +++ b/packages/app/src/translations/rhdh/es.ts @@ -0,0 +1,123 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; + +import { rhdhTranslationRef } from './ref'; + +export default createTranslationMessages({ + ref: rhdhTranslationRef, + full: true, // False means that this is a partial translation + messages: { + // Default main menu items from consts.ts + 'menuItem.home': 'Inicio', + 'menuItem.myGroup': 'Mi Grupo', + 'menuItem.catalog': 'Catálogo', + 'menuItem.apis': 'APIs', + 'menuItem.learningPaths': 'Rutas de Aprendizaje', + 'menuItem.selfService': 'Autoservicio', + 'menuItem.userSettings': 'Configuración de usuario', + 'menuItem.administration': 'Administración', + 'menuItem.extensions': 'Extensiones', + + // dynamic-plugins.default.main-menu-items + 'menuItem.clusters': 'Clústeres', + 'menuItem.rbac': 'RBAC', + 'menuItem.bulkImport': 'Importación masiva', + 'menuItem.docs': 'Documentación', + 'menuItem.lighthouse': 'Lighthouse', + 'menuItem.techRadar': 'Radar tecnológico', + 'menuItem.orchestrator': 'Orquestador', + 'menuItem.adoptionInsights': 'Insights de adopción', + + 'catalog.entityPage.overview.title': 'Resumen', + 'catalog.entityPage.topology.title': 'Topología', + 'catalog.entityPage.issues.title': 'Problemas', + 'catalog.entityPage.pullRequests.title': 'Pull/Merge Requests', + 'catalog.entityPage.ci.title': 'CI', + 'catalog.entityPage.cd.title': 'CD', + 'catalog.entityPage.kubernetes.title': 'Kubernetes', + 'catalog.entityPage.imageRegistry.title': 'Registro de Imágenes', + 'catalog.entityPage.monitoring.title': 'Monitoreo', + 'catalog.entityPage.lighthouse.title': 'Lighthouse', + 'catalog.entityPage.api.title': 'API', + 'catalog.entityPage.dependencies.title': 'Dependencias', + 'catalog.entityPage.docs.title': 'Documentación', + 'catalog.entityPage.definition.title': 'Definición', + 'catalog.entityPage.diagram.title': 'Diagrama del Sistema', + 'catalog.entityPage.workflows.title': 'Flujos de trabajo', + + 'sidebar.menu': 'Menú', + 'sidebar.home': 'Inicio', + 'sidebar.homeLogo': 'Logo de inicio', + + // SignIn page translations + 'signIn.page.title': 'Seleccionar un método de inicio de sesión', + 'signIn.providers.auth0.title': 'Auth0', + 'signIn.providers.auth0.message': 'Iniciar sesión con Auth0', + 'signIn.providers.atlassian.title': 'Atlassian', + 'signIn.providers.atlassian.message': 'Iniciar sesión con Atlassian', + 'signIn.providers.microsoft.title': 'Microsoft', + 'signIn.providers.microsoft.message': 'Iniciar sesión con Microsoft', + 'signIn.providers.bitbucket.title': 'Bitbucket', + 'signIn.providers.bitbucket.message': 'Iniciar sesión con Bitbucket', + 'signIn.providers.bitbucketServer.title': 'Bitbucket Server', + 'signIn.providers.bitbucketServer.message': + 'Iniciar sesión con Bitbucket Server', + 'signIn.providers.github.title': 'GitHub', + 'signIn.providers.github.message': 'Iniciar sesión con GitHub', + 'signIn.providers.gitlab.title': 'GitLab', + 'signIn.providers.gitlab.message': 'Iniciar sesión con GitLab', + 'signIn.providers.google.title': 'Google', + 'signIn.providers.google.message': 'Iniciar sesión con Google', + 'signIn.providers.oidc.title': 'OIDC', + 'signIn.providers.oidc.message': 'Iniciar sesión con OIDC', + 'signIn.providers.okta.title': 'Okta', + 'signIn.providers.okta.message': 'Iniciar sesión con Okta', + 'signIn.providers.onelogin.title': 'OneLogin', + 'signIn.providers.onelogin.message': 'Iniciar sesión con OneLogin', + 'signIn.providers.saml.title': 'SAML', + 'signIn.providers.saml.message': 'Iniciar sesión con SAML', + + // App translations + 'app.scaffolder.title': 'Autoservicio', + 'app.search.title': 'Buscar', + 'app.search.resultType': 'Tipo de resultado', + 'app.search.softwareCatalog': 'Catálogo de software', + 'app.search.filters.kind': 'Tipo', + 'app.search.filters.lifecycle': 'Ciclo de vida', + 'app.search.filters.component': 'Componente', + 'app.search.filters.template': 'Plantilla', + 'app.search.filters.experimental': 'experimental', + 'app.search.filters.production': 'producción', + 'app.learningPaths.title': 'Rutas de aprendizaje', + 'app.learningPaths.error.title': 'No se pudieron obtener los datos.', + 'app.learningPaths.error.unknownError': 'Error desconocido', + 'app.userSettings.infoCard.title': 'Metadatos RHDH', + 'app.userSettings.infoCard.metadataCopied': + 'Metadatos copiados al portapapeles', + 'app.userSettings.infoCard.copyMetadata': + 'Copiar metadatos al portapapeles', + 'app.userSettings.infoCard.showLess': 'Mostrar menos', + 'app.userSettings.infoCard.showMore': 'Mostrar más', + 'app.errors.contactSupport': 'Contactar soporte', + 'app.errors.goBack': 'Volver', + 'app.errors.notFound.message': 'No pudimos encontrar esa página', + 'app.errors.notFound.additionalInfo': + 'La página que buscas pudo haber sido eliminada, renombrada o está temporalmente no disponible.', + 'app.table.createdAt': 'Creado el', + }, +}); diff --git a/packages/app/src/translations/rhdh/fr.ts b/packages/app/src/translations/rhdh/fr.ts new file mode 100644 index 0000000000..89e602d85e --- /dev/null +++ b/packages/app/src/translations/rhdh/fr.ts @@ -0,0 +1,123 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; + +import { rhdhTranslationRef } from './ref'; + +export default createTranslationMessages({ + ref: rhdhTranslationRef, + full: true, // False means that this is a partial translation + messages: { + // Default main menu items from consts.ts + 'menuItem.home': 'Accueil', + 'menuItem.myGroup': 'Mon Groupe', + 'menuItem.catalog': 'Catalogue', + 'menuItem.apis': 'APIs', + 'menuItem.learningPaths': "Parcours d'apprentissage", + 'menuItem.selfService': 'Libre-service', + 'menuItem.userSettings': 'Paramètres utilisateur', + 'menuItem.administration': 'Administration', + 'menuItem.extensions': 'Modules', + + // dynamic-plugins.default.main-menu-items + 'menuItem.clusters': 'Clusters', + 'menuItem.rbac': 'RBAC', + 'menuItem.bulkImport': 'Importation en masse', + 'menuItem.docs': 'Documentation', + 'menuItem.lighthouse': 'Lighthouse', + 'menuItem.techRadar': 'Radar technologique', + 'menuItem.orchestrator': 'Orchestrateur', + 'menuItem.adoptionInsights': "Insights d'adoption", + + 'catalog.entityPage.overview.title': 'Aperçu', + 'catalog.entityPage.topology.title': 'Topologie', + 'catalog.entityPage.issues.title': 'Problèmes', + 'catalog.entityPage.pullRequests.title': 'Pull/Merge Requests', + 'catalog.entityPage.ci.title': 'CI', + 'catalog.entityPage.cd.title': 'CD', + 'catalog.entityPage.kubernetes.title': 'Kubernetes', + 'catalog.entityPage.imageRegistry.title': "Registre d'Images", + 'catalog.entityPage.monitoring.title': 'Surveillance', + 'catalog.entityPage.lighthouse.title': 'Lighthouse', + 'catalog.entityPage.api.title': 'API', + 'catalog.entityPage.dependencies.title': 'Dépendances', + 'catalog.entityPage.docs.title': 'Documentation', + 'catalog.entityPage.definition.title': 'Définition', + 'catalog.entityPage.diagram.title': 'Diagramme du Système', + 'catalog.entityPage.workflows.title': 'Flux de travail', + + 'sidebar.menu': 'Menu', + 'sidebar.home': 'Accueil', + 'sidebar.homeLogo': "Logo d'accueil", + + // SignIn page translations + 'signIn.page.title': 'Sélectionner une méthode de connexion', + 'signIn.providers.auth0.title': 'Auth0', + 'signIn.providers.auth0.message': 'Se connecter avec Auth0', + 'signIn.providers.atlassian.title': 'Atlassian', + 'signIn.providers.atlassian.message': 'Se connecter avec Atlassian', + 'signIn.providers.microsoft.title': 'Microsoft', + 'signIn.providers.microsoft.message': 'Se connecter avec Microsoft', + 'signIn.providers.bitbucket.title': 'Bitbucket', + 'signIn.providers.bitbucket.message': 'Se connecter avec Bitbucket', + 'signIn.providers.bitbucketServer.title': 'Bitbucket Server', + 'signIn.providers.bitbucketServer.message': + 'Se connecter avec Bitbucket Server', + 'signIn.providers.github.title': 'GitHub', + 'signIn.providers.github.message': 'Se connecter avec GitHub', + 'signIn.providers.gitlab.title': 'GitLab', + 'signIn.providers.gitlab.message': 'Se connecter avec GitLab', + 'signIn.providers.google.title': 'Google', + 'signIn.providers.google.message': 'Se connecter avec Google', + 'signIn.providers.oidc.title': 'OIDC', + 'signIn.providers.oidc.message': 'Se connecter avec OIDC', + 'signIn.providers.okta.title': 'Okta', + 'signIn.providers.okta.message': 'Se connecter avec Okta', + 'signIn.providers.onelogin.title': 'OneLogin', + 'signIn.providers.onelogin.message': 'Se connecter avec OneLogin', + 'signIn.providers.saml.title': 'SAML', + 'signIn.providers.saml.message': 'Se connecter avec SAML', + + // App translations + 'app.scaffolder.title': 'Libre-service', + 'app.search.title': 'Rechercher', + 'app.search.resultType': 'Type de résultat', + 'app.search.softwareCatalog': 'Catalogue de logiciels', + 'app.search.filters.kind': 'Type', + 'app.search.filters.lifecycle': 'Cycle de vie', + 'app.search.filters.component': 'Composant', + 'app.search.filters.template': 'Modèle', + 'app.search.filters.experimental': 'expérimental', + 'app.search.filters.production': 'production', + 'app.learningPaths.title': "Parcours d'apprentissage", + 'app.learningPaths.error.title': 'Impossible de récupérer les données.', + 'app.learningPaths.error.unknownError': 'Erreur inconnue', + 'app.userSettings.infoCard.title': 'Métadonnées RHDH', + 'app.userSettings.infoCard.metadataCopied': + 'Métadonnées copiées dans le presse-papiers', + 'app.userSettings.infoCard.copyMetadata': + 'Copier les métadonnées dans le presse-papiers', + 'app.userSettings.infoCard.showLess': 'Afficher moins', + 'app.userSettings.infoCard.showMore': 'Afficher plus', + 'app.errors.contactSupport': 'Contacter le support', + 'app.errors.goBack': 'Retour', + 'app.errors.notFound.message': "Nous n'avons pas pu trouver cette page", + 'app.errors.notFound.additionalInfo': + 'La page que vous recherchez a peut-être été supprimée, renommée ou est temporairement indisponible.', + 'app.table.createdAt': 'Créé le', + }, +}); diff --git a/packages/app/src/translations/rhdh/index.ts b/packages/app/src/translations/rhdh/index.ts new file mode 100644 index 0000000000..040a12b946 --- /dev/null +++ b/packages/app/src/translations/rhdh/index.ts @@ -0,0 +1,34 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTranslationResource } from '@backstage/core-plugin-api/alpha'; + +import { rhdhTranslationRef } from './ref'; + +/** + * Translation Resource for RHDH Application + */ +export const rhdhTranslations = createTranslationResource({ + ref: rhdhTranslationRef, + translations: { + de: () => import('./de') as any, + fr: () => import('./fr') as any, + it: () => import('./it') as any, + es: () => import('./es') as any, + }, +}); + +export { rhdhTranslationRef }; diff --git a/packages/app/src/translations/rhdh/it.ts b/packages/app/src/translations/rhdh/it.ts new file mode 100644 index 0000000000..1762b05536 --- /dev/null +++ b/packages/app/src/translations/rhdh/it.ts @@ -0,0 +1,121 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; + +import { rhdhTranslationRef } from './ref'; + +export default createTranslationMessages({ + ref: rhdhTranslationRef, + full: true, // False means that this is a partial translation + messages: { + // Default main menu items from consts.ts + 'menuItem.home': 'Home', + 'menuItem.myGroup': 'Il Mio Gruppo', + 'menuItem.catalog': 'Catalogo', + 'menuItem.apis': 'API', + 'menuItem.learningPaths': 'Percorsi di Apprendimento', + 'menuItem.selfService': 'Self-service', + 'menuItem.userSettings': 'Impostazioni utente', + 'menuItem.administration': 'Amministrazione', + 'menuItem.extensions': 'Estensioni', + + // dynamic-plugins.default.main-menu-items + 'menuItem.clusters': 'Cluster', + 'menuItem.rbac': 'RBAC', + 'menuItem.bulkImport': 'Importazione in massa', + 'menuItem.docs': 'Documentazione', + 'menuItem.lighthouse': 'Lighthouse', + 'menuItem.techRadar': 'Radar tecnologico', + 'menuItem.orchestrator': 'Orchestratore', + 'menuItem.adoptionInsights': 'Insights di adozione', + + 'catalog.entityPage.overview.title': 'Panoramica', + 'catalog.entityPage.topology.title': 'Topologia', + 'catalog.entityPage.issues.title': 'Problemi', + 'catalog.entityPage.pullRequests.title': 'Pull/Merge Requests', + 'catalog.entityPage.ci.title': 'CI', + 'catalog.entityPage.cd.title': 'CD', + 'catalog.entityPage.kubernetes.title': 'Kubernetes', + 'catalog.entityPage.imageRegistry.title': 'Registro Immagini', + 'catalog.entityPage.monitoring.title': 'Monitoraggio', + 'catalog.entityPage.lighthouse.title': 'Lighthouse', + 'catalog.entityPage.api.title': 'API', + 'catalog.entityPage.dependencies.title': 'Dipendenze', + 'catalog.entityPage.docs.title': 'Documentazione', + 'catalog.entityPage.definition.title': 'Definizione', + 'catalog.entityPage.diagram.title': 'Diagramma del Sistema', + 'catalog.entityPage.workflows.title': 'Flussi di lavoro', + + 'sidebar.menu': 'Menu', + 'sidebar.home': 'Home', + 'sidebar.homeLogo': 'Logo principale', + + // SignIn page translations + 'signIn.page.title': 'Seleziona un metodo di accesso', + 'signIn.providers.auth0.title': 'Auth0', + 'signIn.providers.auth0.message': 'Accedi con Auth0', + 'signIn.providers.atlassian.title': 'Atlassian', + 'signIn.providers.atlassian.message': 'Accedi con Atlassian', + 'signIn.providers.microsoft.title': 'Microsoft', + 'signIn.providers.microsoft.message': 'Accedi con Microsoft', + 'signIn.providers.bitbucket.title': 'Bitbucket', + 'signIn.providers.bitbucket.message': 'Accedi con Bitbucket', + 'signIn.providers.bitbucketServer.title': 'Bitbucket Server', + 'signIn.providers.bitbucketServer.message': 'Accedi con Bitbucket Server', + 'signIn.providers.github.title': 'GitHub', + 'signIn.providers.github.message': 'Accedi con GitHub', + 'signIn.providers.gitlab.title': 'GitLab', + 'signIn.providers.gitlab.message': 'Accedi con GitLab', + 'signIn.providers.google.title': 'Google', + 'signIn.providers.google.message': 'Accedi con Google', + 'signIn.providers.oidc.title': 'OIDC', + 'signIn.providers.oidc.message': 'Accedi con OIDC', + 'signIn.providers.okta.title': 'Okta', + 'signIn.providers.okta.message': 'Accedi con Okta', + 'signIn.providers.onelogin.title': 'OneLogin', + 'signIn.providers.onelogin.message': 'Accedi con OneLogin', + 'signIn.providers.saml.title': 'SAML', + 'signIn.providers.saml.message': 'Accedi con SAML', + + // App translations + 'app.scaffolder.title': 'Self-service', + 'app.search.title': 'Cerca', + 'app.search.resultType': 'Tipo di risultato', + 'app.search.softwareCatalog': 'Catalogo software', + 'app.search.filters.kind': 'Tipo', + 'app.search.filters.lifecycle': 'Ciclo di vita', + 'app.search.filters.component': 'Componente', + 'app.search.filters.template': 'Modello', + 'app.search.filters.experimental': 'sperimentale', + 'app.search.filters.production': 'produzione', + 'app.learningPaths.title': 'Percorsi di apprendimento', + 'app.learningPaths.error.title': 'Impossibile recuperare i dati.', + 'app.learningPaths.error.unknownError': 'Errore sconosciuto', + 'app.userSettings.infoCard.title': 'Metadati RHDH', + 'app.userSettings.infoCard.metadataCopied': + 'Metadati copiati negli appunti', + 'app.userSettings.infoCard.copyMetadata': 'Copia metadati negli appunti', + 'app.userSettings.infoCard.showLess': 'Mostra meno', + 'app.userSettings.infoCard.showMore': 'Mostra di più', + 'app.errors.contactSupport': 'Contatta il supporto', + 'app.errors.goBack': 'Indietro', + 'app.errors.notFound.message': 'Non siamo riusciti a trovare quella pagina', + 'app.errors.notFound.additionalInfo': + 'La pagina che stai cercando potrebbe essere stata rimossa, rinominata o è temporaneamente non disponibile.', + 'app.table.createdAt': 'Creato il', + }, +}); diff --git a/packages/app/src/translations/rhdh/ref.ts b/packages/app/src/translations/rhdh/ref.ts new file mode 100644 index 0000000000..179a4bbc43 --- /dev/null +++ b/packages/app/src/translations/rhdh/ref.ts @@ -0,0 +1,213 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTranslationRef } from '@backstage/core-plugin-api/alpha'; + +/** + * Messages object containing all English translations. + * This is our single source of truth for translations. + */ +export const rhdhMessages = { + menuItem: { + // Default main menu items from consts.ts + home: 'Home', + myGroup: 'My Group', + catalog: 'Catalog', + apis: 'APIs', + learningPaths: 'Learning Paths', + selfService: 'Self-service', + userSettings: 'User Settings', + administration: 'Administration', + extensions: 'Extensions', + + // dynamic-plugins.default.main-menu-items + clusters: 'Clusters', + rbac: 'RBAC', + bulkImport: 'Bulk import', + docs: 'Docs', + lighthouse: 'Lighthouse', + techRadar: 'Tech Radar', + orchestrator: 'Orchestrator', + adoptionInsights: 'Adoption Insights', + }, + sidebar: { + menu: 'Menu', + home: 'Home', + homeLogo: 'Home logo', + }, + signIn: { + page: { + title: 'Select a sign-in method', + }, + providers: { + auth0: { + title: 'Auth0', + message: 'Sign in using Auth0', + }, + atlassian: { + title: 'Atlassian', + message: 'Sign in using Atlassian', + }, + microsoft: { + title: 'Microsoft', + message: 'Sign in using Microsoft', + }, + bitbucket: { + title: 'Bitbucket', + message: 'Sign in using Bitbucket', + }, + bitbucketServer: { + title: 'Bitbucket Server', + message: 'Sign in using Bitbucket Server', + }, + github: { + title: 'GitHub', + message: 'Sign in using GitHub', + }, + gitlab: { + title: 'GitLab', + message: 'Sign in using GitLab', + }, + google: { + title: 'Google', + message: 'Sign in using Google', + }, + oidc: { + title: 'OIDC', + message: 'Sign in using OIDC', + }, + okta: { + title: 'Okta', + message: 'Sign in using Okta', + }, + onelogin: { + title: 'OneLogin', + message: 'Sign in using OneLogin', + }, + saml: { + title: 'SAML', + message: 'Sign in using SAML', + }, + }, + }, + catalog: { + entityPage: { + overview: { + title: 'Overview', + }, + topology: { + title: 'Topology', + }, + issues: { + title: 'Issues', + }, + pullRequests: { + title: 'Pull/Merge Requests', + }, + ci: { + title: 'CI', + }, + cd: { + title: 'CD', + }, + kubernetes: { + title: 'Kubernetes', + }, + imageRegistry: { + title: 'Image Registry', + }, + monitoring: { + title: 'Monitoring', + }, + lighthouse: { + title: 'Lighthouse', + }, + api: { + title: 'API', + }, + dependencies: { + title: 'Dependencies', + }, + docs: { + title: 'Docs', + }, + definition: { + title: 'Definition', + }, + diagram: { + title: 'System Diagram', + }, + workflows: { + title: 'Workflows', + }, + }, + }, + app: { + scaffolder: { + title: 'Self-service', + }, + search: { + title: 'Search', + resultType: 'Result Type', + softwareCatalog: 'Software Catalog', + filters: { + kind: 'Kind', + lifecycle: 'Lifecycle', + component: 'Component', + template: 'Template', + experimental: 'experimental', + production: 'production', + }, + }, + learningPaths: { + title: 'Learning Paths', + error: { + title: 'Could not fetch data.', + unknownError: 'Unknown error', + }, + }, + userSettings: { + infoCard: { + title: 'RHDH Metadata', + metadataCopied: 'Metadata copied to clipboard', + copyMetadata: 'Copy metadata to your clipboard', + showLess: 'Show less', + showMore: 'Show more', + }, + }, + errors: { + contactSupport: 'Contact support', + goBack: 'Go back', + notFound: { + message: "We couldn't find that page", + additionalInfo: + 'The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.', + }, + }, + table: { + createdAt: 'Created At', + }, + }, +}; + +/** + * Translation reference for Quickstart plugin + * @public + */ +export const rhdhTranslationRef = createTranslationRef({ + id: 'rhdh', + messages: rhdhMessages, +}); diff --git a/packages/app/src/translations/scaffolder/scaffolder-en.ts b/packages/app/src/translations/scaffolder/scaffolder-en.ts new file mode 100644 index 0000000000..259e05d5a8 --- /dev/null +++ b/packages/app/src/translations/scaffolder/scaffolder-en.ts @@ -0,0 +1,13 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { scaffolderTranslationRef } from '@backstage/plugin-scaffolder/alpha'; + +const en = createTranslationMessages({ + ref: scaffolderTranslationRef, + full: false, // False means that this is a partial translation + messages: { + 'templateListPage.contentHeader.registerExistingButtonTitle': + 'Import an existing Git repository', + }, +}); + +export default en; diff --git a/packages/app/src/translations/scaffolder/scaffolder.ts b/packages/app/src/translations/scaffolder/scaffolder.ts new file mode 100644 index 0000000000..5976ba6f80 --- /dev/null +++ b/packages/app/src/translations/scaffolder/scaffolder.ts @@ -0,0 +1,9 @@ +import { createTranslationResource } from '@backstage/core-plugin-api/alpha'; +import { scaffolderTranslationRef } from '@backstage/plugin-scaffolder/alpha'; + +export const scaffolderTranslations = createTranslationResource({ + ref: scaffolderTranslationRef, + translations: { + en: () => import('./scaffolder-en'), + }, +}); diff --git a/packages/app/src/translations/search/search-de.ts b/packages/app/src/translations/search/search-de.ts new file mode 100644 index 0000000000..38530e9563 --- /dev/null +++ b/packages/app/src/translations/search/search-de.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { searchTranslationRef } from '@backstage/plugin-search/alpha'; + +const de = createTranslationMessages({ + ref: searchTranslationRef, + full: false, + messages: { + 'sidebarSearchModal.title': 'Suchen', + }, +}); + +export default de; diff --git a/packages/app/src/translations/search/search-en.ts b/packages/app/src/translations/search/search-en.ts new file mode 100644 index 0000000000..bb9705d1fd --- /dev/null +++ b/packages/app/src/translations/search/search-en.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { searchTranslationRef } from '@backstage/plugin-search/alpha'; + +const en = createTranslationMessages({ + ref: searchTranslationRef, + full: false, + messages: { + 'sidebarSearchModal.title': 'Search', + }, +}); + +export default en; diff --git a/packages/app/src/translations/search/search-es.ts b/packages/app/src/translations/search/search-es.ts new file mode 100644 index 0000000000..23f0e6277e --- /dev/null +++ b/packages/app/src/translations/search/search-es.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { searchTranslationRef } from '@backstage/plugin-search/alpha'; + +const es = createTranslationMessages({ + ref: searchTranslationRef, + full: false, + messages: { + 'sidebarSearchModal.title': 'Buscar', + }, +}); + +export default es; diff --git a/packages/app/src/translations/search/search-fr.ts b/packages/app/src/translations/search/search-fr.ts new file mode 100644 index 0000000000..e0ebca0c94 --- /dev/null +++ b/packages/app/src/translations/search/search-fr.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { searchTranslationRef } from '@backstage/plugin-search/alpha'; + +const fr = createTranslationMessages({ + ref: searchTranslationRef, + full: false, + messages: { + 'sidebarSearchModal.title': 'Rechercher', + }, +}); + +export default fr; diff --git a/packages/app/src/translations/search/search-it.ts b/packages/app/src/translations/search/search-it.ts new file mode 100644 index 0000000000..0f2f395693 --- /dev/null +++ b/packages/app/src/translations/search/search-it.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { searchTranslationRef } from '@backstage/plugin-search/alpha'; + +const it = createTranslationMessages({ + ref: searchTranslationRef, + full: false, + messages: { + 'sidebarSearchModal.title': 'Cerca', + }, +}); + +export default it; diff --git a/packages/app/src/translations/search/search.ts b/packages/app/src/translations/search/search.ts new file mode 100644 index 0000000000..606489d6f2 --- /dev/null +++ b/packages/app/src/translations/search/search.ts @@ -0,0 +1,13 @@ +import { createTranslationResource } from '@backstage/core-plugin-api/alpha'; +import { searchTranslationRef } from '@backstage/plugin-search/alpha'; + +export const searchTranslations = createTranslationResource({ + ref: searchTranslationRef, + translations: { + en: () => import('./search-en'), + de: () => import('./search-de'), + fr: () => import('./search-fr'), + es: () => import('./search-es'), + it: () => import('./search-it'), + }, +}); diff --git a/packages/app/src/translations/user-settings/user-settings-de.ts b/packages/app/src/translations/user-settings/user-settings-de.ts new file mode 100644 index 0000000000..8c31c88321 --- /dev/null +++ b/packages/app/src/translations/user-settings/user-settings-de.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; + +const de = createTranslationMessages({ + ref: userSettingsTranslationRef, + full: false, + messages: { + sidebarTitle: 'Einstellungen', + }, +}); + +export default de; diff --git a/packages/app/src/translations/user-settings/user-settings-en.ts b/packages/app/src/translations/user-settings/user-settings-en.ts new file mode 100644 index 0000000000..4257367281 --- /dev/null +++ b/packages/app/src/translations/user-settings/user-settings-en.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; + +const en = createTranslationMessages({ + ref: userSettingsTranslationRef, + full: false, + messages: { + sidebarTitle: 'Settings', + }, +}); + +export default en; diff --git a/packages/app/src/translations/user-settings/user-settings-es.ts b/packages/app/src/translations/user-settings/user-settings-es.ts new file mode 100644 index 0000000000..d21f1de512 --- /dev/null +++ b/packages/app/src/translations/user-settings/user-settings-es.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; + +const es = createTranslationMessages({ + ref: userSettingsTranslationRef, + full: false, + messages: { + sidebarTitle: 'Configuración', + }, +}); + +export default es; diff --git a/packages/app/src/translations/user-settings/user-settings-fr.ts b/packages/app/src/translations/user-settings/user-settings-fr.ts new file mode 100644 index 0000000000..87237e58a5 --- /dev/null +++ b/packages/app/src/translations/user-settings/user-settings-fr.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; + +const fr = createTranslationMessages({ + ref: userSettingsTranslationRef, + full: false, + messages: { + sidebarTitle: 'Paramètres', + }, +}); + +export default fr; diff --git a/packages/app/src/translations/user-settings/user-settings-it.ts b/packages/app/src/translations/user-settings/user-settings-it.ts new file mode 100644 index 0000000000..2cf4d71a32 --- /dev/null +++ b/packages/app/src/translations/user-settings/user-settings-it.ts @@ -0,0 +1,12 @@ +import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; + +const it = createTranslationMessages({ + ref: userSettingsTranslationRef, + full: false, + messages: { + sidebarTitle: 'Impostazioni', + }, +}); + +export default it; diff --git a/packages/app/src/translations/user-settings/user-settings.ts b/packages/app/src/translations/user-settings/user-settings.ts new file mode 100644 index 0000000000..27d8f52393 --- /dev/null +++ b/packages/app/src/translations/user-settings/user-settings.ts @@ -0,0 +1,13 @@ +import { createTranslationResource } from '@backstage/core-plugin-api/alpha'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; + +export const userSettingsTranslations = createTranslationResource({ + ref: userSettingsTranslationRef, + translations: { + en: () => import('./user-settings-en'), + de: () => import('./user-settings-de'), + fr: () => import('./user-settings-fr'), + es: () => import('./user-settings-es'), + it: () => import('./user-settings-it'), + }, +}); diff --git a/packages/app/src/types/types.ts b/packages/app/src/types/types.ts index 71f64543ef..87002175d8 100644 --- a/packages/app/src/types/types.ts +++ b/packages/app/src/types/types.ts @@ -1,3 +1,5 @@ +import { TranslationResource } from '@backstage/core-plugin-api/alpha'; + export type LearningPathLink = { label: string; url: string; @@ -8,7 +10,44 @@ export type LearningPathLink = { }; export type BuildInfo = { - title: string; + title?: string; + titleKey?: string; card: { [key: string]: string }; full?: boolean; + overrideBuildInfo?: boolean; +}; + +export type TranslationConfig = { + defaultLocale?: string; + locales: string[]; + overrides?: string[]; +}; + +export type JSONTranslationConfig = { + locale: string; + path: string; }; + +export type DynamicTranslationResource = { + scope: string; + module: string; + importName: string; + ref?: string | null; + jsonTranslations?: JSONTranslationConfig[]; +}; + +// Types from Backstage core-plugin-api do not expose loader function type +// so we need to create our own internal types to access the loader function + +type InternalTranslationResourceLoader = () => Promise<{ + messages: { [key in string]: string | null }; +}>; + +export interface InternalTranslationResource + extends TranslationResource { + version: 'v1'; + resources: { + language: string; + loader: InternalTranslationResourceLoader; + }[]; +} diff --git a/packages/app/src/utils/dynamicUI/extractDynamicConfig.test.ts b/packages/app/src/utils/dynamicUI/extractDynamicConfig.test.ts index 63671b9489..94a3e653b8 100644 --- a/packages/app/src/utils/dynamicUI/extractDynamicConfig.test.ts +++ b/packages/app/src/utils/dynamicUI/extractDynamicConfig.test.ts @@ -162,6 +162,7 @@ describe('extractDynamicConfig', () => { signInPages: [], techdocsAddons: [], themes: [], + translationResources: [], }); }); @@ -720,6 +721,7 @@ describe('extractDynamicConfig', () => { techdocsAddons: [], themes: [], providerSettings: [], + translationResources: [], ...output, }); }); diff --git a/packages/app/src/utils/dynamicUI/extractDynamicConfig.ts b/packages/app/src/utils/dynamicUI/extractDynamicConfig.ts index 84d31b1ca3..df807c0497 100644 --- a/packages/app/src/utils/dynamicUI/extractDynamicConfig.ts +++ b/packages/app/src/utils/dynamicUI/extractDynamicConfig.ts @@ -9,11 +9,13 @@ import { } from '@red-hat-developer-hub/plugin-utils'; import { hasAnnotation, isType } from '../../components/catalog/utils'; +import { DynamicTranslationResource } from '../../types/types'; import { extractMenuItems } from './extractDynamicConfigFrontend'; export type DynamicRouteMenuItem = | { text: string; + textKey?: string; icon: string; parent?: string; priority?: number; @@ -37,6 +39,7 @@ export type MenuItemConfig = { export type MenuItem = { name: string; title: string; + titleKey?: string; icon: string; children: MenuItem[]; priority?: number; @@ -114,6 +117,7 @@ type EntityTab = { mountPoint: string; path: string; title: string; + titleKey?: string; pariority?: number; }; @@ -122,6 +126,7 @@ type EntityTabEntry = { mountPoint: string; path: string; title: string; + titleKey?: string; priority?: number; }; @@ -171,6 +176,7 @@ type CustomProperties = { signInPage: SignInPageEntry; techdocsAddons?: TechdocsAddon[]; themes?: ThemeEntry[]; + translationResources?: DynamicTranslationResource[]; }; export type FrontendConfig = { @@ -197,6 +203,7 @@ type DynamicConfig = { signInPages: SignInPageEntry[]; techdocsAddons: TechdocsAddon[]; themes: ThemeEntry[]; + translationResources: DynamicTranslationResource[]; }; /** @@ -223,6 +230,7 @@ function extractDynamicConfig( signInPages: [], techdocsAddons: [], themes: [], + translationResources: [], }; config.signInPages = Object.entries(frontend).reduce( (pluginSet, [scope, { signInPage }]) => { @@ -398,6 +406,23 @@ function extractDynamicConfig( }, [], ); + + config.translationResources = Object.entries(frontend).reduce< + DynamicTranslationResource[] + >((accTranslationResources, [scope, { translationResources }]) => { + accTranslationResources.push( + ...(translationResources ?? []).map(resource => ({ + ...resource, + module: resource.module ?? 'PluginRoot', + importName: resource.importName ?? 'default', + ref: resource.ref ?? null, + jsonTranslations: resource.jsonTranslations ?? [], + scope, + })), + ); + return accTranslationResources; + }, []); + return config; } diff --git a/packages/app/src/utils/dynamicUI/extractDynamicConfigFrontend.ts b/packages/app/src/utils/dynamicUI/extractDynamicConfigFrontend.ts index c1e8c21e32..cd090b387c 100644 --- a/packages/app/src/utils/dynamicUI/extractDynamicConfigFrontend.ts +++ b/packages/app/src/utils/dynamicUI/extractDynamicConfigFrontend.ts @@ -89,6 +89,7 @@ export function extractMenuItems(frontend: FrontendConfig): MenuItem[] { name: itemName, icon: 'icon' in mi && mi.icon ? mi.icon : '', title: 'text' in mi && mi.text ? mi.text : '', + titleKey: 'textKey' in mi && mi.textKey ? mi.textKey : undefined, to: dr.path ?? '', children: [], enabled: 'enabled' in mi ? mi.enabled : true, diff --git a/packages/app/src/utils/dynamicUI/initializeRemotePlugins.ts b/packages/app/src/utils/dynamicUI/initializeRemotePlugins.ts index bc7e60c247..6c06b5f4be 100644 --- a/packages/app/src/utils/dynamicUI/initializeRemotePlugins.ts +++ b/packages/app/src/utils/dynamicUI/initializeRemotePlugins.ts @@ -4,10 +4,7 @@ import { ScalprumState } from '@scalprum/react-core'; import { RemotePlugins } from '../../components/DynamicRoot/DynamicRoot'; // See packages/app/src/App.tsx -const ignoreStaticPlugins = [ - 'default.main-menu-items', - 'internal.plugin-dynamic-plugins-info', -]; +const ignoreStaticPlugins = ['default.main-menu-items']; const initializeRemotePlugins = async ( pluginStore: ScalprumState['pluginStore'], diff --git a/packages/app/src/utils/language/language.test.ts b/packages/app/src/utils/language/language.test.ts new file mode 100644 index 0000000000..e76da4afc6 --- /dev/null +++ b/packages/app/src/utils/language/language.test.ts @@ -0,0 +1,506 @@ +import { TranslationConfig } from '../../types/types'; +import { getDefaultLanguage } from './language'; + +// Mock navigator for testing +const mockNavigator = { + languages: ['en-US', 'en', 'fr-FR'], + language: 'en-US', +}; + +// Mock the global navigator +Object.defineProperty(global, 'navigator', { + value: mockNavigator, + writable: true, +}); + +describe('getDefaultLanguage', () => { + beforeEach(() => { + // Reset navigator mock before each test + Object.defineProperty(global, 'navigator', { + value: mockNavigator, + writable: true, + }); + }); + + describe('Priority 1: browser language matching', () => { + it('should use browser language when it matches available locales exactly', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de'], + // No defaultLocale set + }; + + // Mock navigator to have 'fr' as first language + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr', 'en', 'de'], + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); + }); + + it('should use base language when browser has region-specific language', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de'], + // No defaultLocale set + }; + + // Mock navigator to have 'fr-FR' as first language + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr-FR', 'en-US', 'de-DE'], + language: 'fr-FR', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); + }); + + it('should prioritize browser language over defaultLocale configuration', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de'], + defaultLocale: 'de', // This should be ignored when browser language matches + }; + + // Mock navigator to have 'fr' as first language + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr', 'en', 'de'], + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); // Should use browser language, not defaultLocale + }); + + it('should handle multiple region-specific languages', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de', 'es'], + // No defaultLocale set + }; + + // Mock navigator to have multiple region-specific languages + Object.defineProperty(global, 'navigator', { + value: { + languages: ['es-ES', 'fr-FR', 'en-US', 'de-DE'], + language: 'es-ES', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('es'); + }); + + it('should fallback to second browser language when first is not supported', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'de'], + // No defaultLocale set + }; + + // Mock navigator to have 'fr' as first language (not supported) and 'de' as second + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr', 'de', 'en'], + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('de'); + }); + + it('should use base language from second browser language when first is not supported', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'de'], + // No defaultLocale set + }; + + // Mock navigator to have 'fr' as first language (not supported) and 'de-DE' as second + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr', 'de-DE', 'en-US'], + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('de'); + }); + + it('should prioritize exact matches over base language matches', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'en-US', 'fr', 'fr-FR'], + // No defaultLocale set + }; + + // Mock navigator to have both exact and base language matches + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr', 'en-US', 'de'], + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + // Should use 'fr' (exact match) instead of 'en' (base language match) + expect(result).toBe('fr'); + }); + + it('should handle mixed exact and base language matches in browser languages', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de'], + // No defaultLocale set + }; + + // Mock navigator to have mixed exact and base language matches + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr-FR', 'en', 'de-DE'], + language: 'fr-FR', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); // Should use base language from 'fr-FR' + }); + }); + + describe('Priority 2: translationConfig.defaultLocale fallback', () => { + it('should use defaultLocale when browser language does not match available locales', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de'], + defaultLocale: 'fr', + }; + + // Mock navigator to have unsupported languages + Object.defineProperty(global, 'navigator', { + value: { + languages: ['es', 'it', 'pt'], + language: 'es', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); // Should use defaultLocale as fallback + }); + + it('should use defaultLocale when browser language is not supported', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de'], + defaultLocale: 'de', + }; + + // Mock navigator to have unsupported languages + Object.defineProperty(global, 'navigator', { + value: { + languages: ['ja', 'ko', 'zh'], + language: 'ja', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('de'); // Should use defaultLocale as fallback + }); + + it('should prioritize browser language over defaultLocale when both are available', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de'], + defaultLocale: 'de', + }; + + // Mock navigator to have supported language + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr', 'en', 'de'], + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); // Should use browser language, not defaultLocale + }); + }); + + describe('Priority 3: fallback to "en"', () => { + it('should default to "en" when no browser language is supported and no defaultLocale is configured', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'de'], + // No defaultLocale set + }; + + // Mock navigator to have only unsupported languages + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr', 'es', 'it'], + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('en'); + }); + + it('should default to "en" when translationConfig is undefined', () => { + const result = getDefaultLanguage(undefined); + expect(result).toBe('en'); + }); + + it('should default to "en" when translationConfig.locales is empty', () => { + const translationConfig: TranslationConfig = { + locales: [], + // No defaultLocale set + }; + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('en'); + }); + + it('should default to "en" when translationConfig.locales only contains unsupported languages', () => { + const translationConfig: TranslationConfig = { + locales: ['fr', 'de'], + // No defaultLocale set + }; + + // Mock navigator to have only unsupported languages + Object.defineProperty(global, 'navigator', { + value: { + languages: ['es', 'it', 'pt'], + language: 'es', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('en'); + }); + }); + + describe('Edge cases and error handling', () => { + it('should handle navigator.languages being undefined', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr'], + // No defaultLocale set + }; + + // Mock navigator to have undefined languages + Object.defineProperty(global, 'navigator', { + value: { + languages: undefined, + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); + }); + + it('should handle navigator.language being undefined', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr'], + // No defaultLocale set + }; + + // Mock navigator to have undefined language + Object.defineProperty(global, 'navigator', { + value: { + languages: ['fr', 'en'], + language: undefined, + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); + }); + + it('should handle both navigator.languages and navigator.language being undefined', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr'], + // No defaultLocale set + }; + + // Mock navigator to have undefined languages and language + Object.defineProperty(global, 'navigator', { + value: { + languages: undefined, + language: undefined, + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('en'); + }); + + it('should handle empty browser languages array', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr'], + // No defaultLocale set + }; + + // Mock navigator to have empty languages array + Object.defineProperty(global, 'navigator', { + value: { + languages: [], + language: 'fr', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); + }); + + it('should handle browser languages with empty strings', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr'], + // No defaultLocale set + }; + + // Mock navigator to have empty strings in languages array + Object.defineProperty(global, 'navigator', { + value: { + languages: ['', 'fr', 'en'], + language: '', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); // Should skip empty string and use 'fr' + }); + + it('should handle browser languages with null/undefined values', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr'], + // No defaultLocale set + }; + + // Mock navigator to have null/undefined values in languages array + Object.defineProperty(global, 'navigator', { + value: { + languages: [null, undefined, 'fr', 'en'], + language: null, + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('fr'); // Should skip null/undefined and use 'fr' + }); + + it('should handle language codes with multiple hyphens', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'zh', 'zh-CN'], + // No defaultLocale set + }; + + // Mock navigator to have language codes with multiple hyphens + Object.defineProperty(global, 'navigator', { + value: { + languages: ['zh-CN-Hans', 'en-US'], + language: 'zh-CN-Hans', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('zh'); // Should extract 'zh' from 'zh-CN-Hans' + }); + + it('should handle single-character language codes', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'a', 'b'], + // No defaultLocale set + }; + + // Mock navigator to have single-character language codes + Object.defineProperty(global, 'navigator', { + value: { + languages: ['a', 'b', 'en'], + language: 'a', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('a'); + }); + }); + + describe('Real-world scenarios', () => { + it('should handle common browser language combinations', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'fr', 'de', 'es'], + // No defaultLocale set + }; + + // Common browser language combination: English (US), English, French (Canada) + Object.defineProperty(global, 'navigator', { + value: { + languages: ['en-US', 'en', 'fr-CA'], + language: 'en-US', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('en'); // Should use base language from 'en-US' + }); + + it('should handle European browser language preferences', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'de', 'fr', 'it'], + // No defaultLocale set + }; + + // European browser language preference: German (Germany), English (US), French (France) + Object.defineProperty(global, 'navigator', { + value: { + languages: ['de-DE', 'en-US', 'fr-FR'], + language: 'de-DE', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('de'); // Should use base language from 'de-DE' + }); + + it('should handle Asian browser language preferences', () => { + const translationConfig: TranslationConfig = { + locales: ['en', 'zh', 'ja', 'ko'], + // No defaultLocale set + }; + + // Asian browser language preference: Chinese (Simplified), English (US) + Object.defineProperty(global, 'navigator', { + value: { + languages: ['zh-CN', 'en-US'], + language: 'zh-CN', + }, + writable: true, + }); + + const result = getDefaultLanguage(translationConfig); + expect(result).toBe('zh'); // Should use base language from 'zh-CN' + }); + }); +}); diff --git a/packages/app/src/utils/language/language.ts b/packages/app/src/utils/language/language.ts new file mode 100644 index 0000000000..35df8df6c1 --- /dev/null +++ b/packages/app/src/utils/language/language.ts @@ -0,0 +1,50 @@ +import { TranslationConfig } from '../../types/types'; + +/** + * Determines the default language: + */ +export const getDefaultLanguage = ( + translationConfig?: TranslationConfig, +): string => { + // Priority 1: try to use browser language if supported + const availableLocales = translationConfig?.locales ?? ['en']; + const browserLanguages = navigator.languages || [navigator.language]; + + // Find the first browser language that's supported + for (const browserLang of browserLanguages) { + if (!browserLang || typeof browserLang !== 'string') { + continue; + } + + if (availableLocales.includes(browserLang)) { + return browserLang; + } + + // Also check language codes without region (e.g., 'en' from 'en-US') + const baseLang = browserLang.split('-')[0]; + if (baseLang && availableLocales.includes(baseLang)) { + return baseLang; + } + } + + // If navigator.languages is empty or doesn't contain supported languages, + // also check navigator.language as a fallback + if (navigator.language && typeof navigator.language === 'string') { + if (availableLocales.includes(navigator.language)) { + return navigator.language; + } + + // Check base language from navigator.language + const baseLang = navigator.language.split('-')[0]; + if (baseLang && availableLocales.includes(baseLang)) { + return baseLang; + } + } + + // Priority 2: admin configured default locale (fallback) + if (translationConfig?.defaultLocale) { + return translationConfig.defaultLocale; + } + + return 'en'; +}; diff --git a/packages/app/src/utils/test/TestRoot.tsx b/packages/app/src/utils/test/TestRoot.tsx index d533d17bc1..b8d09b7263 100644 --- a/packages/app/src/utils/test/TestRoot.tsx +++ b/packages/app/src/utils/test/TestRoot.tsx @@ -45,6 +45,7 @@ const TestRoot = ({ children }: PropsWithChildren<{}>) => { scaffolderFieldExtensions: [], providerSettings: [], techdocsAddons: [], + translationRefs: [], }), [current], ); diff --git a/packages/app/src/utils/translations/fetchOverrideTranslations.ts b/packages/app/src/utils/translations/fetchOverrideTranslations.ts new file mode 100644 index 0000000000..4922898b41 --- /dev/null +++ b/packages/app/src/utils/translations/fetchOverrideTranslations.ts @@ -0,0 +1,21 @@ +export const fetchOverrideTranslations = async ( + baseUrl: string, +): Promise>>> => { + try { + const res = await fetch(`${baseUrl}/api/translations`); + if (!res.ok) { + let errorMessage = `/api/translation Request failed with status ${res.status}`; + const errorBody = await res.json(); + if (errorBody?.error) { + errorMessage += `: ${errorBody.error}`; + } + + // eslint-disable-next-line no-console + console.warn(errorMessage); + return {}; + } + return res.json(); + } catch (err) { + return {}; + } +}; diff --git a/packages/app/src/utils/translations/index.ts b/packages/app/src/utils/translations/index.ts new file mode 100644 index 0000000000..2d9572bed7 --- /dev/null +++ b/packages/app/src/utils/translations/index.ts @@ -0,0 +1,3 @@ +export { fetchOverrideTranslations } from './fetchOverrideTranslations'; +export { translationResourceGenerator } from './translationResourceGenerator'; +export { getTranslatedTextWithFallback } from './translationUtils'; diff --git a/packages/app/src/utils/translations/staticTranslationConfigs.ts b/packages/app/src/utils/translations/staticTranslationConfigs.ts new file mode 100644 index 0000000000..2a993ebe64 --- /dev/null +++ b/packages/app/src/utils/translations/staticTranslationConfigs.ts @@ -0,0 +1,87 @@ +import { coreComponentsTranslationRef } from '@backstage/core-components/alpha'; +import { + createTranslationResource, + TranslationRef, + TranslationResource, +} from '@backstage/core-plugin-api/alpha'; +import { apiDocsTranslationRef } from '@backstage/plugin-api-docs/alpha'; +import { catalogGraphTranslationRef } from '@backstage/plugin-catalog-graph/alpha'; +import { catalogImportTranslationRef } from '@backstage/plugin-catalog-import/alpha'; +import { catalogReactTranslationRef } from '@backstage/plugin-catalog-react/alpha'; +import { catalogTranslationRef } from '@backstage/plugin-catalog/alpha'; +import { orgTranslationRef } from '@backstage/plugin-org/alpha'; +import { scaffolderReactTranslationRef } from '@backstage/plugin-scaffolder-react/alpha'; +import { scaffolderTranslationRef } from '@backstage/plugin-scaffolder/alpha'; +import { searchReactTranslationRef } from '@backstage/plugin-search-react/alpha'; +import { searchTranslationRef } from '@backstage/plugin-search/alpha'; +import { userSettingsTranslationRef } from '@backstage/plugin-user-settings/alpha'; + +import { + translationsPluginTranslationRef, + translationsPluginTranslations, +} from '@red-hat-developer-hub/backstage-plugin-translations/alpha'; + +import { catalogTranslations } from '../../components/catalog/translations/catalog'; +import { catalogImportTranslations } from '../../translations/catalog-import/catalog-import'; +import { coreComponentsTranslations } from '../../translations/core-components/core-components'; +import { rhdhTranslationRef, rhdhTranslations } from '../../translations/rhdh'; +import { scaffolderTranslations } from '../../translations/scaffolder/scaffolder'; +import { userSettingsTranslations } from '../../translations/user-settings/user-settings'; + +export interface StaticTranslationConfig { + resource: TranslationResource; + ref: TranslationRef; +} + +/** + * Static translation configurations for core Backstage components and RHDH translation plugin + */ +export const staticTranslationConfigs: StaticTranslationConfig[] = [ + { + resource: coreComponentsTranslations, + ref: coreComponentsTranslationRef, + }, + { + resource: userSettingsTranslations, + ref: userSettingsTranslationRef, + }, + { + resource: catalogTranslations, + ref: catalogTranslationRef, + }, + { + resource: scaffolderTranslations, + ref: scaffolderTranslationRef, + }, + { + resource: catalogImportTranslations, + ref: catalogImportTranslationRef, + }, + { + resource: translationsPluginTranslations, + ref: translationsPluginTranslationRef, + }, + + { + resource: rhdhTranslations, + ref: rhdhTranslationRef, + }, + ...[ + catalogReactTranslationRef, + scaffolderTranslationRef, + userSettingsTranslationRef, + searchTranslationRef, + searchReactTranslationRef, + scaffolderReactTranslationRef, + apiDocsTranslationRef, + catalogGraphTranslationRef, + orgTranslationRef, + userSettingsTranslationRef, + ].map((ref: TranslationRef) => ({ + resource: createTranslationResource({ + ref, + translations: {}, + }), + ref, + })), +]; diff --git a/packages/app/src/utils/translations/translationResourceGenerator.test.ts b/packages/app/src/utils/translations/translationResourceGenerator.test.ts new file mode 100644 index 0000000000..9c0887642d --- /dev/null +++ b/packages/app/src/utils/translations/translationResourceGenerator.test.ts @@ -0,0 +1,93 @@ +import { + createTranslationMessages, + createTranslationResource, + TranslationRef, +} from '@backstage/core-plugin-api/alpha'; + +import { translationResourceGenerator } from './translationResourceGenerator'; + +jest.mock('@backstage/core-plugin-api/alpha'); + +describe('translationResourceGenerator', () => { + let mockRef: TranslationRef; + const baseResource = { + $$type: '' as any, + id: 'test.translation', + version: 'v1' as any, + resources: [ + { + language: 'en', + loader: async () => ({ + messages: { + hello: 'Hello', + bye: 'Goodbye', + }, + }), + }, + { + language: 'fr', + loader: async () => ({ + messages: { + hello: 'Bonjour', + bye: 'Au revoir', + }, + }), + }, + ], + }; + + beforeEach(() => { + jest.resetAllMocks(); + mockRef = { id: 'test.translation' } as TranslationRef; + }); + + it('should merge base translations with JSON overrides', async () => { + const jsonTranslations = { + en: { + bye: 'See ya', + welcome: 'Welcome', + }, + }; + + (createTranslationMessages as jest.Mock).mockImplementation( + ({ ref, messages }) => ({ ref, messages }), + ); + (createTranslationResource as jest.Mock).mockImplementation( + ({ ref, translations }) => ({ ref, translations }), + ); + + const resource = translationResourceGenerator( + mockRef, + baseResource, + jsonTranslations, + ); + + const enMessages = await (resource as any).translations?.en(); + expect(enMessages.default.messages).toEqual({ + hello: 'Hello', + bye: 'See ya', + welcome: 'Welcome', + }); + }); + it('should create new translation resource for the locale not present in base resource', async () => { + const jsonTranslations = { + ko: { hello: 'annyeonghaseyo' }, + }; + + (createTranslationMessages as jest.Mock).mockImplementation( + ({ ref, messages }) => ({ ref, messages }), + ); + (createTranslationResource as jest.Mock).mockImplementation( + ({ ref, translations }) => ({ ref, translations }), + ); + + const resource = translationResourceGenerator( + mockRef, + baseResource, + jsonTranslations, + ); + const translations = await (resource as any).translations; + + expect(Object.keys(translations)).toContain('ko'); + }); +}); diff --git a/packages/app/src/utils/translations/translationResourceGenerator.ts b/packages/app/src/utils/translations/translationResourceGenerator.ts new file mode 100644 index 0000000000..82e38a5bdb --- /dev/null +++ b/packages/app/src/utils/translations/translationResourceGenerator.ts @@ -0,0 +1,86 @@ +import { + createTranslationMessages, + createTranslationResource, + TranslationRef, + TranslationResource, +} from '@backstage/core-plugin-api/alpha'; + +import { InternalTranslationResource } from '../../types/types'; + +const createTranslationMessagesWrapper = ( + ref: TranslationRef, + messages: { [key: string]: string }, + full: boolean = false, +) => { + return { + default: createTranslationMessages({ + ref, + full, + messages, + }), + }; +}; + +const mergeTranslations = ( + resource: InternalTranslationResource, + jsonTranslations: { [key: string]: any }, + ref: TranslationRef, +) => { + const resourceWithNewTranslations: Record = {}; + for (const res of resource.resources) { + // update translations for existing locale(s) + if (jsonTranslations[res.language]) { + resourceWithNewTranslations[res.language] = async () => { + const overrides: { [key: string]: string } = + jsonTranslations[res.language]; + const baseMessages = await res.loader(); + + const mergedMessages = { + ...baseMessages.messages, + ...overrides, + } as { [key: string]: string }; + + return createTranslationMessagesWrapper(ref, mergedMessages, false); + }; + } else { + // create translation resource for new/default locale(s) based on default resources + resourceWithNewTranslations[res.language] = async () => { + const baseMessages = await res.loader(); + return createTranslationMessagesWrapper( + ref, + baseMessages.messages as { [key: string]: string }, + false, + ); + }; + } + } + + // create translation resource for new locale(s) based on jsonTranslations passed + for (const [locale] of Object.entries(jsonTranslations)) { + if (!resourceWithNewTranslations[locale]) { + resourceWithNewTranslations[locale] = async () => { + const newLocaleTranslations: { [key: string]: string } = + jsonTranslations[locale]; + + return createTranslationMessagesWrapper( + ref, + newLocaleTranslations, + false, + ); + }; + } + } + + return resourceWithNewTranslations; +}; + +export const translationResourceGenerator = ( + ref: TranslationRef, + resource: InternalTranslationResource, + jsonTranslations: { [key: string]: any }, +): TranslationResource => { + return createTranslationResource({ + ref, + translations: mergeTranslations(resource, jsonTranslations, ref), + }); +}; diff --git a/packages/app/src/utils/translations/translationResourceProcessor.ts b/packages/app/src/utils/translations/translationResourceProcessor.ts new file mode 100644 index 0000000000..1c14cfbe1d --- /dev/null +++ b/packages/app/src/utils/translations/translationResourceProcessor.ts @@ -0,0 +1,182 @@ +import { + TranslationRef, + TranslationResource, +} from '@backstage/core-plugin-api/alpha'; + +import { InternalTranslationResource } from '../../types/types'; +import { translationResourceGenerator } from './translationResourceGenerator'; + +export interface TranslationResourceWithRef { + resource: TranslationResource; + ref: TranslationRef; +} + +export interface PluginTranslationConfig { + scope: string; + module: string; + importName: string; + ref?: string | null; +} + +export interface StaticTranslationConfig { + resource: TranslationResource; + ref: TranslationRef; +} + +/** + * Processes a single plugin translation resource + */ +export function processPluginTranslationResource( + config: PluginTranslationConfig, + allPlugins: Record, + overrideTranslations: Record>>, +): TranslationResource | null { + const { scope, module, importName, ref } = config; + const plugin = allPlugins[scope]?.[module]; + const resource = plugin?.[importName] as InternalTranslationResource; + const resourceRef = ref + ? (plugin?.[ref] as any as TranslationRef) + : null; + + if (!resource?.id) { + // eslint-disable-next-line no-console + console.warn( + `Plugin ${scope} is not configured properly: ${module}.${importName} not found, ignoring translation resource: ${importName}`, + ); + return null; + } + + const hasJsonOverrides = overrideTranslations[resource.id]; + + if (hasJsonOverrides) { + if (!resourceRef) { + // eslint-disable-next-line no-console + console.warn( + `Plugin translation ref for ${scope} is not configured, ignoring JSON translation for this plugin`, + ); + return resource; + } + + return translationResourceGenerator( + resourceRef, + resource, + overrideTranslations[resource.id], + ); + } + + return resource; +} + +/** + * Processes a single static translation resource + */ +export function processStaticTranslationResource( + config: StaticTranslationConfig, + overrideTranslations: Record>>, +): TranslationResource { + const { resource, ref } = config; + const hasJsonOverrides = overrideTranslations[resource?.id]; + + if (hasJsonOverrides) { + return translationResourceGenerator( + ref, + resource as any as InternalTranslationResource, + overrideTranslations[resource.id], + ); + } + + return resource; +} + +/** + * Processes multiple plugin translation resources + */ +export function processPluginTranslationResources( + translationResources: PluginTranslationConfig[], + allPlugins: Record, + overrideTranslations: Record>>, +): { + resources: TranslationResource[]; + refs: TranslationRef[]; +} { + const resources: TranslationResource[] = []; + const refs: TranslationRef[] = []; + + translationResources.forEach(config => { + const resource = processPluginTranslationResource( + config, + allPlugins, + overrideTranslations, + ); + + if (resource) { + resources.push(resource); + + // Add ref if it exists + const plugin = allPlugins[config.scope]?.[config.module]; + const resourceRef = config.ref + ? (plugin?.[config.ref] as any as TranslationRef) + : null; + + if (resourceRef) { + refs.push(resourceRef); + } + } + }); + + return { resources, refs }; +} + +/** + * Processes multiple static translation resources + */ +export function processStaticTranslationResources( + translationResources: StaticTranslationConfig[], + overrideTranslations: Record>>, +): { + resources: TranslationResource[]; + refs: TranslationRef[]; +} { + const resources: TranslationResource[] = []; + const refs: TranslationRef[] = []; + + translationResources.forEach(config => { + const resource = processStaticTranslationResource( + config, + overrideTranslations, + ); + resources.push(resource); + refs.push(config.ref); + }); + + return { resources, refs }; +} + +/** + * Main function to process all translation resources + */ +export function processAllTranslationResources( + dynamicTranslationResources: PluginTranslationConfig[], + staticTranslationResources: StaticTranslationConfig[], + allPlugins: Record, + overrideTranslations: Record>>, +): { + allResources: TranslationResource[]; + allRefs: TranslationRef[]; +} { + const dynamicResult = processPluginTranslationResources( + dynamicTranslationResources, + allPlugins, + overrideTranslations, + ); + + const staticResult = processStaticTranslationResources( + staticTranslationResources, + overrideTranslations, + ); + + return { + allResources: [...dynamicResult.resources, ...staticResult.resources], + allRefs: [...dynamicResult.refs, ...staticResult.refs], + }; +} diff --git a/packages/app/src/utils/translations/translationUtils.ts b/packages/app/src/utils/translations/translationUtils.ts new file mode 100644 index 0000000000..42bad0ee6b --- /dev/null +++ b/packages/app/src/utils/translations/translationUtils.ts @@ -0,0 +1,39 @@ +/* + * Copyright Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { TranslationFunction } from '@backstage/core-plugin-api/alpha'; + +import { rhdhTranslationRef } from '../../translations/rhdh'; + +/** + * Utility function to get translated text with fallback to original text + * + * @param t - Translation function + * @param translationKey - Optional translation key to look up + * @param fallbackText - Text to display if translation key is not provided or translation is not found + * @returns Translated text or fallback text + */ +export const getTranslatedTextWithFallback = ( + t: TranslationFunction, + translationKey: string | undefined, + fallbackText: string, +): string => { + if (!translationKey) { + return fallbackText; + } + + const translation = t(translationKey as keyof typeof t, {}); + return translation !== translationKey ? translation : fallbackText; +}; diff --git a/packages/backend/package.json b/packages/backend/package.json index bb04d08f17..3f206e6452 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -9,6 +9,7 @@ }, "scripts": { "start": "backstage-cli package start --require ./src/instrumentation.js", + "start:next": "APP_CONFIG_app_packageName=app-next ENABLE_STANDARD_MODULE_FEDERATION=true backstage-cli package start --require ./src/instrumentation.js", "start:prometheus": "docker run --mount type=bind,source=./prometheus.yml,destination=/etc/prometheus/prometheus.yml --publish published=9090,target=9090,protocol=tcp prom/prometheus", "build": "backstage-cli package build", "lint:check": "backstage-cli package lint", @@ -20,49 +21,50 @@ "prettier:fix": "prettier --ignore-unknown --write ." }, "dependencies": { - "@backstage-community/plugin-rbac-backend": "7.0.0", - "@backstage-community/plugin-rbac-node": "1.12.0", + "@backstage-community/plugin-rbac-backend": "7.4.0", + "@backstage-community/plugin-rbac-node": "1.14.0", "@backstage-community/plugin-scaffolder-backend-module-annotator": "2.8.0", - "@backstage/backend-app-api": "1.2.3", - "@backstage/backend-defaults": "0.10.0", - "@backstage/backend-dynamic-feature-service": "0.7.0", - "@backstage/backend-plugin-api": "1.3.1", - "@backstage/catalog-client": "1.10.0", - "@backstage/catalog-model": "1.7.4", - "@backstage/cli-node": "0.2.13", - "@backstage/config": "1.3.2", - "@backstage/config-loader": "1.10.1", - "@backstage/plugin-app-backend": "0.5.2", - "@backstage/plugin-auth-backend": "0.25.0", - "@backstage/plugin-auth-backend-module-atlassian-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-auth0-provider": "0.2.3", - "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.2.8", - "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-bitbucket-server-provider": "0.2.3", - "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-github-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-gitlab-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-google-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-guest-provider": "0.2.8", - "@backstage/plugin-auth-backend-module-microsoft-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.2.8", - "@backstage/plugin-auth-backend-module-oidc-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-okta-provider": "0.2.3", - "@backstage/plugin-auth-backend-module-onelogin-provider": "0.3.3", - "@backstage/plugin-auth-node": "0.6.3", - "@backstage/plugin-catalog-backend": "2.0.0", - "@backstage/plugin-catalog-backend-module-logs": "0.1.10", - "@backstage/plugin-catalog-backend-module-openapi": "0.2.10", - "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.8", - "@backstage/plugin-events-backend": "0.5.2", - "@backstage/plugin-events-node": "0.4.11", - "@backstage/plugin-permission-backend": "0.7.0", - "@backstage/plugin-proxy-backend": "0.6.2", - "@backstage/plugin-scaffolder-backend": "1.33.0", - "@backstage/plugin-search-backend": "2.0.2", - "@backstage/plugin-search-backend-module-catalog": "0.3.4", - "@backstage/plugin-search-backend-module-pg": "0.5.44", + "@backstage/backend-app-api": "1.2.6", + "@backstage/backend-defaults": "0.12.0", + "@backstage/backend-dynamic-feature-service": "0.7.3", + "@backstage/backend-plugin-api": "1.4.2", + "@backstage/catalog-client": "1.11.0", + "@backstage/catalog-model": "1.7.5", + "@backstage/cli-node": "0.2.14", + "@backstage/config": "1.3.3", + "@backstage/config-loader": "1.10.2", + "@backstage/plugin-app-backend": "0.5.5", + "@backstage/plugin-auth-backend": "0.25.3", + "@backstage/plugin-auth-backend-module-atlassian-provider": "0.4.6", + "@backstage/plugin-auth-backend-module-auth0-provider": "0.2.6", + "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.2.11", + "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.3.6", + "@backstage/plugin-auth-backend-module-bitbucket-server-provider": "0.2.6", + "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.4.6", + "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.4.6", + "@backstage/plugin-auth-backend-module-github-provider": "0.3.6", + "@backstage/plugin-auth-backend-module-gitlab-provider": "0.3.6", + "@backstage/plugin-auth-backend-module-google-provider": "0.3.6", + "@backstage/plugin-auth-backend-module-guest-provider": "0.2.11", + "@backstage/plugin-auth-backend-module-microsoft-provider": "0.3.6", + "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.2.11", + "@backstage/plugin-auth-backend-module-oidc-provider": "0.4.6", + "@backstage/plugin-auth-backend-module-okta-provider": "0.2.6", + "@backstage/plugin-auth-backend-module-onelogin-provider": "0.3.6", + "@backstage/plugin-auth-node": "0.6.6", + "@backstage/plugin-catalog-backend": "3.0.1", + "@backstage/plugin-catalog-backend-module-logs": "0.1.13", + "@backstage/plugin-catalog-backend-module-openapi": "0.2.13", + "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.11", + "@backstage/plugin-events-backend": "0.5.5", + "@backstage/plugin-events-node": "0.4.14", + "@backstage/plugin-permission-backend": "0.7.3", + "@backstage/plugin-proxy-backend": "0.6.5", + "@backstage/plugin-scaffolder-backend": "2.2.0", + "@backstage/plugin-search-backend": "2.0.5", + "@backstage/plugin-search-backend-module-catalog": "0.3.7", + "@backstage/plugin-search-backend-module-pg": "0.5.47", + "@backstage/plugin-user-settings-backend": "0.3.5", "@internal/plugin-dynamic-plugins-info-backend": "*", "@internal/plugin-licensed-users-info-backend": "*", "@internal/plugin-scalprum-backend": "*", @@ -74,21 +76,23 @@ "@opentelemetry/instrumentation-runtime-node": "0.14.0", "@opentelemetry/sdk-metrics": "1.30.1", "@opentelemetry/sdk-node": "0.57.2", - "app": "*", + "@red-hat-developer-hub/backstage-plugin-translations-backend": "0.0.2", + "app": "workspace:*", + "app-next": "workspace:*", "global-agent": "3.0.0", "jose": "5.10.0", - "undici": "6.21.2", + "undici": "6.21.3", "winston": "3.14.2", "zod": "3.23.8" }, "devDependencies": { - "@backstage/backend-test-utils": "1.5.0", - "@backstage/cli": "0.32.1", - "@backstage/plugin-catalog-node": "1.17.0", + "@backstage/backend-test-utils": "1.8.0", + "@backstage/cli": "0.34.1", + "@backstage/plugin-catalog-node": "1.18.0", "@types/express": "4.17.23", "@types/global-agent": "2.1.3", "prettier": "3.6.2", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist" diff --git a/packages/backend/src/defaultServiceFactories.test.ts b/packages/backend/src/defaultServiceFactories.test.ts index a676723279..d05c74d19c 100644 --- a/packages/backend/src/defaultServiceFactories.test.ts +++ b/packages/backend/src/defaultServiceFactories.test.ts @@ -33,6 +33,6 @@ describe('Default service factory list comparison', () => { ); expect( findSymmetricDifference(upstreamServiceFactoryIds, serviceFactoryIds), - ).toEqual(['core.rootLogger']); + ).toEqual([]); }); }); diff --git a/packages/backend/src/defaultServiceFactories.ts b/packages/backend/src/defaultServiceFactories.ts index e8fc5a9a08..84efbe57ad 100644 --- a/packages/backend/src/defaultServiceFactories.ts +++ b/packages/backend/src/defaultServiceFactories.ts @@ -1,3 +1,7 @@ +import { + actionsRegistryServiceFactory, + actionsServiceFactory, +} from '@backstage/backend-defaults/alpha'; import { auditorServiceFactory } from '@backstage/backend-defaults/auditor'; import { authServiceFactory } from '@backstage/backend-defaults/auth'; import { cacheServiceFactory } from '@backstage/backend-defaults/cache'; @@ -13,7 +17,10 @@ import { rootConfigServiceFactory } from '@backstage/backend-defaults/rootConfig import { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth'; import { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter'; import { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle'; -import { WinstonLogger } from '@backstage/backend-defaults/rootLogger'; +import { + rootLoggerServiceFactory, + WinstonLogger, +} from '@backstage/backend-defaults/rootLogger'; import { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler'; import { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader'; import { userInfoServiceFactory } from '@backstage/backend-defaults/userInfo'; @@ -41,11 +48,14 @@ export const DEFAULT_SERVICE_FACTORIES: ServiceFactory[] = [ rootHealthServiceFactory, rootHttpRouterServiceFactory, rootLifecycleServiceFactory, - // rootLoggerServiceFactory, + rootLoggerServiceFactory, schedulerServiceFactory, userInfoServiceFactory, urlReaderServiceFactory, eventsServiceFactory, + // alpha services + actionsRegistryServiceFactory, + actionsServiceFactory, ] as const; export const getDefaultServiceFactories = ({ diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index a5cf890526..7f0acf4ca6 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -17,6 +17,7 @@ import { pluginIDProviderService, rbacDynamicPluginsProvider, } from './modules'; +import { userSettingsBackend } from './modules/userSettings'; // Create a logger to cover logging static initialization tasks const staticLogger = WinstonLogger.create({ @@ -160,6 +161,11 @@ if (process.env.ENABLE_AUTH_PROVIDER_MODULE_OVERRIDE !== 'true') { backend.add(import('@internal/plugin-dynamic-plugins-info-backend')); backend.add(import('@internal/plugin-scalprum-backend')); +backend.add( + import('@red-hat-developer-hub/backstage-plugin-translations-backend'), +); backend.add(import('@internal/plugin-licensed-users-info-backend')); +backend.add(userSettingsBackend); + backend.start(); diff --git a/packages/backend/src/modules/userSettings.ts b/packages/backend/src/modules/userSettings.ts new file mode 100644 index 0000000000..b41c8fd157 --- /dev/null +++ b/packages/backend/src/modules/userSettings.ts @@ -0,0 +1,25 @@ +import { + coreServices, + createBackendFeatureLoader, +} from '@backstage/backend-plugin-api'; + +export const userSettingsBackend = createBackendFeatureLoader({ + deps: { + config: coreServices.rootConfig, + }, + async loader({ config }) { + const persistence = + config.getOptionalString('userSettings.persistence') ?? 'database'; // default to database + + if (persistence !== 'database' && persistence !== 'browser') { + throw new Error( + `Invalid config value for 'userSettings.persistence': "${persistence}". Must be either "database" or "browser".`, + ); + } + if (persistence === 'database') { + return [import('@backstage/plugin-user-settings-backend')]; + } + // Opt-out: browser -> no backend feature + return []; + }, +}); diff --git a/packages/plugin-utils/package.json b/packages/plugin-utils/package.json index 2fd12c17ef..a5ab35f2d7 100644 --- a/packages/plugin-utils/package.json +++ b/packages/plugin-utils/package.json @@ -16,9 +16,10 @@ "pluginId": "plugin-utils", "pluginPackage": "@janus-idp/plugin-utils", "pluginPackages": [ - "@janus-idp/plugin-utils" + "@red-hat-developer-hub/plugin-utils" ] }, + "sideEffects": false, "scripts": { "build": "backstage-cli package build", "clean": "backstage-cli package clean", @@ -30,13 +31,14 @@ "prettier:fix": "prettier --ignore-unknown --write ." }, "dependencies": { - "@backstage/catalog-model": "1.7.4" + "@backstage/catalog-model": "1.7.5", + "@backstage/core-plugin-api": "1.10.9" }, "devDependencies": { - "@backstage/cli": "0.32.1", - "@backstage/test-utils": "1.7.8", + "@backstage/cli": "0.34.1", + "@backstage/test-utils": "1.7.11", "@testing-library/dom": "9.3.4", - "@testing-library/jest-dom": "6.6.3", + "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "14.3.1", "@testing-library/react-hooks": "8.0.1", "@types/node": "22.16.3", @@ -44,7 +46,7 @@ "@types/react-dom": "18.3.7", "prettier": "3.6.2", "react": "18.3.1", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "browserslist": { "production": [ diff --git a/packages/plugin-utils/src/context/DynamicRootContext.test.tsx b/packages/plugin-utils/src/context/DynamicRootContext.test.tsx index a9c42f6ff0..63b855cac7 100644 --- a/packages/plugin-utils/src/context/DynamicRootContext.test.tsx +++ b/packages/plugin-utils/src/context/DynamicRootContext.test.tsx @@ -122,6 +122,7 @@ describe('DynamicRootContext', () => { config: { props: {} }, }, ], + translationRefs: [], }; const TestComponent = () => { @@ -227,6 +228,7 @@ describe('DynamicRootContext', () => { providerSettings: [], scaffolderFieldExtensions: [], techdocsAddons: [], + translationRefs: [], }; const TestComponent = () => { diff --git a/packages/plugin-utils/src/context/DynamicRootContext.tsx b/packages/plugin-utils/src/context/DynamicRootContext.tsx index 416548e010..46a90f94ed 100644 --- a/packages/plugin-utils/src/context/DynamicRootContext.tsx +++ b/packages/plugin-utils/src/context/DynamicRootContext.tsx @@ -12,4 +12,5 @@ export const DynamicRootContext = createContext({ providerSettings: [], scaffolderFieldExtensions: [], techdocsAddons: [], + translationRefs: [], }); diff --git a/packages/plugin-utils/src/hooks/useDynamicPlugin.ts b/packages/plugin-utils/src/hooks/useDynamicPlugin.ts index d6c3b78f26..eaba7a762e 100644 --- a/packages/plugin-utils/src/hooks/useDynamicPlugin.ts +++ b/packages/plugin-utils/src/hooks/useDynamicPlugin.ts @@ -21,6 +21,7 @@ export function useDynamicPluginConfig(): DynamicRootConfig { providerSettings, scaffolderFieldExtensions, techdocsAddons, + translationRefs, } = context; return { @@ -31,5 +32,6 @@ export function useDynamicPluginConfig(): DynamicRootConfig { providerSettings, scaffolderFieldExtensions, techdocsAddons, + translationRefs, }; } diff --git a/packages/plugin-utils/src/hooks/useDynamicPlugins.test.tsx b/packages/plugin-utils/src/hooks/useDynamicPlugins.test.tsx index f3fc21e663..9322f636c7 100644 --- a/packages/plugin-utils/src/hooks/useDynamicPlugins.test.tsx +++ b/packages/plugin-utils/src/hooks/useDynamicPlugins.test.tsx @@ -68,6 +68,7 @@ const mockContextValue: ComponentRegistry = { config: { props: {} }, }, ], + translationRefs: [], }; // Test wrapper component @@ -207,6 +208,7 @@ describe('useDynamicPluginConfig', () => { providerSettings: [], scaffolderFieldExtensions: [], techdocsAddons: [], + translationRefs: [], }; const EmptyWrapper: React.FC<{ children: React.ReactNode }> = ({ diff --git a/packages/plugin-utils/src/types.ts b/packages/plugin-utils/src/types.ts index 1de6fb4a2a..f5afff0ac3 100644 --- a/packages/plugin-utils/src/types.ts +++ b/packages/plugin-utils/src/types.ts @@ -1,4 +1,5 @@ import { Entity } from '@backstage/catalog-model'; +import { TranslationRef } from '@backstage/core-plugin-api/alpha'; export type RouteBinding = { bindTarget: string; @@ -23,6 +24,7 @@ export type ResolvedDynamicRouteMenuItem = export type ResolvedMenuItem = { name: string; title: string; + titleKey?: string; icon?: string; children?: ResolvedMenuItem[]; to?: string; @@ -76,7 +78,7 @@ export type MountPoint = { export type EntityTabOverrides = Record< string, - { title: string; mountPoint: string; priority?: number } + { title: string; titleKey?: string; mountPoint: string; priority?: number } >; export type MountPoints = Record; @@ -112,6 +114,7 @@ export type DynamicRootConfig = { providerSettings: ProviderSetting[]; scaffolderFieldExtensions: ScaffolderFieldExtension[]; techdocsAddons: TechdocsAddon[]; + translationRefs: TranslationRef[]; }; export type ComponentRegistry = { diff --git a/packages/theme-wrapper/package.json b/packages/theme-wrapper/package.json new file mode 100644 index 0000000000..f672415374 --- /dev/null +++ b/packages/theme-wrapper/package.json @@ -0,0 +1,5 @@ +{ + "name": "theme-wrapper", + "version": "0.0.0", + "private": true +} diff --git a/plugins/dynamic-plugins-info-backend/README.md b/plugins/dynamic-plugins-info-backend/README.md index 51d2c068e6..e1d3005be9 100644 --- a/plugins/dynamic-plugins-info-backend/README.md +++ b/plugins/dynamic-plugins-info-backend/README.md @@ -1,12 +1,9 @@ -# dynamic-plugins-info +# dynamic-plugins-info-backend -Welcome to the dynamic-plugins-info backend plugin! - -This plugin depends on the `backend-dynamic-feature-service` and lists all the dynamic plugins installed in the dynamic plugins root folder. +This backend provides an endpoint `/api/dynamic-plugins-info/loaded-plugins` to list all installed and enabled dynamic plugins. ## Getting started -This plugin has been added to the backend app in this repository, meaning you'll be able to access it by running `yarn -start-backend` in the root directory, and then navigating to [/api/dynamic-plugins-info](http://localhost:7007/api/dynamic-plugins-info). - -To view the list of installed dynamic plugins, navigate to `http://localhost:7007/api/dynamic-plugins-info/loaded-plugins` +This plugin has been added to the backend app in this repository, meaning you'll be able to access it by running +`yarn start` or `yarn dev` in the root directory, and then navigating to +[http://localhost:7007/api/dynamic-plugins-info/loaded-plugins](http://localhost:7007/api/dynamic-plugins-info/loaded-plugins). diff --git a/plugins/dynamic-plugins-info-backend/package.json b/plugins/dynamic-plugins-info-backend/package.json index c6b5977b52..e3fdeef858 100644 --- a/plugins/dynamic-plugins-info-backend/package.json +++ b/plugins/dynamic-plugins-info-backend/package.json @@ -32,23 +32,23 @@ "prettier:fix": "prettier --ignore-unknown --write ." }, "dependencies": { - "@backstage/backend-defaults": "0.10.0", - "@backstage/backend-dynamic-feature-service": "0.7.0", - "@backstage/backend-plugin-api": "1.3.1", - "@backstage/config": "1.3.2", + "@backstage/backend-defaults": "0.12.0", + "@backstage/backend-dynamic-feature-service": "0.7.3", + "@backstage/backend-plugin-api": "1.4.2", + "@backstage/config": "1.3.3", "express": "4.21.2", "node-fetch": "2.7.0", "winston": "3.14.2" }, "devDependencies": { - "@backstage/backend-test-utils": "1.5.0", - "@backstage/cli": "0.32.1", + "@backstage/backend-test-utils": "1.8.0", + "@backstage/cli": "0.34.1", "@types/express": "4.17.23", "@types/supertest": "6.0.3", "msw": "1.3.5", "prettier": "3.6.2", "supertest": "6.3.4", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist" diff --git a/plugins/dynamic-plugins-info/.eslintrc.js b/plugins/dynamic-plugins-info/.eslintrc.js deleted file mode 100644 index 07630f21af..0000000000 --- a/plugins/dynamic-plugins-info/.eslintrc.js +++ /dev/null @@ -1,12 +0,0 @@ -const backstageConfig = require('@backstage/cli/config/eslint-factory')( - __dirname, -); - -module.exports = { - ...backstageConfig, - rules: { - ...backstageConfig.rules, - 'react/react-in-jsx-scope': 'off', - 'react/jsx-uses-react': 'off', - }, -}; diff --git a/plugins/dynamic-plugins-info/.lintstagedrc.json b/plugins/dynamic-plugins-info/.lintstagedrc.json deleted file mode 100644 index 14b2263def..0000000000 --- a/plugins/dynamic-plugins-info/.lintstagedrc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "*": "prettier --ignore-unknown --write", - "*.{js,jsx,ts,tsx,mjs,cjs}": "backstage-cli package lint --fix" -} diff --git a/plugins/dynamic-plugins-info/.prettierignore b/plugins/dynamic-plugins-info/.prettierignore deleted file mode 100644 index 3f6fff7b2b..0000000000 --- a/plugins/dynamic-plugins-info/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -coverage \ No newline at end of file diff --git a/plugins/dynamic-plugins-info/.prettierrc.js b/plugins/dynamic-plugins-info/.prettierrc.js deleted file mode 100644 index 83c5a44066..0000000000 --- a/plugins/dynamic-plugins-info/.prettierrc.js +++ /dev/null @@ -1,20 +0,0 @@ -// @ts-check - -/** @type {import("@ianvs/prettier-plugin-sort-imports").PrettierConfig} */ -module.exports = { - ...require('@backstage/cli/config/prettier.json'), - plugins: ['@ianvs/prettier-plugin-sort-imports'], - importOrder: [ - '^react(.*)$', - '', - '^@backstage/(.*)$', - '', - '', - '', - '^@janus-idp/(.*)$', - '', - '', - '', - '^[.]', - ], -}; diff --git a/plugins/dynamic-plugins-info/CONTRIBUTING.md b/plugins/dynamic-plugins-info/CONTRIBUTING.md deleted file mode 100644 index 17defbe66a..0000000000 --- a/plugins/dynamic-plugins-info/CONTRIBUTING.md +++ /dev/null @@ -1,7 +0,0 @@ -# Setting up the development environment for Dynamic Plugins Info plugin - -In [Backstage plugin terminology](https://backstage.io/docs/local-dev/cli-build-system#package-roles), the Dynamic Plugins Info plugin is a front-end plugin. You can start a live development session from the repository root using the following command: - -```console -yarn workspace @internal/plugin-dynamic-plugins-info run dev -``` diff --git a/plugins/dynamic-plugins-info/README.md b/plugins/dynamic-plugins-info/README.md deleted file mode 100644 index a176fa783c..0000000000 --- a/plugins/dynamic-plugins-info/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Dynamic Plugins Info plugin for Backstage - -The dynamic-plugins-info plugin is a frontend component for the [dynamic-plugins-info-backend](../dynamic-plugins-info-backend) plugin. It offers a simple table of plugins that are currently installed in Janus IDP (or Red Hat Developer Hub) that supports client-side sorting, filtering and pagination. - -![dynamic-plugins-info-screenshot](./images/screenshot-plugin-list.png) diff --git a/plugins/dynamic-plugins-info/app-config.dynamic.yaml b/plugins/dynamic-plugins-info/app-config.dynamic.yaml deleted file mode 100644 index d940e45986..0000000000 --- a/plugins/dynamic-plugins-info/app-config.dynamic.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# please keep this in sync with packages/app/src/App.tsx -dynamicPlugins: - frontend: - internal.plugin-dynamic-plugins-info: - appIcons: - - name: pluginsInfoIcon - importName: PluginsInfoIcon - - name: adminIcon - importName: AdminIcon - dynamicRoutes: - - path: /extensions - importName: DynamicPluginsInfoPage - menuItem: - text: Extensions - icon: pluginsInfoIcon - mountPoints: - - mountPoint: internal.plugins/tab - importName: DynamicPluginsInfoContent - config: - path: installed - title: Installed Plugins - menuItems: - admin: - title: Administration - icon: adminIcon - extensions: - parent: admin - title: Extensions - icon: pluginsInfoIcon diff --git a/plugins/dynamic-plugins-info/dev/index.tsx b/plugins/dynamic-plugins-info/dev/index.tsx deleted file mode 100644 index 76054d37e3..0000000000 --- a/plugins/dynamic-plugins-info/dev/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { createDevApp } from '@backstage/dev-utils'; -import { TestApiProvider } from '@backstage/test-utils'; - -import { listLoadedPluginsResult } from '../src/__fixtures__/listLoadedPluginsResult'; -import { dynamicPluginsInfoApiRef } from '../src/api/types'; -import { DynamicPluginsInfoContent } from '../src/components/DynamicPluginsInfoContent/DynamicPluginsInfoContent'; -import { dynamicPluginsInfoPlugin } from '../src/plugin'; - -const mockedApi = { - listLoadedPlugins: async () => { - return listLoadedPluginsResult; - }, -}; - -createDevApp() - .registerPlugin(dynamicPluginsInfoPlugin) - .addPage({ - element: ( - - - - ), - title: 'Root Page', - path: '/dynamic-plugins-info', - }) - .render(); diff --git a/plugins/dynamic-plugins-info/images/screenshot-plugin-list.png b/plugins/dynamic-plugins-info/images/screenshot-plugin-list.png deleted file mode 100644 index 43ceca86df..0000000000 Binary files a/plugins/dynamic-plugins-info/images/screenshot-plugin-list.png and /dev/null differ diff --git a/plugins/dynamic-plugins-info/package.json b/plugins/dynamic-plugins-info/package.json deleted file mode 100644 index 74fda203f8..0000000000 --- a/plugins/dynamic-plugins-info/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@internal/plugin-dynamic-plugins-info", - "version": "1.0.2", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", - "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "frontend-plugin", - "pluginId": "dynamic-plugins-info", - "pluginPackages": [ - "@internal/plugin-dynamic-plugins-info", - "@internal/plugin-dynamic-plugins-info-backend" - ] - }, - "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "clean": "backstage-cli package clean", - "lint:check": "backstage-cli package lint", - "lint:fix": "backstage-cli package lint --fix", - "postpack": "backstage-cli package postpack", - "postversion": "yarn run export-dynamic", - "prepack": "backstage-cli package prepack", - "dev": "backstage-cli package start", - "test": "backstage-cli package test --passWithNoTests --coverage", - "tsc": "tsc", - "prettier:check": "prettier --ignore-unknown --check .", - "prettier:fix": "prettier --ignore-unknown --write ." - }, - "dependencies": { - "@backstage/core-components": "0.17.2", - "@backstage/core-plugin-api": "1.10.7", - "@backstage/theme": "0.6.6", - "@material-table/core": "3.2.5", - "@mui/icons-material": "5.18.0", - "@mui/material": "5.18.0", - "@scalprum/react-core": "0.9.5", - "react-use": "17.6.0" - }, - "peerDependencies": { - "react": "16.13.1 || ^17.0.0 || ^18.2.0", - "react-router-dom": "6.30.1" - }, - "devDependencies": { - "@backstage/cli": "0.32.1", - "@backstage/core-app-api": "1.17.0", - "@backstage/dev-utils": "1.1.10", - "@backstage/test-utils": "1.7.8", - "@testing-library/jest-dom": "6.6.3", - "@testing-library/react": "14.3.1", - "@testing-library/user-event": "14.6.1", - "glob": "11.0.3", - "msw": "1.3.5", - "prettier": "3.6.2", - "react": "18.3.1", - "react-router-dom": "6.30.1", - "typescript": "5.8.3" - }, - "files": [ - "dist" - ] -} diff --git a/plugins/dynamic-plugins-info/src/__fixtures__/listLoadedPluginsResult.ts b/plugins/dynamic-plugins-info/src/__fixtures__/listLoadedPluginsResult.ts deleted file mode 100644 index 363a1b794c..0000000000 --- a/plugins/dynamic-plugins-info/src/__fixtures__/listLoadedPluginsResult.ts +++ /dev/null @@ -1,50 +0,0 @@ -export const listLoadedPluginsResult = [ - { - name: 'api-returned-some-plugin-one', - version: '0.1.0', - role: 'frontend-plugin', - platform: 'web', - internal: true, - enabled: true, - }, - { - name: 'api-returned-some-plugin-two', - version: '1.1.0', - role: 'backend-plugin-module', - platform: 'node', - internal: false, - enabled: true, - }, - { - name: 'api-returned-some-plugin-three', - version: '0.1.2', - role: 'backend-plugin', - platform: 'node', - internal: false, - enabled: true, - }, - { - name: 'api-returned-some-plugin-four', - version: '1.1.0', - role: 'frontend-plugin', - platform: 'web', - internal: true, - enabled: true, - }, - { - name: 'api-returned-some-plugin-five', - version: '1.2.0', - role: 'frontend-plugin', - platform: 'web', - internal: true, - enabled: true, - }, - { - name: 'api-returned-some-plugin-six', - version: '0.6.3', - role: 'backend-plugin', - platform: 'node', - internal: true, - enabled: true, - }, -]; diff --git a/plugins/dynamic-plugins-info/src/api/DynamicPluginsInfoClient.ts b/plugins/dynamic-plugins-info/src/api/DynamicPluginsInfoClient.ts deleted file mode 100644 index 1fa7ddb774..0000000000 --- a/plugins/dynamic-plugins-info/src/api/DynamicPluginsInfoClient.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - DiscoveryApi, - FetchApi, - IdentityApi, -} from '@backstage/core-plugin-api'; - -import { DynamicPluginInfo, DynamicPluginsInfoApi } from './types'; - -export interface DynamicPluginsInfoClientOptions { - discoveryApi: DiscoveryApi; - fetchApi: FetchApi; - identityApi: IdentityApi; -} - -const loadedPluginsEndpoint = '/loaded-plugins'; - -export class DynamicPluginsInfoClient implements DynamicPluginsInfoApi { - private readonly discoveryApi: DiscoveryApi; - private readonly fetchApi: FetchApi; - private readonly identityApi: IdentityApi; - - constructor(options: DynamicPluginsInfoClientOptions) { - this.discoveryApi = options.discoveryApi; - this.fetchApi = options.fetchApi; - this.identityApi = options.identityApi; - } - async listLoadedPlugins(): Promise { - const baseUrl = await this.discoveryApi.getBaseUrl('dynamic-plugins-info'); - const targetUrl = `${baseUrl}${loadedPluginsEndpoint}`; - const { token } = await this.identityApi.getCredentials(); - const response = await this.fetchApi.fetch(targetUrl, { - ...(token ? { headers: { Authorization: `Bearer ${token}` } } : {}), - }); - const data = await response.json(); - if (!response.ok) { - const message = data.error?.message || data.message || data.toString?.(); - throw new Error(`Failed to load dynamic plugin info: ${message}`); - } - return data; - } -} diff --git a/plugins/dynamic-plugins-info/src/api/types.ts b/plugins/dynamic-plugins-info/src/api/types.ts deleted file mode 100644 index d8dd3af377..0000000000 --- a/plugins/dynamic-plugins-info/src/api/types.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createApiRef } from '@backstage/core-plugin-api'; - -export type DynamicPluginInfo = { - name: string; - version: string; - role: string; - platform: string; - enabled: boolean; - internal: boolean; -}; - -export interface DynamicPluginsInfoApi { - listLoadedPlugins(): Promise; -} - -export const dynamicPluginsInfoApiRef = createApiRef({ - id: 'plugin.dynamic-plugins-info', -}); diff --git a/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoContent/DynamicPluginsInfoContent.tsx b/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoContent/DynamicPluginsInfoContent.tsx deleted file mode 100644 index e636b60723..0000000000 --- a/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoContent/DynamicPluginsInfoContent.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import { DynamicPluginsTable } from '../DynamicPluginsTable/DynamicPluginsTable'; - -export const DynamicPluginsInfoContent = () => ; diff --git a/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoPage.tsx b/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoPage.tsx deleted file mode 100644 index e237d4d6c6..0000000000 --- a/plugins/dynamic-plugins-info/src/components/DynamicPluginsInfoPage.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import React from 'react'; - -import { - Content, - Header, - Page, - TabbedLayout, -} from '@backstage/core-components'; - -import { useScalprum } from '@scalprum/react-core'; - -export interface PluginTab { - Component: React.ComponentType; - config: { - path: string; - title: string; - }; -} - -export interface ScalprumState { - api?: { - dynamicRootConfig?: { - mountPoints?: { - 'internal.plugins/tab': PluginTab[]; - }; - }; - }; -} - -export const DynamicPluginsInfoPage = () => { - const scalprum = useScalprum(); - - const tabs = - scalprum.api?.dynamicRootConfig?.mountPoints?.['internal.plugins/tab'] || - []; - - const FirstComponent = tabs[0]?.Component; - - return ( - -
- {tabs.length > 1 ? ( - - {tabs.map(({ Component, config }) => ( - - - - ))} - - ) : ( - - - - )} - - ); -}; diff --git a/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.test.tsx b/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.test.tsx deleted file mode 100644 index 210887d7fd..0000000000 --- a/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.test.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { errorApiRef } from '@backstage/core-plugin-api'; -import { - TranslationApi, - translationApiRef, - TranslationSnapshot, -} from '@backstage/core-plugin-api/alpha'; -import { - MockErrorApi, - renderWithEffects, - TestApiProvider, -} from '@backstage/test-utils'; - -import { screen } from '@testing-library/react'; - -import { listLoadedPluginsResult } from '../../__fixtures__/listLoadedPluginsResult'; -import { dynamicPluginsInfoApiRef } from '../../api/types'; -import { InternalPluginsMap } from '../InternalPluginsMap'; -import { DynamicPluginsTable } from './DynamicPluginsTable'; - -const DEFAULT_ROWS_DISPLAYED = 5; - -// 6 mockapi returned external(enabled) + 53 internal(not enabled) -// mockapi returns enabled plugins -// keys from InternalPluginsMap are internal plugins -const plugins = [ - ...Object.keys(InternalPluginsMap).map(name => ({ - name, - version: undefined, - role: undefined, - platform: undefined, - internal: true, - enabled: true, - })), - ...listLoadedPluginsResult, -]; - -// This mock simulates the translation API. -// It may be able to be removed when upstream provides a mock compatible with our usage. -const translationApiMock: Partial = { - getTranslation: ( - _ref: any, - ): TranslationSnapshot => - ({ - t: (key: keyof TMessages) => key as string, - ready: true, - }) as TranslationSnapshot, - - translation$: () => ({ - subscribe: () => ({ unsubscribe: () => {}, closed: true }), - [Symbol.observable]() { - return this; - }, - }), -}; - -describe('DynamicPluginsTable', () => { - beforeEach(() => { - // sort by the plugin name - plugins.sort((a, b) => { - return a.name.localeCompare(b.name); - }); - }); - - it('should display the plugins', async () => { - const mockDynamicPluginApi = { - listLoadedPlugins: async () => listLoadedPluginsResult, - }; - - const { container } = await renderWithEffects( - - - , - ); - - expect( - await screen.findByText(`Plugins (${plugins.length})`), - ).toBeInTheDocument(); - expect( - await screen.findByText(plugins.at(0)?.name ?? ''), - ).toBeInTheDocument(); - - const nameCells = Array.from( - container.querySelectorAll('tbody tr > td:first-child'), - ); - const versionCells = Array.from( - container.querySelectorAll('tbody tr > td:nth-child(2)'), - ); - const enabledCells = Array.from( - container.querySelectorAll('tbody tr > td:nth-child(3)'), - ); - const internalCells = Array.from( - container.querySelectorAll('tbody tr > td:nth-child(4)'), - ); - - const displayedPlugins = plugins.slice(0, DEFAULT_ROWS_DISPLAYED); - expect(nameCells.length).toBe(displayedPlugins.length); - - for (let i = 0; i < DEFAULT_ROWS_DISPLAYED; i++) { - expect(nameCells[i].textContent).toBe(displayedPlugins[i].name); - try { - expect(versionCells[i].textContent).toBe(displayedPlugins[i].version); - expect(enabledCells[i].textContent).toBe( - displayedPlugins[i].enabled ? 'Yes' : 'No', - ); - expect(internalCells[i].textContent).toBe( - displayedPlugins[i].internal ? 'Yes' : 'No', - ); - } catch (e) { - throw new Error(`${displayedPlugins[i].name}: ${(e as Error).message}`); - } - } - }); -}); diff --git a/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.tsx b/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.tsx deleted file mode 100644 index 088f019faf..0000000000 --- a/plugins/dynamic-plugins-info/src/components/DynamicPluginsTable/DynamicPluginsTable.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import { useState } from 'react'; - -import { - ResponseErrorPanel, - Table, - TableColumn, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; - -import { Query, QueryResult } from '@material-table/core'; - -import { DynamicPluginInfo, dynamicPluginsInfoApiRef } from '../../api/types'; -import { - getNotEnabledInternalPlugins, - InternalPluginsMap, -} from '../InternalPluginsMap'; - -export const DynamicPluginsTable = () => { - const [error, setError] = useState(undefined); - const [count, setCount] = useState(0); - const dynamicPluginInfo = useApi(dynamicPluginsInfoApiRef); - let data: DynamicPluginInfo[] = []; - const columns: TableColumn[] = [ - { - title: 'Name', - field: 'name', - defaultSort: 'asc', - }, - { - title: 'Version', - field: 'version', - width: '15%', - }, - { - title: 'Enabled', - field: 'enabled', - render: ({ enabled }) => <>{enabled ? 'Yes' : 'No'}, - width: '10%', - }, - { - title: 'Preinstalled', - field: 'internal', - render: ({ internal }) => <>{internal ? 'Yes' : 'No'}, - width: '10%', - }, - { - title: 'Role', - render: ({ platform, role }) => ( - <>{(role && `${role} (${platform})`) || null} - ), - sorting: false, - }, - ]; - const fetchData = async ( - query: Query, - ): Promise> => { - const { - orderBy = { field: 'name' }, - orderDirection = 'asc', - page = 0, - pageSize = 5, - search = '', - } = query || {}; - try { - // for now sorting/searching/pagination is handled client-side - const enabledPlugins = (await dynamicPluginInfo.listLoadedPlugins()).map( - plugin => { - if (plugin.name in InternalPluginsMap) { - return { - ...plugin, - internal: true, - enabled: true, - }; - } - return { - ...plugin, - enabled: true, - }; - }, - ); - const notEnabledInternalPlugins = getNotEnabledInternalPlugins( - enabledPlugins.map(plugin => plugin.name), - ); - data = [...enabledPlugins] - // add other internal plugins that are not enabled - .concat(notEnabledInternalPlugins) - .sort( - ( - a: Record, - b: Record, - ) => { - const field = orderBy.field!; - const orderMultiplier = orderDirection === 'desc' ? -1 : 1; - - if (a[field] === null || b[field] === null) { - return 0; - } - - // Handle boolean values separately - if ( - typeof a[field] === 'boolean' && - typeof b[field] === 'boolean' - ) { - return (a[field] ? 1 : -1) * orderMultiplier; - } - - return ( - (a[field] as string).localeCompare(b[field] as string) * - orderMultiplier - ); - }, - ) - .filter(plugin => - plugin.name - .toLowerCase() - .trim() - .includes(search.toLowerCase().trim()), - ); - const totalCount = data.length; - let start = 0; - let end = totalCount; - if (totalCount > pageSize) { - start = page * pageSize; - end = start + pageSize; - } - setCount(totalCount); - return { data: data.slice(start, end), page, totalCount }; - } catch (loadingError) { - // eslint-disable-next-line no-console - console.error('Failed to load plugins', loadingError); - setError(loadingError as Error); - return { data: [], totalCount: 0, page: 0 }; - } - }; - if (error) { - return ; - } - return ( - - ); -}; diff --git a/plugins/dynamic-plugins-info/src/components/InternalPluginsMap.test.ts b/plugins/dynamic-plugins-info/src/components/InternalPluginsMap.test.ts deleted file mode 100644 index 719b45426e..0000000000 --- a/plugins/dynamic-plugins-info/src/components/InternalPluginsMap.test.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { glob } from 'glob'; - -import fs from 'node:fs'; -import path from 'node:path'; - -import { InternalPluginsMap } from './InternalPluginsMap'; - -const PACKAGE_JSON_GLOB = '**/package.json'; -const IGNORE_GLOB = ['**/node_modules/**', '**/dist-dynamic/**']; - -const ROOT_DIR = path.join(__dirname, '../../../..'); -const DYNAMIC_PLUGINS_DIR = path.join(ROOT_DIR, 'dynamic-plugins/wrappers'); - -type WrapperFrontendPackageJson = { - name: string; - backstage: { - role: 'frontend-plugin'; - }; - scalprum: { - name: string; - }; - repository: { - directory: string; - }; -}; - -type WrapperBackendPackageJson = { - name: string; - backstage: { - role: 'backend-plugin' | 'backend-plugin-module'; - }; - repository: { - directory: string; - }; -}; - -type WrapperPackageJson = - | WrapperFrontendPackageJson - | WrapperBackendPackageJson; - -function isFrontendPlugin( - packageJson: WrapperPackageJson, -): packageJson is WrapperFrontendPackageJson { - return packageJson.backstage.role === 'frontend-plugin'; -} - -function isBackendPlugin( - packageJson: WrapperPackageJson, -): packageJson is WrapperBackendPackageJson { - return ( - packageJson.backstage.role === 'backend-plugin' || - packageJson.backstage.role === 'backend-plugin-module' - ); -} - -function getDifference(arrA: T[], arrB: T[]): T[] { - return arrA.filter(x => !arrB.includes(x)); -} - -describe('InternalPluginsMap', () => { - const wrapperPackageJsonPaths = glob.sync(PACKAGE_JSON_GLOB, { - cwd: DYNAMIC_PLUGINS_DIR, // Search only within DYNAMIC_PLUGINS_DIR - ignore: IGNORE_GLOB, - }); - - const wrapperDirNames = wrapperPackageJsonPaths.map(path.dirname); - - const wrapperPackageJsonFiles = wrapperPackageJsonPaths.map( - packageJsonPath => { - const packageJson = fs.readFileSync( - path.join(DYNAMIC_PLUGINS_DIR, packageJsonPath), - ); - return JSON.parse(packageJson.toString()) as WrapperPackageJson; - }, - ); - const frontendPackageJsonFiles = wrapperPackageJsonFiles.filter(packageJson => - isFrontendPlugin(packageJson), - ); - const backendPackageJsonFiles = wrapperPackageJsonFiles.filter(packageJson => - isBackendPlugin(packageJson), - ); - - it('should have a valid map', () => { - const difference = getDifference( - Object.keys(InternalPluginsMap), - wrapperDirNames, - ); - - try { - expect(difference).toStrictEqual([]); - } catch { - throw new Error( - `The following plugins are missing: ${difference.join(', ')}`, - ); - } - }); - - it.each(backendPackageJsonFiles)( - '$name should have a `-dynamic` suffix in the directory name', - ({ name }) => { - const hasDynamicSuffix = Object.values(InternalPluginsMap).some(value => - value.includes(`${name}-dynamic`), - ); - expect(hasDynamicSuffix).toBeTruthy(); - }, - ); - - it.each(frontendPackageJsonFiles)( - '$name should have a matching directory name', - ({ name }) => { - const hasMatchingDirName = Object.values(InternalPluginsMap).some(value => - value.includes(name), - ); - expect(hasMatchingDirName).toBeTruthy(); - }, - ); -}); diff --git a/plugins/dynamic-plugins-info/src/components/InternalPluginsMap.ts b/plugins/dynamic-plugins-info/src/components/InternalPluginsMap.ts deleted file mode 100644 index 7c8ca669ac..0000000000 --- a/plugins/dynamic-plugins-info/src/components/InternalPluginsMap.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { DynamicPluginInfo } from '../api/types'; - -// This is a mapping of internal plugins to their package path based off dynamic-plugins.default.yaml -export const InternalPluginsMap: Record = { - 'backstage-plugin-scaffolder-backend-module-github-dynamic': - './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-github-dynamic', - 'backstage-plugin-catalog-backend-module-github-dynamic': - './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic', - 'backstage-plugin-catalog-backend-module-github-org-dynamic': - './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org-dynamic', - 'backstage-community-plugin-github-actions': - './dynamic-plugins/dist/backstage-community-plugin-github-actions', - 'backstage-community-plugin-github-issues': - './dynamic-plugins/dist/backstage-community-plugin-github-issues', - 'roadiehq-backstage-plugin-github-insights': - './dynamic-plugins/dist/roadiehq-backstage-plugin-github-insights', - 'roadiehq-backstage-plugin-github-pull-requests': - './dynamic-plugins/dist/roadiehq-backstage-plugin-github-pull-requests', - 'roadiehq-backstage-plugin-security-insights': - './dynamic-plugins/dist/roadiehq-backstage-plugin-security-insights', - 'backstage-plugin-scaffolder-backend-module-gitlab-dynamic': - './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-gitlab-dynamic', - 'backstage-plugin-kubernetes-backend-dynamic': - './dynamic-plugins/dist/backstage-plugin-kubernetes-backend-dynamic', - 'backstage-plugin-kubernetes': - './dynamic-plugins/dist/backstage-plugin-kubernetes', - 'backstage-community-plugin-topology': - './dynamic-plugins/dist/backstage-community-plugin-topology', - 'roadiehq-scaffolder-backend-argocd-dynamic': - './dynamic-plugins/dist/roadiehq-scaffolder-backend-argocd-dynamic', - 'roadiehq-backstage-plugin-argo-cd-backend-dynamic': - './dynamic-plugins/dist/roadiehq-backstage-plugin-argo-cd-backend-dynamic', - 'backstage-plugin-scaffolder-backend-module-azure-dynamic': - './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-azure-dynamic', - 'backstage-community-plugin-azure-devops-backend-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-azure-devops-backend-dynamic', - 'backstage-community-plugin-azure-devops': - './dynamic-plugins/dist/backstage-community-plugin-azure-devops', - 'backstage-community-plugin-jenkins-backend-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-jenkins-backend-dynamic', - 'backstage-community-plugin-jenkins': - './dynamic-plugins/dist/backstage-community-plugin-jenkins', - 'backstage-plugin-notifications': - './dynamic-plugins/dist/backstage-plugin-notifications', - 'backstage-plugin-notifications-backend-dynamic': - './dynamic-plugins/dist/backstage-plugin-notifications-backend-dynamic', - 'backstage-plugin-notifications-backend-module-email-dynamic': - './dynamic-plugins/dist/backstage-plugin-notifications-backend-module-email-dynamic', - 'backstage-plugin-signals-backend-dynamic': - './dynamic-plugins/dist/backstage-plugin-signals-backend-dynamic', - 'backstage-plugin-signals': './dynamic-plugins/dist/backstage-plugin-signals', - 'backstage-community-plugin-sonarqube-backend-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-sonarqube-backend-dynamic', - 'backstage-community-plugin-sonarqube': - './dynamic-plugins/dist/backstage-community-plugin-sonarqube', - 'backstage-community-plugin-ocm-backend-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-ocm-backend-dynamic', - 'backstage-community-plugin-ocm': - './dynamic-plugins/dist/backstage-community-plugin-ocm', - 'red-hat-developer-hub-backstage-plugin-adoption-insights': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-adoption-insights', - 'red-hat-developer-hub-backstage-plugin-adoption-insights-backend-dynamic': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-adoption-insights-backend-dynamic', - 'red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights-dynamic': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights-dynamic', - 'red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic', - 'red-hat-developer-hub-backstage-plugin-bulk-import': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import', - 'red-hat-developer-hub-backstage-plugin-global-header': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header', - 'red-hat-developer-hub-backstage-plugin-quickstart': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-quickstart', - 'red-hat-developer-hub-backstage-plugin-global-floating-action-button': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button', - 'red-hat-developer-hub-backstage-plugin-dynamic-home-page': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page', - 'red-hat-developer-hub-backstage-plugin-marketplace': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace', - 'red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace-backend-dynamic', - 'red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic': - './dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-catalog-backend-module-marketplace-dynamic', - 'backstage-plugin-techdocs-backend-dynamic': - './dynamic-plugins/dist/backstage-plugin-techdocs-backend-dynamic', - 'backstage-plugin-techdocs': - './dynamic-plugins/dist/backstage-plugin-techdocs', - 'backstage-plugin-techdocs-module-addons-contrib': - './dynamic-plugins/dist/backstage-plugin-techdocs-module-addons-contrib', - 'backstage-plugin-scaffolder-backend-module-gerrit-dynamic': - './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-gerrit-dynamic', - 'roadiehq-scaffolder-backend-module-utils-dynamic': - './dynamic-plugins/dist/roadiehq-scaffolder-backend-module-utils-dynamic', - 'roadiehq-scaffolder-backend-module-http-request-dynamic': - './dynamic-plugins/dist/roadiehq-scaffolder-backend-module-http-request-dynamic', - 'backstage-community-plugin-scaffolder-backend-module-kubernetes-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-kubernetes-dynamic', - 'backstage-community-plugin-scaffolder-backend-module-quay-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-quay-dynamic', - 'backstage-community-plugin-rbac': - './dynamic-plugins/dist/backstage-community-plugin-rbac', - 'backstage-community-plugin-scaffolder-backend-module-regex-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-regex-dynamic', - 'backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-servicenow-dynamic', - 'backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic': - '/dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-sonarqube-dynamic', - 'backstage-community-plugin-3scale-backend-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-3scale-backend-dynamic', - 'backstage-community-plugin-catalog-backend-module-keycloak-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-keycloak-dynamic', - 'backstage-community-plugin-redhat-argocd': - './dynamic-plugins/dist/backstage-community-plugin-redhat-argocd', - 'backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic': - './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-cloud-dynamic', - 'backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic': - './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-bitbucket-cloud-dynamic', - 'backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic': - './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-bitbucket-server-dynamic', - 'backstage-plugin-catalog-backend-module-bitbucket-server-dynamic': - './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-bitbucket-server-dynamic', - 'backstage-community-plugin-dynatrace': - './dynamic-plugins/dist/backstage-community-plugin-dynatrace', - 'roadiehq-backstage-plugin-jira': - './dynamic-plugins/dist/roadiehq-backstage-plugin-jira', - 'roadiehq-backstage-plugin-datadog': - './dynamic-plugins/dist/roadiehq-backstage-plugin-datadog', - 'backstage-community-plugin-tekton': - './dynamic-plugins/dist/backstage-community-plugin-tekton', - 'backstage-community-plugin-quay': - './dynamic-plugins/dist/backstage-community-plugin-quay', - 'backstage-community-plugin-nexus-repository-manager': - './dynamic-plugins/dist/backstage-community-plugin-nexus-repository-manager', - 'backstage-community-plugin-acr': - './dynamic-plugins/dist/backstage-community-plugin-acr', - 'backstage-community-plugin-jfrog-artifactory': - './dynamic-plugins/dist/backstage-community-plugin-jfrog-artifactory', - 'pagerduty-backstage-plugin': - './dynamic-plugins/dist/pagerduty-backstage-plugin', - 'pagerduty-backstage-plugin-backend-dynamic': - './dynamic-plugins/dist/pagerduty-backstage-plugin-backend-dynamic', - 'backstage-community-plugin-lighthouse': - './dynamic-plugins/dist/backstage-community-plugin-lighthouse', - 'backstage-community-plugin-tech-radar': - './dynamic-plugins/dist/backstage-community-plugin-tech-radar', - 'backstage-community-plugin-tech-radar-backend-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-tech-radar-backend-dynamic', - 'backstage-community-plugin-analytics-provider-segment': - './dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment', - 'parfuemerie-douglas-scaffolder-backend-module-azure-repositories-dynamic': - './dynamic-plugins/dist/parfuemerie-douglas-scaffolder-backend-module-azure-repositories-dynamic', - 'immobiliarelabs-backstage-plugin-gitlab-backend-dynamic': - './dynamic-plugins/dist/immobiliarelabs-backstage-plugin-gitlab-backend-dynamic', - 'backstage-community-plugin-catalog-backend-module-pingidentity-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-pingidentity-dynamic', - 'backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic': - './dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic', - 'backstage-plugin-catalog-backend-module-gitlab-dynamic': - './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-gitlab-dynamic', - 'backstage-plugin-catalog-backend-module-gitlab-org-dynamic': - './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-gitlab-org-dynamic', - 'backstage-plugin-catalog-backend-module-ldap-dynamic': - './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-ldap-dynamic', - 'backstage-plugin-catalog-backend-module-msgraph-dynamic': - './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-msgraph-dynamic', -}; - -export const getNotEnabledInternalPlugins = (enabledPlugins: string[]) => { - const plugins: DynamicPluginInfo[] = []; - if (!enabledPlugins || enabledPlugins?.length === 0) return []; - Object.keys(InternalPluginsMap).forEach(internalPlugin => { - if (!enabledPlugins.includes(internalPlugin)) { - plugins.push({ - name: internalPlugin, - version: '', - internal: true, - enabled: false, - role: '', - platform: '', - }); - } - }); - return plugins; -}; diff --git a/plugins/dynamic-plugins-info/src/index.ts b/plugins/dynamic-plugins-info/src/index.ts deleted file mode 100644 index 8c1a4ecd12..0000000000 --- a/plugins/dynamic-plugins-info/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './plugin'; -export { default as PluginsInfoIcon } from '@mui/icons-material/PowerOutlined'; -export { default as AdminIcon } from '@mui/icons-material/GppMaybeOutlined'; diff --git a/plugins/dynamic-plugins-info/src/plugin.test.ts b/plugins/dynamic-plugins-info/src/plugin.test.ts deleted file mode 100644 index 1b311ce7b4..0000000000 --- a/plugins/dynamic-plugins-info/src/plugin.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { dynamicPluginsInfoPlugin } from './plugin'; - -describe('dynamic-plugins-info', () => { - it('should export plugin', () => { - expect(dynamicPluginsInfoPlugin).toBeDefined(); - }); -}); diff --git a/plugins/dynamic-plugins-info/src/plugin.ts b/plugins/dynamic-plugins-info/src/plugin.ts deleted file mode 100644 index bf194f40ed..0000000000 --- a/plugins/dynamic-plugins-info/src/plugin.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - createApiFactory, - createComponentExtension, - createPlugin, - createRoutableExtension, - discoveryApiRef, - fetchApiRef, - identityApiRef, -} from '@backstage/core-plugin-api'; - -import { DynamicPluginsInfoClient } from './api/DynamicPluginsInfoClient'; -import { dynamicPluginsInfoApiRef } from './api/types'; -import { dynamicPluginsInfoRouteRef } from './routes'; - -export const dynamicPluginsInfoPlugin = createPlugin({ - id: 'dynamic-plugins-info', - routes: { - root: dynamicPluginsInfoRouteRef, - }, - apis: [ - createApiFactory({ - api: dynamicPluginsInfoApiRef, - deps: { - discoveryApi: discoveryApiRef, - fetchApi: fetchApiRef, - identityApi: identityApiRef, - }, - factory: ({ discoveryApi, fetchApi, identityApi }) => - new DynamicPluginsInfoClient({ discoveryApi, fetchApi, identityApi }), - }), - ], -}); - -export const DynamicPluginsInfoPage = dynamicPluginsInfoPlugin.provide( - createRoutableExtension({ - name: 'DynamicPluginsInfoPage', - component: () => - import('./components/DynamicPluginsInfoPage').then( - m => m.DynamicPluginsInfoPage, - ), - mountPoint: dynamicPluginsInfoRouteRef, - }), -); - -export const DynamicPluginsInfoContent = dynamicPluginsInfoPlugin.provide( - createComponentExtension({ - name: 'DynamicPluginsInfoContent', - component: { - lazy: () => - import( - './components/DynamicPluginsInfoContent/DynamicPluginsInfoContent' - ).then(m => m.DynamicPluginsInfoContent), - }, - }), -); diff --git a/plugins/dynamic-plugins-info/src/routes.ts b/plugins/dynamic-plugins-info/src/routes.ts deleted file mode 100644 index 478de64255..0000000000 --- a/plugins/dynamic-plugins-info/src/routes.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createRouteRef } from '@backstage/core-plugin-api'; - -export const dynamicPluginsInfoRouteRef = createRouteRef({ - id: 'dynamic-plugins-info', -}); diff --git a/plugins/dynamic-plugins-info/src/setupTests.ts b/plugins/dynamic-plugins-info/src/setupTests.ts deleted file mode 100644 index 7b0828bfa8..0000000000 --- a/plugins/dynamic-plugins-info/src/setupTests.ts +++ /dev/null @@ -1 +0,0 @@ -import '@testing-library/jest-dom'; diff --git a/plugins/dynamic-plugins-info/tsconfig.json b/plugins/dynamic-plugins-info/tsconfig.json deleted file mode 100644 index 89537c775b..0000000000 --- a/plugins/dynamic-plugins-info/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src", "dev", "migrations"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "../../dist-types/plugins/dynamic-plugins-info", - "rootDir": ".", - "jsx": "preserve" - } -} diff --git a/plugins/dynamic-plugins-info/turbo.json b/plugins/dynamic-plugins-info/turbo.json deleted file mode 100644 index aaf87bed7c..0000000000 --- a/plugins/dynamic-plugins-info/turbo.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": ["//"], - "tasks": { - "tsc": { - "outputs": ["../../dist-types/plugins/dynamic-plugins-info/**"] - } - } -} diff --git a/plugins/licensed-users-info-backend/package.json b/plugins/licensed-users-info-backend/package.json index 3aac522f5c..22bc0973d0 100644 --- a/plugins/licensed-users-info-backend/package.json +++ b/plugins/licensed-users-info-backend/package.json @@ -31,15 +31,15 @@ "prettier:fix": "prettier --ignore-unknown --write ." }, "dependencies": { - "@backstage-community/plugin-rbac-common": "1.18.0", - "@backstage/backend-defaults": "0.10.0", - "@backstage/backend-plugin-api": "1.3.1", - "@backstage/catalog-client": "1.10.0", - "@backstage/catalog-model": "1.7.4", - "@backstage/config": "1.3.2", + "@backstage-community/plugin-rbac-common": "1.20.0", + "@backstage/backend-defaults": "0.12.0", + "@backstage/backend-plugin-api": "1.4.2", + "@backstage/catalog-client": "1.11.0", + "@backstage/catalog-model": "1.7.5", + "@backstage/config": "1.3.3", "@backstage/errors": "1.2.7", - "@backstage/plugin-auth-backend": "0.25.0", - "@backstage/plugin-permission-common": "0.9.0", + "@backstage/plugin-auth-backend": "0.25.3", + "@backstage/plugin-permission-common": "0.9.1", "@backstage/types": "1.2.1", "express": "4.21.2", "express-promise-router": "4.1.1", @@ -49,15 +49,15 @@ "node-fetch": "2.7.0" }, "devDependencies": { - "@backstage/backend-test-utils": "1.5.0", - "@backstage/cli": "0.32.1", - "@backstage/plugin-auth-backend-module-guest-provider": "0.2.8", + "@backstage/backend-test-utils": "1.8.0", + "@backstage/cli": "0.34.1", + "@backstage/plugin-auth-backend-module-guest-provider": "0.2.11", "@types/express": "4.17.23", "@types/supertest": "6.0.3", "msw": "1.3.5", "prettier": "3.6.2", "supertest": "6.3.4", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist" diff --git a/plugins/licensed-users-info-backend/src/database/databaseUserInfoStore.ts b/plugins/licensed-users-info-backend/src/database/databaseUserInfoStore.ts index 72f1708031..a5a8ebdbae 100644 --- a/plugins/licensed-users-info-backend/src/database/databaseUserInfoStore.ts +++ b/plugins/licensed-users-info-backend/src/database/databaseUserInfoStore.ts @@ -3,7 +3,7 @@ import { Knex } from 'knex'; export type UserInfoRow = { user_entity_ref: string; user_info: string; - exp: string; + updated_at: string; }; export class DatabaseUserInfoStore { diff --git a/plugins/licensed-users-info-backend/src/service/router.ts b/plugins/licensed-users-info-backend/src/service/router.ts index 5aa57de504..09745218f2 100644 --- a/plugins/licensed-users-info-backend/src/service/router.ts +++ b/plugins/licensed-users-info-backend/src/service/router.ts @@ -127,20 +127,23 @@ export function rowToResponse( userInfoRow: UserInfoRow, tokenExpirationSeconds: number, ): UserInfoResponse { - let tokenExpirationDate = DateTime.fromSQL(userInfoRow.exp, { + let tokenExpirationDate = DateTime.fromSQL(userInfoRow.updated_at, { zone: 'utc', }); if (!tokenExpirationDate.isValid) { - tokenExpirationDate = DateTime.fromJSDate(new Date(userInfoRow.exp), { - zone: 'utc', - }); + tokenExpirationDate = DateTime.fromJSDate( + new Date(userInfoRow.updated_at), + { + zone: 'utc', + }, + ); } // Validate the date if (!tokenExpirationDate.isValid) { throw new Error( - 'Failed to parse expiration date format in userInfoRow.exp', + 'Failed to parse expiration date format in userInfoRow.updated_at', ); } diff --git a/plugins/scalprum-backend/package.json b/plugins/scalprum-backend/package.json index b2b7155e2e..d11a06ea55 100644 --- a/plugins/scalprum-backend/package.json +++ b/plugins/scalprum-backend/package.json @@ -31,17 +31,17 @@ "prettier:fix": "prettier --ignore-unknown --write ." }, "dependencies": { - "@backstage/backend-defaults": "0.10.0", - "@backstage/backend-dynamic-feature-service": "0.7.0", - "@backstage/backend-plugin-api": "1.3.1", - "@backstage/config": "1.3.2", + "@backstage/backend-defaults": "0.12.0", + "@backstage/backend-dynamic-feature-service": "0.7.3", + "@backstage/backend-plugin-api": "1.4.2", + "@backstage/config": "1.3.3", "express": "4.21.2", "node-fetch": "2.7.0", "winston": "3.14.2" }, "devDependencies": { - "@backstage/backend-test-utils": "1.5.0", - "@backstage/cli": "0.32.1", + "@backstage/backend-test-utils": "1.8.0", + "@backstage/cli": "0.34.1", "@types/express": "4.17.23", "@types/mock-fs": "4.13.4", "@types/supertest": "6.0.3", @@ -49,7 +49,7 @@ "msw": "1.3.5", "prettier": "3.6.2", "supertest": "6.3.4", - "typescript": "5.8.3" + "typescript": "5.9.3" }, "files": [ "dist" diff --git a/python/README.requirements.md b/python/README.requirements.md index 4b7b07ec15..eccc6d2ad7 100644 --- a/python/README.requirements.md +++ b/python/README.requirements.md @@ -1,6 +1,11 @@ # To iteratively add/fix requirements: -Add more to, or update existing dependencies in, the `requirements.in`, then: + +## Testing locally using github sources + +Add more to, or update existing dependencies in, the `requirements.in`. + +You can also remove all the pinned versions, then: ``` pip-compile --allow-unsafe --strip-extras requirements.in -o requirements.txt @@ -11,7 +16,7 @@ Try to install everything in `requirements.txt`: ``` rm -rf pyvenv.cfg lib* bin/* virtualenv .; . bin/activate -pip install -r requirements.txt +pip install --upgrade pip; pip install -r requirements.txt ``` If it fails, repeat previous step to add more dependencies `requirements.in` and repeat. @@ -35,11 +40,83 @@ If it passes, you can run `cachito_hash.sh` to fix the sha256sums. Finally, MAKE SURE YOU OVERRIDE what's in the .txt files to add in the cachito_hash values, as pip-compile will remove them. This can be done by running `cachito_hash.sh`. ``` -mkdocs-techdocs-core @ https://github.com/backstage/mkdocs-techdocs-core/archive/bbdab44e0d3aecfdc4e77b14c72b57791d4902b2.zip#cachito_hash=sha256:40421a5f43b11fd9ea9f92e107f91089b6bfa326967ad497666ab5a451fcf136 +# plantuml-markdown==3.9.7 plantuml-markdown @ https://github.com/mikitex70/plantuml-markdown/archive/fcf62aa930708368ec1daaad8b5b5dbe1d1b2014.zip#cachito_hash=sha256:a487c2312a53fe47a0947e8624290b2c8ea51e373140d02950531966b1db5caa + +# plantuml-markdown==3.11.1 +plantuml-markdown @ https://github.com/mikitex70/plantuml-markdown/archive/592837e9c26b9e92d711af42bce8fb8697183f9d.zip#cachito_hash=sha256:adb7dd7f1aa90a0fdb279f3ad58ede6cdc9eb826adc9d1405b02d4491e492df0 +``` + +## Testing locally with Hermeto + +To validate your requirements files in an offline way, you can use Hermeto. + +First, clone this repo if not already done + +```# for github, check out this project to some folder: +git_repo=/path/to/cloned/redhat-developer/rhdh + +# or for gitlab, check out the rhidp/rhdh project to some folder: +git_repo=/path/to/cloned/rhidp/rhdh +``` + +Next, regenerate the requirements*.txt files. + +You may also want to remove any versions pinned to the .in files to see if the latest deps can work together. + +``` +# for github +path_to_python=python + +# or for gitlab +path_to_python=distgit/containers/rhdh-hub/python + +cd "$git_repo" +cd "$path_to_python" +rm -fr "./requirements"*.txt && \ +pip-compile --output-file=requirements.txt --strip-extras requirements.in && \ +pip-compile --output-file=requirements-build.txt --strip-extras requirements-build.in + +# add the plantuml-markdown hash back in +hash=$(grep "plantuml-markdown @" requirements.in) && \ +sed -i requirements.txt -r -e "s|plantuml-markdown @.+|${hash}|" && \ +sed -i requirements-build.txt -r -e "s|plantuml-markdown @.+|${hash}|" + +cd - +``` + +Next, run Hermeto: + +``` +# "install" hermeto as a podman-run container: +alias hermeto='podman run --rm -ti -v "$PWD:$PWD:z" -w "$PWD" quay.io/konflux-ci/hermeto:latest' + +# make sure you're running repo clone folder or Hermeto will get lost: +cd "$git_repo" + +# fetch deps to see if anything breaks: +hermeto fetch-deps --source ${git_repo} --output /tmp/python-hermeto-github-output $(jq -c '.' ${git_repo}/python/hermeto_github.json) + +# or for gitlab: +hermeto fetch-deps --source ${git_repo} --output /tmp/python-hermeto-gitlab-output $(jq -c '.' ${git_repo}/distgit/containers/rhdh-hub/python/hermeto_gitlab.json) +``` + +Should see something like this: + +``` +2025-07-14 14:49:25,691 INFO Found name in setup.py: 'Python dependencies' +2025-07-14 14:49:25,691 INFO Found version in setup.py: '1.0' +2025-07-14 14:49:25,691 INFO Resolved name Python dependencies for package at /home/nboldt/4/tmp70bz7pdq.hermeto-source-copy/distgit/containers/rhdh-hub/python +2025-07-14 14:49:25,691 INFO Resolved version 1.0 for package at /home/nboldt/4/tmp70bz7pdq.hermeto-source-copy/distgit/containers/rhdh-hub/python +... +2025-07-14 14:50:30,784 INFO All dependencies fetched successfully \o/ ``` -To test in Konflux, using something like: +For more on Hermeto and pip, see https://github.com/hermetoproject/hermeto/blob/main/docs/pip.md + +## Testing in Konflux using gitlab sources + +To test in Konflux, repeat the above steps in the midstream (gitlab) repo, using something like: ``` pip3.11 install --user --no-cache-dir -r requirements.txt -r requirements-build.txt diff --git a/python/hermeto_github.json b/python/hermeto_github.json new file mode 100644 index 0000000000..c07ed98788 --- /dev/null +++ b/python/hermeto_github.json @@ -0,0 +1,7 @@ +{ + "type": "pip", + "path": "./python", + "requirements_files": ["requirements.txt"], + "requirements_build_files": ["requirements-build.txt"], + "allow_binary": "false" +} diff --git a/python/hermeto_gitlab.json b/python/hermeto_gitlab.json new file mode 100644 index 0000000000..a69f4c1a37 --- /dev/null +++ b/python/hermeto_gitlab.json @@ -0,0 +1,7 @@ +{ + "type": "pip", + "path": "./distgit/containers/rhdh-hub/python", + "requirements_files": ["requirements.txt"], + "requirements_build_files": ["requirements-build.txt"], + "allow_binary": "false" +} diff --git a/python/requirements-build.in b/python/requirements-build.in index a7d2220792..e1f8638ffa 100644 --- a/python/requirements-build.in +++ b/python/requirements-build.in @@ -47,7 +47,7 @@ text-unidecode==1.3 tomli==2.0.1 trove-classifiers typing-extensions -urllib3==2.5.0 +urllib3==2.2.2 watchdog==3.0.0 wheel wheel==0.43.0 diff --git a/python/requirements-build.txt b/python/requirements-build.txt index 2d47dd0001..8a8c433550 100644 --- a/python/requirements-build.txt +++ b/python/requirements-build.txt @@ -194,7 +194,7 @@ typing-extensions==4.12.2 # via # -r requirements-build.in # setuptools-scm -urllib3==2.5.0 +urllib3==2.2.2 # via # -r requirements-build.in # requests diff --git a/python/requirements.in b/python/requirements.in index 0b49fbe177..b4148f20ad 100644 --- a/python/requirements.in +++ b/python/requirements.in @@ -47,7 +47,7 @@ text-unidecode==1.3 tomli==2.0.1 trove-classifiers typing-extensions -urllib3==2.5.0 +urllib3==2.2.2 watchdog==3.0.0 wheel wheel==0.43.0 diff --git a/python/requirements.txt b/python/requirements.txt index e1c9e8099e..4bd5ff6ecc 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -194,7 +194,7 @@ typing-extensions==4.12.2 # via # -r requirements.in # setuptools-scm -urllib3==2.5.0 +urllib3==2.2.2 # via # -r requirements.in # requests diff --git a/rpms.in.yaml b/rpms.in.yaml new file mode 100644 index 0000000000..9cdd5a9fb7 --- /dev/null +++ b/rpms.in.yaml @@ -0,0 +1,365 @@ +# after editing, run (https://github.com/konflux-ci/rpm-lockfile-prototype): +# rpm-lockfile-prototype -f .rhdh/docker/Dockerfile rpms.in.yaml +# to regen rpms.lock.yaml +# Note that the repoid values are special, and must be from here: +# https://github.com/release-engineering/rhtap-ec-policy/blob/main/data/known_rpm_repositories.yml +allowerasing: true +contentOrigin: + repos: + - repoid: ubi-9-for-$basearch-appstream-rpms + baseurl: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/$basearch/appstream/os/ + - repoid: ubi-9-for-$basearch-appstream-source-rpms + baseurl: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/$basearch/appstream/source/SRPMS + - repoid: ubi-9-for-$basearch-baseos-rpms + baseurl: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/$basearch/baseos/os/ + - repoid: ubi-9-for-$basearch-baseos-source-rpms + baseurl: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/$basearch/baseos/source/SRPMS + # - repoid: codeready-builder-for-ubi-9-$basearch-rpms + # baseurl: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/$basearch/codeready-builder/os/ + # # gpgcheck: 0 + # - repoid: codeready-builder-for-ubi-9-$basearch-source-rpms + # baseurl: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/$basearch/codeready-builder/source/SRPMS + # # gpgcheck: 0 + +moduleEnable: + - nodejs:22 +packages: + - acl + - alsa-lib + - alternatives + - at-spi2-atk + - at-spi2-core + - atk + - attr + - audit-libs + - basesystem + - bash + - binutils + - binutils-gold + - brotli + - brotli-devel + - bsdtar + - bzip2-libs + - ca-certificates + - cairo + - containers-common + - coreutils-single + - cmake + - cpp + - cracklib + - cracklib-dicts + - criu + - criu-libs + - crun + - crypto-policies + - crypto-policies-scripts + - cups-libs + - curl-minimal + - cyrus-sasl-lib + - dbus + - dbus-broker + - dbus-common + - dbus-libs + - dejavu-sans-fonts + - dmidecode + - dnf + - dnf-data + - elfutils-debuginfod-client + - elfutils-default-yama-scope + - elfutils-libelf + - elfutils-libs + - emacs-filesystem + - environment-modules + - expat + - file-libs + - filesystem + - findutils + - fonts-filesystem + - fuse-common + - fuse-overlayfs + - fuse3 + - fuse3-libs + - gawk + - gcc + - gcc-c++ + - gdb-gdbserver + - gdbm-libs + - gettext + - gettext-libs + - git + - git-core + - git-core-doc + - glib2 + - glibc + - glibc-common + - glibc-devel + - glibc-headers + - glibc-langpack-en + - glibc-locale-source + - glibc-minimal-langpack + - gmp + - gnupg2 + - gnutls + - gobject-introspection + - gpgme + - grep + - groff-base + - gzip + - ima-evm-utils + - iproute + - json-c + - json-glib + - kernel-headers + - keyutils + - keyutils-libs + - kmod + - kmod-libs + - krb5-libs + - langpacks-core-en + - langpacks-core-font-en + - langpacks-en + - less + - libacl + - libarchive + - libassuan + - libattr + - libblkid + - libbpf + - libbrotli + - libcap + - libcap-ng + - libcbor + - libcom_err + - libcomps + - libcurl-minimal + - libdb + - libdnf + - libdnf-plugin-subscription-manager + - libdrm + - libeconf + - libedit + - libevent + - libfdisk + - libffi + - libfido2 + - libgcc + - libgcrypt + - libgomp + - libgpg-error + - libidn2 + - libksba + - libmnl + - libmodulemd + - libmount + - libmpc + - libnet + - libnghttp2 + - libnl3 + - libpipeline + - libpkgconf + - libpwquality + - librepo + - libreport-filesystem + - librhsm + - libseccomp + - libselinux + - libsemanage + - libsepol + - libsigsegv + - libslirp + - libsmartcols + - libsolv + - libstdc++ + - libstdc++-devel + - libtasn1 + - libunistring + - libuser + - libutempter + - libuuid + - libverto + - libX11 + - libX11-xcb + - libXcomposite + - libxcrypt + - libxcrypt-compat + - libxcrypt-devel + - libXdamage + - libXext + - libXfixes + - libxkbcommon + - libxml2 + - libXrandr + - libyaml + - libzstd + - lua-libs + - lz4-libs + - make + - man + - mesa-libgbm + - mpfr + - ncurses + - ncurses-base + - ncurses-libs + - nettle + - npth + - nspr + - nss + - nss_wrapper-libs + - openldap + - openssh + - openssh-clients + - openssl + - openssl-devel + - openssl-fips-provider + - openssl-fips-provider-so + - openssl-libs + - p11-kit + - p11-kit-trust + - pam + - pango + - passwd + - pcre + - pcre2 + - pcre2-syntax + - perl + - perl-AutoLoader + - perl-B + - perl-base + - perl-Carp + - perl-Class-Struct + - perl-constant + - perl-Data-Dumper + - perl-Digest + - perl-Digest-MD5 + - perl-DynaLoader + - perl-Encode + - perl-Errno + - perl-Error + - perl-Exporter + - perl-Fcntl + - perl-File-Basename + - perl-File-Find + - perl-File-Path + - perl-File-stat + - perl-File-Temp + - perl-FileHandle + - perl-Getopt-Long + - perl-Getopt-Std + - perl-Git + - perl-HTTP-Tiny + - perl-interpreter + - perl-IO + - perl-IO-Socket-IP + - perl-IO-Socket-SSL + - perl-IPC-Open3 + - perl-lib + - perl-libnet + - perl-libs + - perl-MIME-Base64 + - perl-Mozilla-CA + - perl-mro + - perl-NDBM_File + - perl-Net-SSLeay + - perl-overload + - perl-overloading + - perl-parent + - perl-PathTools + - perl-Pod-Escapes + - perl-Pod-Perldoc + - perl-Pod-Simple + - perl-Pod-Usage + - perl-podlators + - perl-POSIX + - perl-Scalar-List-Utils + - perl-SelectSaver + - perl-Socket + - perl-Storable + - perl-subs + - perl-Symbol + - perl-Term-ANSIColor + - perl-Term-Cap + - perl-TermReadKey + - perl-Text-ParseWords + - perl-Text-Tabs+Wrap + - perl-Time-Local + - perl-URI + - perl-vars + - pkgconf + - pkgconf-m4 + - pkgconf-pkg-config + - popt + - procps-ng + - protobuf-c + - psmisc + - python3-chardet + - python3-cloud-what + - python3-dateutil + - python3-dbus + - python3-decorator + - python3-dnf + - python3-dnf-plugins-core + - python3-gobject-base + - python3-gobject-base-noarch + - python3-gpg + - python3-hawkey + - python3-iniparse + - python3-inotify + - python3-libcomps + - python3-libdnf + - python3-librepo + - python3-pip + - python3-rpm + - python3-subscription-manager-rhsm + - python3-systemd + - python3.11 + - python3.11-devel + - python3.11-idna + - python3.11-pip + - python3.11-pip-wheel + - python3.11-pysocks + - python3.11-requests + - python3.11-setuptools + - python3.11-setuptools-wheel + - python3.11-urllib3 + - readline + - redhat-release + - rootfiles + - rpm + - rpm-build-libs + - rpm-libs + - rpm-plugin-selinux + - rpm-sign-libs + - rsync + - scl-utils + - sed + - selinux-policy + - selinux-policy-targeted + - setup + - shadow-utils + - skopeo + - slirp4netns + - sqlite-libs + - subscription-manager + - subscription-manager-rhsm-certificates + - systemd + - systemd-libs + - systemd-pam + - systemd-rpm-macros + - tar + - tcl + - tpm2-tss + - tzdata + - unzip + - usermode + - util-linux + - util-linux-core + - vim-filesystem + - vim-minimal + - virt-what + - which + - xz + - xz-libs + - yajl + - yum + - zlib + - zlib-devel diff --git a/rpms.lock.yaml b/rpms.lock.yaml new file mode 100644 index 0000000000..dc9553318f --- /dev/null +++ b/rpms.lock.yaml @@ -0,0 +1,5172 @@ +--- +lockfileVersion: 1 +lockfileVendor: redhat +arches: +- arch: x86_64 + packages: + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/a/alsa-lib-1.2.13-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 542585 + checksum: sha256:fdb83e171266628cc89b0ac9697e47038ef17aae3341f05a6cb13201fb39fb49 + name: alsa-lib + evr: 1.2.13-2.el9 + sourcerpm: alsa-lib-1.2.13-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/a/annobin-12.92-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 1106759 + checksum: sha256:3e28996cf349e045628002c66c1ff0bc3977f97e30dfe692f56211d64183d324 + name: annobin + evr: 12.92-1.el9 + sourcerpm: annobin-12.92-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/a/at-spi2-atk-2.38.0-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 92491 + checksum: sha256:e8b1f1128e90e9b9d8572f8357d3f2f79e2f9545a7563a88ad9c9cf04230f6ee + name: at-spi2-atk + evr: 2.38.0-4.el9 + sourcerpm: at-spi2-atk-2.38.0-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/a/at-spi2-core-2.40.3-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 203784 + checksum: sha256:ef886779a18650356b048d5240b67281c8efdae0abd1451895202ce7de6b70e0 + name: at-spi2-core + evr: 2.40.3-1.el9 + sourcerpm: at-spi2-core-2.40.3-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/a/atk-2.36.0-5.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 302773 + checksum: sha256:69f4b9213ab26010346d18206b858743d73018a3781dffa3305f14709bd9c67c + name: atk + evr: 2.36.0-5.el9 + sourcerpm: atk-2.36.0-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/b/brotli-1.0.9-7.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 320286 + checksum: sha256:9d9be6ff56dc68c384cb442ce07baf4f2ea21bdc95d81e182d45b3fe30bce2f1 + name: brotli + evr: 1.0.9-7.el9_5 + sourcerpm: brotli-1.0.9-7.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/b/brotli-devel-1.0.9-7.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 35192 + checksum: sha256:4d7eddea467c95912c33e091c8cf5648137f51e76707bf68b2bf51446718520d + name: brotli-devel + evr: 1.0.9-7.el9_5 + sourcerpm: brotli-1.0.9-7.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/b/bsdtar-3.5.3-6.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 62947 + checksum: sha256:d209727edfdabb977bc409d12883b82965eda99407c19c72fa730669851f22dc + name: bsdtar + evr: 3.5.3-6.el9_6 + sourcerpm: libarchive-3.5.3-6.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/cairo-1.17.4-7.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 680200 + checksum: sha256:a97d3ff0ab1a6b028dd68e8753f13d568e7f3e66b6890531fd600bbc9817c4fc + name: cairo + evr: 1.17.4-7.el9 + sourcerpm: cairo-1.17.4-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/cmake-3.26.5-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9159462 + checksum: sha256:f553370cb02b87e7388697468256556e765b102c2fcb56be6bc250cb2351e8ad + name: cmake + evr: 3.26.5-2.el9 + sourcerpm: cmake-3.26.5-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/cmake-data-3.26.5-2.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 2488227 + checksum: sha256:84da65a7b8921f031d15903d91c5967022620f9e96b7493c8ab8024014755ee7 + name: cmake-data + evr: 3.26.5-2.el9 + sourcerpm: cmake-3.26.5-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/cmake-filesystem-3.26.5-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 23450 + checksum: sha256:49fafe6c2b29fdede611a0a78664021d13f7126599e37ebff92bcb06d18f58b6 + name: cmake-filesystem + evr: 3.26.5-2.el9 + sourcerpm: cmake-3.26.5-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/cmake-rpm-macros-3.26.5-2.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12250 + checksum: sha256:1c74969c8a4f21851f5b89f25ac55c689b75bed1318d0435fc3a14a49c39d0e3 + name: cmake-rpm-macros + evr: 3.26.5-2.el9 + sourcerpm: cmake-3.26.5-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/container-selinux-2.237.0-2.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 60424 + checksum: sha256:d6f3a1a16bf8d80e505ce1a464e6897a6cf6193ff407d515fcd0c8ae2ff4c56a + name: container-selinux + evr: 4:2.237.0-2.el9_6 + sourcerpm: container-selinux-2.237.0-2.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/containers-common-1-117.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 158417 + checksum: sha256:4a45b00847d30c3c804a6184af69e0e11836be975e51960596ce31c459a5d532 + name: containers-common + evr: 2:1-117.el9_6 + sourcerpm: containers-common-1-117.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/cpp-11.5.0-5.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 11229073 + checksum: sha256:b5567c690d46d4f5a2cb13be6a4f962dbe8cc7e821b9d3baa09a4f10c59014d9 + name: cpp + evr: 11.5.0-5.el9_5 + sourcerpm: gcc-11.5.0-5.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/criu-3.19-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 576009 + checksum: sha256:823ac6aab1745521039d5aa4db2e843cb632854449d5b06420eb52825a985b59 + name: criu + evr: 3.19-1.el9 + sourcerpm: criu-3.19-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/criu-libs-3.19-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 33643 + checksum: sha256:bb821ddf9bd0321e0750d2fc5cadd5f531e67cafacf6d92512e714b31133a64d + name: criu-libs + evr: 3.19-1.el9 + sourcerpm: criu-3.19-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/c/crun-1.23.1-2.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 249255 + checksum: sha256:0f885a416fe6086cf8d5e2dca053fdc8366e7878be939da6fe049dbb685eaa06 + name: crun + evr: 1.23.1-2.el9_6 + sourcerpm: crun-1.23.1-2.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/d/dwz-0.14-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 133177 + checksum: sha256:9b429a1abaadc0fd63cb0667ef5bc5ec4db4debc340f7f5742a9252dd8301a30 + name: dwz + evr: 0.14-3.el9 + sourcerpm: dwz-0.14-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/e/efi-srpm-macros-6-2.el9_0.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 24452 + checksum: sha256:1a1fa7561f5cef960b36c6a796d8a6fb4af70511118dacbfd5f707181a6c02fe + name: efi-srpm-macros + evr: 6-2.el9_0 + sourcerpm: efi-rpm-macros-6-2.el9_0.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/e/emacs-filesystem-27.2-14.el9_6.2.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9099 + checksum: sha256:49bb85cb79889ae677f6961f4582eb28620864257abfe5b00a05ae0073cb2dd6 + name: emacs-filesystem + evr: 1:27.2-14.el9_6.2 + sourcerpm: emacs-27.2-14.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/f/fontconfig-2.14.0-2.el9_1.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 307951 + checksum: sha256:229b88e1750e7b54de9049392350d202b1025f5750a7e4e55a575ffb9519a6ae + name: fontconfig + evr: 2.14.0-2.el9_1 + sourcerpm: fontconfig-2.14.0-2.el9_1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/f/fonts-srpm-macros-2.0.5-7.el9.1.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 30140 + checksum: sha256:f8c6aaa6af574698f6d1a7eb8e7f6ed725e4366dc14553bc816f5aa305675367 + name: fonts-srpm-macros + evr: 1:2.0.5-7.el9.1 + sourcerpm: fonts-rpm-macros-2.0.5-7.el9.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/f/fribidi-1.0.10-6.el9.2.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 90847 + checksum: sha256:c4483b10a1b3bfd2ccdd70fbeb34d1b0f9c264edc71afbcd42c0aa7d72a38b41 + name: fribidi + evr: 1.0.10-6.el9.2 + sourcerpm: fribidi-1.0.10-6.el9.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/f/fuse-overlayfs-1.14-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 71022 + checksum: sha256:884e4034c930e0305d2402da2bdc1eac5a91295da06e554b75c1c9a4529ddbc2 + name: fuse-overlayfs + evr: 1.14-1.el9 + sourcerpm: fuse-overlayfs-1.14-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/f/fuse3-3.10.2-9.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 58706 + checksum: sha256:4674b4ee6150c8f8be01a028a471c209a6be7c0cf78e9450cf28fb01eaed9ea2 + name: fuse3 + evr: 3.10.2-9.el9 + sourcerpm: fuse3-3.10.2-9.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/f/fuse3-libs-3.10.2-9.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 95573 + checksum: sha256:945e1d95edbce9c7dba52e9317d4564381efa5a1ba48d4bd49a58c85e47cd717 + name: fuse3-libs + evr: 3.10.2-9.el9 + sourcerpm: fuse3-3.10.2-9.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/gcc-11.5.0-5.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 34006000 + checksum: sha256:03c99bc1021dbe54dd93120ed6b5249bbb02dbd5da9e0dc5d8c4a21d674fb1fd + name: gcc + evr: 11.5.0-5.el9_5 + sourcerpm: gcc-11.5.0-5.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/gcc-c++-11.5.0-5.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13479598 + checksum: sha256:b8392274e302d665bc132aee4ed023f8a777d9c446531679ede18150d7867189 + name: gcc-c++ + evr: 11.5.0-5.el9_5 + sourcerpm: gcc-11.5.0-5.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/gcc-plugin-annobin-11.5.0-5.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42533 + checksum: sha256:9af134e5b2e2fae5a0b33253abdad68c0cb854f14e2668853c9b42e00c098a5a + name: gcc-plugin-annobin + evr: 11.5.0-5.el9_5 + sourcerpm: gcc-11.5.0-5.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/gdb-gdbserver-14.2-4.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 314667 + checksum: sha256:531e904c20e46b19822a4d5e10856438c1884e516d846487dabebba031ac578f + name: gdb-gdbserver + evr: 14.2-4.1.el9_6 + sourcerpm: gdb-14.2-4.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/ghc-srpm-macros-1.5.0-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9252 + checksum: sha256:80fb1c39b5d8c23352b8928332fa0794e679e054ffa3f04a34c2b18bb7e28c93 + name: ghc-srpm-macros + evr: 1.5.0-6.el9 + sourcerpm: ghc-srpm-macros-1.5.0-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/git-2.47.3-1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 51883 + checksum: sha256:5097b6a0540e33dd02d581109cf1b10fcc736975c330208fae148efacb13b649 + name: git + evr: 2.47.3-1.el9_6 + sourcerpm: git-2.47.3-1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/git-core-2.47.3-1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 4926340 + checksum: sha256:4056d5f982607b0c8106ad1467b396be4abf150d8532fe018c9dc469cf149411 + name: git-core + evr: 2.47.3-1.el9_6 + sourcerpm: git-2.47.3-1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/git-core-doc-2.47.3-1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 3195826 + checksum: sha256:0008ecada894ff2a51c43f868b7727baae3836911b541a613769d2e93d501442 + name: git-core-doc + evr: 2.47.3-1.el9_6 + sourcerpm: git-2.47.3-1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/glibc-devel-2.34-168.el9_6.23.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 34295 + checksum: sha256:0fa11752abf8ee80658e10017c62f7c0301bcae4008e4716fe6f114a7b9e3977 + name: glibc-devel + evr: 2.34-168.el9_6.23 + sourcerpm: glibc-2.34-168.el9_6.23.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/glibc-headers-2.34-168.el9_6.23.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 553222 + checksum: sha256:b090ce707af3eb4d6a20e57fe780502d363892ecaaa41bc1575e4c6c5912f2ab + name: glibc-headers + evr: 2.34-168.el9_6.23 + sourcerpm: glibc-2.34-168.el9_6.23.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/glibc-locale-source-2.34-168.el9_6.23.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 4356630 + checksum: sha256:2d260f1f73a9ee8308b211778ed1799414e8b96dea0d9d43fcda4197a9bc5bfb + name: glibc-locale-source + evr: 2.34-168.el9_6.23 + sourcerpm: glibc-2.34-168.el9_6.23.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/g/go-srpm-macros-3.6.0-10.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 28143 + checksum: sha256:c1cbc05c812994c77b7f7bf80e76039c94d6ba887c9169228833e7e702aa095a + name: go-srpm-macros + evr: 3.6.0-10.el9_6 + sourcerpm: go-rpm-macros-3.6.0-10.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/k/kernel-headers-5.14.0-570.55.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 3733025 + checksum: sha256:a15a60842f50b17c45fba989d34db6fac5bd5955e9b3930d85733f9a3e84cb21 + name: kernel-headers + evr: 5.14.0-570.55.1.el9_6 + sourcerpm: kernel-5.14.0-570.55.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/k/kernel-srpm-macros-1.0-13.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 17792 + checksum: sha256:7e891fa264fb538bf4a26aa94e91ff0c3084bf2613e2061dbb6f4f0c26856777 + name: kernel-srpm-macros + evr: 1.0-13.el9 + sourcerpm: kernel-srpm-macros-1.0-13.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libX11-1.7.0-11.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 663116 + checksum: sha256:d9b515a65727621e20804bf5bc0c1cb80466c3eb1070cc755fa54014bbbe580b + name: libX11 + evr: 1.7.0-11.el9 + sourcerpm: libX11-1.7.0-11.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libX11-common-1.7.0-11.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 214201 + checksum: sha256:6c71dcb5ecbf19b1d7cd72a48a399d0208942bf07afd529effe3ed426499512b + name: libX11-common + evr: 1.7.0-11.el9 + sourcerpm: libX11-1.7.0-11.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libX11-xcb-1.7.0-11.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12795 + checksum: sha256:dd0d8d9e16ba0069a58b3ae02cf49b67fe7d59c6427ff44a4b90450156805902 + name: libX11-xcb + evr: 1.7.0-11.el9 + sourcerpm: libX11-1.7.0-11.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXau-1.0.9-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 34395 + checksum: sha256:ec895f13b3babb4ed27e5c5f6718c462808af58d636a90a45745accca8e26a94 + name: libXau + evr: 1.0.9-8.el9 + sourcerpm: libXau-1.0.9-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXcomposite-0.4.5-7.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 27006 + checksum: sha256:2a318d5306cbbeddc409d6310269f755cc597370ab550e8c04b5aca3fd514e50 + name: libXcomposite + evr: 0.4.5-7.el9 + sourcerpm: libXcomposite-0.4.5-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXdamage-1.1.5-7.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25662 + checksum: sha256:743c3c507140a8927ed7b062f11d1b0aea775e5b842575c5189d917cdf101642 + name: libXdamage + evr: 1.1.5-7.el9 + sourcerpm: libXdamage-1.1.5-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXext-1.3.4-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42529 + checksum: sha256:c295f071518f6366131e7b143e6c37f30caf6fdb51a0aec8ba516364e6bbde91 + name: libXext + evr: 1.3.4-8.el9 + sourcerpm: libXext-1.3.4-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXfixes-5.0.3-16.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22318 + checksum: sha256:eeac342b5233b335f15832e92eda87b04b054108fc0f9edd05c1404bc5312c7f + name: libXfixes + evr: 5.0.3-16.el9 + sourcerpm: libXfixes-5.0.3-16.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXft-2.3.3-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 65929 + checksum: sha256:05372e66ce337a73f29f5839b7504f23b05104fad900fc2556901b27a7ee4752 + name: libXft + evr: 2.3.3-8.el9 + sourcerpm: libXft-2.3.3-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXi-1.7.10-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42155 + checksum: sha256:0271faeb8661cd275d341f5cc95d422ae425374160dce7b4f691f154764a66d8 + name: libXi + evr: 1.7.10-8.el9 + sourcerpm: libXi-1.7.10-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXrandr-1.5.2-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 30948 + checksum: sha256:74d6f01f5986c28837c7bcc527ed4a984fb23625dd845c780e04ad4b5790e4b5 + name: libXrandr + evr: 1.5.2-8.el9 + sourcerpm: libXrandr-1.5.2-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXrender-0.9.10-16.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 30453 + checksum: sha256:ab69ef172aaae7535eac07e516a4973d5d7e386e0e693af5f901806f7b527676 + name: libXrender + evr: 0.9.10-16.el9 + sourcerpm: libXrender-0.9.10-16.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libXtst-1.2.3-16.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 23624 + checksum: sha256:d111d50960014b1fcac7a736be0cae30477c57fa5c026edcc823341ffa5ab87f + name: libXtst + evr: 1.2.3-16.el9 + sourcerpm: libXtst-1.2.3-16.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libdatrie-0.2.13-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 35144 + checksum: sha256:21eb2f4481898f6de999b37c3dee2763ed6d530cf5a5147acad2da48871beae5 + name: libdatrie + evr: 0.2.13-4.el9 + sourcerpm: libdatrie-0.2.13-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libdrm-2.4.123-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 169101 + checksum: sha256:197a76452582e100fe86803dee8afbb415bc78a11e8421dce5b5acbde39e382d + name: libdrm + evr: 2.4.123-2.el9 + sourcerpm: libdrm-2.4.123-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libmpc-1.2.1-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 66075 + checksum: sha256:b97b4e98c3c6f41dcfc2ceb4ffa1aba7a338b7cfd9e6c4f63e3160dd3cc033d3 + name: libmpc + evr: 1.2.1-4.el9 + sourcerpm: libmpc-1.2.1-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libnet-1.2-7.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 61278 + checksum: sha256:738b9a7ab78c149487e349d90c384b59031d5763ba687a6b58a4f853671af86b + name: libnet + evr: 1.2-7.el9 + sourcerpm: libnet-1.2-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libnsl2-2.0.0-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 33287 + checksum: sha256:052f7a182180528ba6e3c4378e5dcfb84640594a3e2e7bbe4f0167381e824ce0 + name: libnsl2 + evr: 2.0.0-1.el9 + sourcerpm: libnsl2-2.0.0-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libslirp-4.4.0-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 71992 + checksum: sha256:9bd269ec50504f997683e963481f870bb937c3cfdb54a057e9acca67bf2b7631 + name: libslirp + evr: 4.4.0-8.el9 + sourcerpm: libslirp-4.4.0-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libstdc++-devel-11.5.0-5.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 2531717 + checksum: sha256:84695eeeb1daa8ff74baf7efd9fc57fb136bec7e8a2ca56c105be6d83ec22d07 + name: libstdc++-devel + evr: 11.5.0-5.el9_5 + sourcerpm: gcc-11.5.0-5.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libthai-0.1.28-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 216254 + checksum: sha256:289d4e53a6d59ba84dffc9ad5f8312bf9c14dc7528556e1a0e94c71428ead7e1 + name: libthai + evr: 0.1.28-8.el9 + sourcerpm: libthai-0.1.28-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libuv-1.42.0-2.el9_4.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 154427 + checksum: sha256:e1fab39251239ccaad2fb4dbe6c55ec1ae60f76d4ae81582b06e6a58e30879b2 + name: libuv + evr: 1:1.42.0-2.el9_4 + sourcerpm: libuv-1.42.0-2.el9_4.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libwayland-server-1.21.0-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 44352 + checksum: sha256:0f6975e768796f109827b74d377c4289de52aaefb8d05ab662fc26755cb80eb9 + name: libwayland-server + evr: 1.21.0-1.el9 + sourcerpm: wayland-1.21.0-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libxcb-1.13.1-9.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 252989 + checksum: sha256:a95c41c93768b9f4a1a0a57140866f5e48dc722d15ae10b39edab8b24794e5bf + name: libxcb + evr: 1.13.1-9.el9 + sourcerpm: libxcb-1.13.1-9.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libxcrypt-compat-4.4.18-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 93189 + checksum: sha256:2bd6c288e1970a001d3a1ae69166c0d926d9c87ce892edcb2110f4e142c12a7a + name: libxcrypt-compat + evr: 4.4.18-3.el9 + sourcerpm: libxcrypt-4.4.18-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libxcrypt-devel-4.4.18-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 33101 + checksum: sha256:c1d171391a7d2e043a6953efd3df3e01edc9b4c6cdb54517e1608d204a5fce18 + name: libxcrypt-devel + evr: 4.4.18-3.el9 + sourcerpm: libxcrypt-4.4.18-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libxkbcommon-1.0.3-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 139163 + checksum: sha256:b609731c8a40ea473e147102fc0bd05ec059b3a1aa2c910326b283c6ea4736e1 + name: libxkbcommon + evr: 1.0.3-4.el9 + sourcerpm: libxkbcommon-1.0.3-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/libxshmfence-1.3-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14099 + checksum: sha256:d4bbbb26d1f725d721724ae734c25e61f97f4252eaf6b3e51884b10e662a10be + name: libxshmfence + evr: 1.3-10.el9 + sourcerpm: libxshmfence-1.3-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/llvm-libs-19.1.7-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 30399454 + checksum: sha256:168c8d2d7ed92d3a77c2d8ba898b3506a483a623674072d057606cb29d2e3b87 + name: llvm-libs + evr: 19.1.7-2.el9 + sourcerpm: llvm-19.1.7-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/l/lua-srpm-macros-1-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 10476 + checksum: sha256:64946edfd54f7d4668f7fdcb7be961ceaca8cff7d0bef438bef4e2498ccf3cd6 + name: lua-srpm-macros + evr: 1-6.el9 + sourcerpm: lua-rpm-macros-1-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/m/mesa-dri-drivers-24.2.8-3.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9837523 + checksum: sha256:4baeac62f82dcd6ed1319cfa34ad1f7123a9dfdd42ba0b0c484d01fbf9f9b805 + name: mesa-dri-drivers + evr: 24.2.8-3.el9_6 + sourcerpm: mesa-24.2.8-3.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/m/mesa-filesystem-24.2.8-3.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 10776 + checksum: sha256:cefd073cce1d96c2fa737da4cf255dc430ae1d8bc3793ee0cc067d2e3a4a4406 + name: mesa-filesystem + evr: 24.2.8-3.el9_6 + sourcerpm: mesa-24.2.8-3.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/m/mesa-libgbm-24.2.8-3.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 36446 + checksum: sha256:436edc5022667a01cec4bd7499f16c1fa22eea36a99ecc0902fd82115d690091 + name: mesa-libgbm + evr: 24.2.8-3.el9_6 + sourcerpm: mesa-24.2.8-3.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/m/mesa-libglapi-24.2.8-3.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 45330 + checksum: sha256:4a70de296f3bec329440c23a28b17f05d5f533d6abcf23363a4ade863e711e33 + name: mesa-libglapi + evr: 24.2.8-3.el9_6 + sourcerpm: mesa-24.2.8-3.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/m/mpdecimal-2.5.1-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 89670 + checksum: sha256:89a8c9951ac56bed2caa1adbcba349c021af1134b6e2df3fc0a8a60577a4f54d + name: mpdecimal + evr: 2.5.1-3.el9 + sourcerpm: mpdecimal-2.5.1-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/n/nspr-4.36.0-4.el9_4.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 136524 + checksum: sha256:dd9a598390e8adfebdcec7adbc5aa140d6584ede4d581d5fec328d2e4a5107db + name: nspr + evr: 4.36.0-4.el9_4 + sourcerpm: nss-3.112.0-4.el9_4.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/n/nss-3.112.0-4.el9_4.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 740527 + checksum: sha256:6eefe50251cf43934ea5c949a0f23e0da20d81262394e7824328e0f21aabbe88 + name: nss + evr: 3.112.0-4.el9_4 + sourcerpm: nss-3.112.0-4.el9_4.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/n/nss-softokn-3.112.0-4.el9_4.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 409821 + checksum: sha256:ac09b91c717cf003714b62cb033bea51770c887fdc70426f625a677e50b0813f + name: nss-softokn + evr: 3.112.0-4.el9_4 + sourcerpm: nss-3.112.0-4.el9_4.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/n/nss-softokn-freebl-3.112.0-4.el9_4.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 423244 + checksum: sha256:1eb3fb60d885f3a1071dcb335e1ee34c156bbc50c797f42772d61412a91db8f5 + name: nss-softokn-freebl + evr: 3.112.0-4.el9_4 + sourcerpm: nss-3.112.0-4.el9_4.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/n/nss-sysinit-3.112.0-4.el9_4.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 18225 + checksum: sha256:5b5314ce6088f161b2a404b566c6d5016811b6c12e90c7bf70d3fd281168d659 + name: nss-sysinit + evr: 3.112.0-4.el9_4 + sourcerpm: nss-3.112.0-4.el9_4.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/n/nss-util-3.112.0-4.el9_4.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 91543 + checksum: sha256:3904f1eab4e56789d8d818d0ca4a76c49d1ef5de947ccdabaf64f9d748ad05df + name: nss-util + evr: 3.112.0-4.el9_4 + sourcerpm: nss-3.112.0-4.el9_4.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/n/nss_wrapper-libs-1.1.13-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42421 + checksum: sha256:4502ad25db18ef8a48d37d513d6c685f33b91cf209db98f7f3387af105db4326 + name: nss_wrapper-libs + evr: 1.1.13-1.el9 + sourcerpm: nss_wrapper-1.1.13-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/o/ocaml-srpm-macros-6-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9270 + checksum: sha256:783710ad3710e594275fb23d280f030a68279927ca82ce38787f4c93971eaa88 + name: ocaml-srpm-macros + evr: 6-6.el9 + sourcerpm: ocaml-srpm-macros-6-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/o/openblas-srpm-macros-2-11.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 8807 + checksum: sha256:091911db0712bfe9b03952046191438bdd9b1080558e0c1014611d39aa80571d + name: openblas-srpm-macros + evr: 2-11.el9 + sourcerpm: openblas-srpm-macros-2-11.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/o/openssl-devel-3.2.2-6.el9_5.1.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 4650823 + checksum: sha256:30cd1b3dec089a7da71e9167532693bef7c202a5dbe3c010af2a9387106a0b36 + name: openssl-devel + evr: 1:3.2.2-6.el9_5.1 + sourcerpm: openssl-3.2.2-6.el9_5.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/pango-1.48.7-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 313015 + checksum: sha256:496a309e10e050e8e647624fbda6a319a52434894479302e1a5244aa54168015 + name: pango + evr: 1.48.7-3.el9 + sourcerpm: pango-1.48.7-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-5.32.1-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 8429 + checksum: sha256:74d2e4262c902dd95287455934c265d9a406fc316b490f37c72deda9adefc5e7 + name: perl + evr: 4:5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Algorithm-Diff-1.2010-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 52041 + checksum: sha256:3d252e247a41978a10faef66931ac5fb2525c7fa708d8caa537d368ef5ba62ce + name: perl-Algorithm-Diff + evr: 1.2010-4.el9 + sourcerpm: perl-Algorithm-Diff-1.2010-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Archive-Tar-2.38-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 77744 + checksum: sha256:5cf97230d350543cdf34f379dc04e1383f89591ad76768b5a2738b474cdec404 + name: perl-Archive-Tar + evr: 2.38-6.el9 + sourcerpm: perl-Archive-Tar-2.38-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Archive-Zip-1.68-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 118766 + checksum: sha256:2237a7cdfa30cda2ad475cb6ee5796f1e4cafa07e8760e08bca8d252cd6eb51d + name: perl-Archive-Zip + evr: 1.68-6.el9 + sourcerpm: perl-Archive-Zip-1.68-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Attribute-Handlers-1.01-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 27731 + checksum: sha256:95ee8b22f5c962b56b95dc3e74280ed1471c17bb2031995d3efd431478e40aac + name: perl-Attribute-Handlers + evr: 1.01-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-AutoLoader-5.74-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 21344 + checksum: sha256:b4557d853be8048aaefde5c4083c43fa34375e224731e93e584e4e3d5db46ac3 + name: perl-AutoLoader + evr: 5.74-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-AutoSplit-5.74-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 21714 + checksum: sha256:de53b7057da078864d27f4acddf37594d40ee4d5f710d129c40cfb5c6097ceb0 + name: perl-AutoSplit + evr: 5.74-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-B-1.80-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 183818 + checksum: sha256:8b5a3d27f69cce8dd4c237510c2aaa2d01b3e884452e5da467d9c41015372c6a + name: perl-B + evr: 1.80-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Benchmark-1.23-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 27055 + checksum: sha256:690cc6ca69fd267f025ddc18116d8f10dff6693645ff949820c83ed7776aa454 + name: perl-Benchmark + evr: 1.23-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-CPAN-2.29-5.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 589480 + checksum: sha256:a46e7bb747f0b5dc26d8eda788b98492576048f5df271d070c35118f8d980b9d + name: perl-CPAN + evr: 2.29-5.el9_6 + sourcerpm: perl-CPAN-2.29-5.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-CPAN-DistnameInfo-0.12-23.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 17060 + checksum: sha256:35687783ded44b01c37af59f66499b42e10df074c36608fc3f84bd4ae082c852 + name: perl-CPAN-DistnameInfo + evr: 0.12-23.el9 + sourcerpm: perl-CPAN-DistnameInfo-0.12-23.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-CPAN-Meta-2.150010-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 210745 + checksum: sha256:ec35026baabe720d7c880f896f84271f0c408c56d3fea6d7c5d22580ac175690 + name: perl-CPAN-Meta + evr: 2.150010-460.el9 + sourcerpm: perl-CPAN-Meta-2.150010-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-CPAN-Meta-Requirements-2.140-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 35205 + checksum: sha256:eca17976f76fd8d31eda995a9ced2d813c1c94b9efafa1a83454fb120be62784 + name: perl-CPAN-Meta-Requirements + evr: 2.140-461.el9 + sourcerpm: perl-CPAN-Meta-Requirements-2.140-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-CPAN-Meta-YAML-0.018-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 29542 + checksum: sha256:b21eb298e56bc6623257cae1434198789e80ab92b818af4e29514a7bbc6f5910 + name: perl-CPAN-Meta-YAML + evr: 0.018-461.el9 + sourcerpm: perl-CPAN-Meta-YAML-0.018-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Carp-1.50-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 32039 + checksum: sha256:c51470a55b1dce42f944bdea06a10469f5a42d55be898a33c2fed3a99843fbb2 + name: perl-Carp + evr: 1.50-460.el9 + sourcerpm: perl-Carp-1.50-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Class-Struct-0.66-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22220 + checksum: sha256:d35ff343bd718fbd8531995a8aedb866c6d37fac6a688fcf9a458017781bf058 + name: perl-Class-Struct + evr: 0.66-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Compress-Bzip2-2.28-5.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 75359 + checksum: sha256:ec290efc1b75d09f29bde0a52758ec46b959f8273a89f8118e062da98862c9d3 + name: perl-Compress-Bzip2 + evr: 2.28-5.el9 + sourcerpm: perl-Compress-Bzip2-2.28-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Compress-Raw-Bzip2-2.101-5.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 39060 + checksum: sha256:bcaa6bb1dc582507d04551f9aac3f7a049f26e48476b1b08184f2647466adde5 + name: perl-Compress-Raw-Bzip2 + evr: 2.101-5.el9 + sourcerpm: perl-Compress-Raw-Bzip2-2.101-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Compress-Raw-Lzma-2.101-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 55819 + checksum: sha256:da1dd21f15039f8c3c6e79f40b201a73d28fc11825c771dd51cc4a14972d4b23 + name: perl-Compress-Raw-Lzma + evr: 2.101-3.el9 + sourcerpm: perl-Compress-Raw-Lzma-2.101-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Compress-Raw-Zlib-2.101-5.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 65949 + checksum: sha256:c638818fb0baf3c36166b1d0a674fa63d58aeacaa9edd91b2519278b112f33b7 + name: perl-Compress-Raw-Zlib + evr: 2.101-5.el9 + sourcerpm: perl-Compress-Raw-Zlib-2.101-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Config-Extensions-0.03-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12128 + checksum: sha256:86695c36cd0bd3516cdb72d9f30ddec6aef47eb48432a76b71d15372e86549a6 + name: perl-Config-Extensions + evr: 0.03-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Config-Perl-V-0.33-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 24943 + checksum: sha256:7ec321ecb6f37b6be09ad182cb66fdeee9f12138f75fc48858bde2177c358d1d + name: perl-Config-Perl-V + evr: 0.33-4.el9 + sourcerpm: perl-Config-Perl-V-0.33-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-DBM_Filter-0.06-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 32009 + checksum: sha256:2ea4092322228a400fe8ad6c19302878e46771cbc1a2d623371c49732ad5e018 + name: perl-DBM_Filter + evr: 0.06-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-DB_File-1.855-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 86215 + checksum: sha256:8c99c19d93e32729c6eefa704e4a3f9dc08b2c693c525cc3717661aefccd18c8 + name: perl-DB_File + evr: 1.855-4.el9 + sourcerpm: perl-DB_File-1.855-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Data-Dumper-2.174-462.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 59910 + checksum: sha256:6cd912e640cbc8785e33dae9cf07561509491a0ec76a81c01d6b7a77ad08668d + name: perl-Data-Dumper + evr: 2.174-462.el9 + sourcerpm: perl-Data-Dumper-2.174-462.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Data-OptList-0.110-17.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 30694 + checksum: sha256:1455a3e90116f504008f8d27db57acb65c3389440dc6e2d605f54bf40b009a10 + name: perl-Data-OptList + evr: 0.110-17.el9 + sourcerpm: perl-Data-OptList-0.110-17.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Data-Section-0.200007-14.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 28030 + checksum: sha256:9fb57b4fbcfea93de114505082261abd97f576cf78e1a205c255d69d8eb6babf + name: perl-Data-Section + evr: 0.200007-14.el9 + sourcerpm: perl-Data-Section-0.200007-14.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Devel-PPPort-3.62-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 220678 + checksum: sha256:5edf31d2993a73056802f4281108e4636f33e5c7d5cb910cdb45996475baee73 + name: perl-Devel-PPPort + evr: 3.62-4.el9 + sourcerpm: perl-Devel-PPPort-3.62-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Devel-Peek-1.28-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 32411 + checksum: sha256:a8618c242704beebdc36e9ef6f9d797822ae16ff6ce195dc8192b68358cdc5e9 + name: perl-Devel-Peek + evr: 1.28-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Devel-SelfStubber-1.06-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14231 + checksum: sha256:703faaef6ca5a65ed4c3cbdb256da9612eed842bd77620a2d527ca8d0fa8a7d2 + name: perl-Devel-SelfStubber + evr: 1.06-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Devel-Size-0.83-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 35096 + checksum: sha256:84738fe6f546dae38e113c340c66f3b8adbd466328f22dc15ec481b793cdf922 + name: perl-Devel-Size + evr: 0.83-10.el9 + sourcerpm: perl-Devel-Size-0.83-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Digest-1.19-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 29409 + checksum: sha256:e0b8633f818467f9e1bf46b9c0012af7bf8a309ac64e903a2a9faf3fae7705f9 + name: perl-Digest + evr: 1.19-4.el9 + sourcerpm: perl-Digest-1.19-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Digest-MD5-2.58-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 40274 + checksum: sha256:2a6b21a144ae1d060e51ee2b6328c5dd1a646f429da160f386c2eb420b1220b4 + name: perl-Digest-MD5 + evr: 2.58-4.el9 + sourcerpm: perl-Digest-MD5-2.58-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Digest-SHA-6.02-461.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 67580 + checksum: sha256:251519573b1785a2102bb235c3a3fea5f6d7b949176969eb0a0fcd69883df4a5 + name: perl-Digest-SHA + evr: 1:6.02-461.el9 + sourcerpm: perl-Digest-SHA-6.02-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Digest-SHA1-2.13-34.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 57553 + checksum: sha256:0f8d777e8c8cab429c3963c477ae16fa7233c568b88e309ee89478ce81b7b3d6 + name: perl-Digest-SHA1 + evr: 2.13-34.el9 + sourcerpm: perl-Digest-SHA1-2.13-34.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-DirHandle-1.05-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12337 + checksum: sha256:2c79a7d1c783c4eb4305e7b15c885c7afc5e2612ab4b1245f4f9ef8dcff4804f + name: perl-DirHandle + evr: 1.05-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Dumpvalue-2.27-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 18343 + checksum: sha256:7659f1dab24e96da4be5624f90a3ac04b383071a96a32e185b196bc527377e1c + name: perl-Dumpvalue + evr: 2.27-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-DynaLoader-1.47-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25958 + checksum: sha256:937d31c9fc324bfa7434e8455cf1828afd46e4502f661566a7286853d8d46bf1 + name: perl-DynaLoader + evr: 1.47-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Encode-3.08-462.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 1802386 + checksum: sha256:d05248697e48928be004ed4c683b04966aa452ae1e2bd81f650c6de108b46956 + name: perl-Encode + evr: 4:3.08-462.el9 + sourcerpm: perl-Encode-3.08-462.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Encode-Locale-1.05-21.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 21500 + checksum: sha256:58afacf30f4a476f4ba6646a6419122d2a729bd59880611b631527502dcdc269 + name: perl-Encode-Locale + evr: 1.05-21.el9 + sourcerpm: perl-Encode-Locale-1.05-21.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Encode-devel-3.08-462.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 45176 + checksum: sha256:8c5dc8e93efddb8ad14fd0a98b1d076cf0b6912b4542a4d4ec6a136f0f1ea797 + name: perl-Encode-devel + evr: 4:3.08-462.el9 + sourcerpm: perl-Encode-3.08-462.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-English-1.11-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13497 + checksum: sha256:04a48f25493933a3ae04eac446efefa1d4c092e323db1561e7653e4f570987da + name: perl-English + evr: 1.11-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Env-1.04-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22160 + checksum: sha256:92fb2287084a3c88a6b2d2bd300d1279251cec59156c1a9a3e0fa8fda6c546b2 + name: perl-Env + evr: 1.04-460.el9 + sourcerpm: perl-Env-1.04-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Errno-1.30-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14862 + checksum: sha256:9c03ad1166d9f8e6d2affb52185f59d625468d160f7c749e3d53a844d5129d4c + name: perl-Errno + evr: 1.30-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Error-0.17029-7.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 47552 + checksum: sha256:17cecf9160050d4709f4817eceba32c637e10d8bc87487a754e8f1764b1e8b6a + name: perl-Error + evr: 1:0.17029-7.el9 + sourcerpm: perl-Error-0.17029-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Exporter-5.74-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 34509 + checksum: sha256:888e14ebd70c2b69150873236b0df7c3a29c9edd488fd8488527c179e798b409 + name: perl-Exporter + evr: 5.74-461.el9 + sourcerpm: perl-Exporter-5.74-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-CBuilder-0.280236-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 54624 + checksum: sha256:1f03cdbebc6f7b1b877e170363ab4906d194aa5edbaee17df724ca7ffc972011 + name: perl-ExtUtils-CBuilder + evr: 1:0.280236-4.el9 + sourcerpm: perl-ExtUtils-CBuilder-0.280236-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-Command-7.60-3.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16489 + checksum: sha256:642338ff95d94e2c6e4b7de47cda7b772d1fbc204b2869925bd0326fcc4b0e26 + name: perl-ExtUtils-Command + evr: 2:7.60-3.el9 + sourcerpm: perl-ExtUtils-MakeMaker-7.60-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-Constant-0.25-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 47285 + checksum: sha256:f10abe9f8d9f26c2ef2f278baf37a98e7a654cf192521d72bb797a3ef2131698 + name: perl-ExtUtils-Constant + evr: 0.25-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-Embed-1.35-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 17684 + checksum: sha256:10fa80d9248c159ad12cce5222d3d1b82953ddfc7c4123ca0b14b5d5340e1421 + name: perl-ExtUtils-Embed + evr: 1.35-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-Install-2.20-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 48441 + checksum: sha256:2533a1d97d45dc79c07cc51409c34f188c042757a2811b04dc16892ae2c7443e + name: perl-ExtUtils-Install + evr: 2.20-4.el9 + sourcerpm: perl-ExtUtils-Install-2.20-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-MM-Utils-7.60-3.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14176 + checksum: sha256:51d7199c10886580e6cbff82546a34f26b2d5b894dcc338e28b1b55938f50ae3 + name: perl-ExtUtils-MM-Utils + evr: 2:7.60-3.el9 + sourcerpm: perl-ExtUtils-MakeMaker-7.60-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-MakeMaker-7.60-3.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 311769 + checksum: sha256:2286e5004cb6436b7ac8dd436c91b4e1d36c18b9385d07a24fc167c930c9dee8 + name: perl-ExtUtils-MakeMaker + evr: 2:7.60-3.el9 + sourcerpm: perl-ExtUtils-MakeMaker-7.60-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-Manifest-1.73-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 37829 + checksum: sha256:f7cf7fd259fb8a6c27537dc98e1ed4923b26c2d8d8fd6b789e166ac104cac5bc + name: perl-ExtUtils-Manifest + evr: 1:1.73-4.el9 + sourcerpm: perl-ExtUtils-Manifest-1.73-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-Miniperl-1.09-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 15171 + checksum: sha256:6b00fb367aea4654a14495802d46daa87d2e51ee203a8b0e207edae507773edc + name: perl-ExtUtils-Miniperl + evr: 1.09-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ExtUtils-ParseXS-3.40-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 194711 + checksum: sha256:bb7e4bcfe24371bbe202a9fa704360a7bbc5d9f4103ec36e6e571da6eb76a186 + name: perl-ExtUtils-ParseXS + evr: 1:3.40-460.el9 + sourcerpm: perl-ExtUtils-ParseXS-3.40-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Fcntl-1.13-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 20397 + checksum: sha256:72587bf21b26885361ec991d153e1b4db26e9b117c1c70b92cc2891cecae4575 + name: perl-Fcntl + evr: 1.13-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-Basename-2.85-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 17211 + checksum: sha256:e39dcc13a24d3b5a7ba11288e63b22a055a8e1061743b8a409858d98ebd794e4 + name: perl-File-Basename + evr: 2.85-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-Compare-1.100.600-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13166 + checksum: sha256:0dd800746b848a84fce73dcef035c4241e6aa90262c821a0ad295a7756ca1a4c + name: perl-File-Compare + evr: 1.100.600-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-Copy-2.34-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 20143 + checksum: sha256:165816db79e88e63c96bdafaf0c3bfee95b6feedb78e40da3a6dcc196a15a186 + name: perl-File-Copy + evr: 2.34-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-DosGlob-1.12-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 19610 + checksum: sha256:d1414f1a77b939a24f8d1ed1a982d6090620232e626e0aab25e40d8c562e9c07 + name: perl-File-DosGlob + evr: 1.12-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-Fetch-1.00-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 33372 + checksum: sha256:8c46735b0f703cd53fbaf915423b63baf98701d81406b30b84e42e53a0efbb6e + name: perl-File-Fetch + evr: 1.00-4.el9 + sourcerpm: perl-File-Fetch-1.00-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-Find-1.37-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25551 + checksum: sha256:002ec6d107fff6949f1a88965fb31b0a4efe6ce663395ab47e0cb939e3920c08 + name: perl-File-Find + evr: 1.37-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-HomeDir-1.006-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 65857 + checksum: sha256:68f539b86abb7ab910286188ad3742f4338330f3246f6da07cb4ca5c83d8e80f + name: perl-File-HomeDir + evr: 1.006-4.el9 + sourcerpm: perl-File-HomeDir-1.006-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-Path-2.18-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 38466 + checksum: sha256:d1df5e509c10365eaa329a0b97e38bc2667874240d3942195eb6ce7a88985a41 + name: perl-File-Path + evr: 2.18-4.el9 + sourcerpm: perl-File-Path-2.18-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-Temp-0.231.100-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 64150 + checksum: sha256:0a81b062391ac6dac3ec28ff1e435001dd798cf1ff19fdb52cfe1e0720d5de03 + name: perl-File-Temp + evr: 1:0.231.100-4.el9 + sourcerpm: perl-File-Temp-0.231.100-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-Which-1.23-10.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 24163 + checksum: sha256:80a41f9f823312dca2c9fed97f6568a88957572277b75920fb76f20a60902e7f + name: perl-File-Which + evr: 1.23-10.el9 + sourcerpm: perl-File-Which-1.23-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-File-stat-1.09-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 17117 + checksum: sha256:b235134c1961e9b57f86bddc02e874607c17c155d2aa5ad78cc3ed9c8fd9c95b + name: perl-File-stat + evr: 1.09-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-FileCache-1.10-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14640 + checksum: sha256:0b0ab9a79395bb7a926ec674b66f42845580903f514c511da156ffd497205f42 + name: perl-FileCache + evr: 1.10-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-FileHandle-2.03-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 15452 + checksum: sha256:c2139abdb9b3335f592aa2835ef6d6fcde1e89232eb3d3c5a15f7cc1d0829f8d + name: perl-FileHandle + evr: 2.03-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Filter-1.60-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 97662 + checksum: sha256:f4fca2ffe54fa291963cfdb816ed4830f75b5be5f70964a73820e4736b242792 + name: perl-Filter + evr: 2:1.60-4.el9 + sourcerpm: perl-Filter-1.60-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Filter-Simple-0.96-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 29899 + checksum: sha256:080a1c4c16acddca179c0e2ab8120fe01e374bb86d0a950923a610e50fabfc00 + name: perl-Filter-Simple + evr: 0.96-460.el9 + sourcerpm: perl-Filter-Simple-0.96-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-FindBin-1.51-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13872 + checksum: sha256:44f9c97a57dafae68f8183d1ca2682a8308b68f1a399ab333a3dd52836bb6b17 + name: perl-FindBin + evr: 1.51-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-GDBM_File-1.18-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22466 + checksum: sha256:c7659709e0958edc4837e42dde09b861c1605020e50b82152ff56dda55141e2d + name: perl-GDBM_File + evr: 1.18-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Getopt-Long-2.52-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 65144 + checksum: sha256:055fe33d2a7a421c1de8902b86a2f246ef6457774239d04b604f2d0ec6a00a14 + name: perl-Getopt-Long + evr: 1:2.52-4.el9 + sourcerpm: perl-Getopt-Long-2.52-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Getopt-Std-1.12-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 15551 + checksum: sha256:49bd8381823d680d17c37f3bebfd97dd92bfbf59e8019f15c7606f41dca02a7d + name: perl-Getopt-Std + evr: 1.12-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Git-2.47.3-1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 38720 + checksum: sha256:d0b4a24233ba8a6eb0966b3b6d8d52dfc5c33577fc8033e693f9aa181f3e2330 + name: perl-Git + evr: 2.47.3-1.el9_6 + sourcerpm: git-2.47.3-1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-HTTP-Tiny-0.076-462.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 58720 + checksum: sha256:696f388a50f5be81596757d68251067449203e1c126ee8c23a7c5a0ad1ac5418 + name: perl-HTTP-Tiny + evr: 0.076-462.el9 + sourcerpm: perl-HTTP-Tiny-0.076-462.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Hash-Util-0.23-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 34584 + checksum: sha256:f587cd7123b8b38acffa99b85b4d27726f0f715749be338fc6e3877b3497480d + name: perl-Hash-Util + evr: 0.23-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Hash-Util-FieldHash-1.20-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 38321 + checksum: sha256:5e7ffdcf78c697892faaa5dae07a84d5a7f012f2e7929e767a2ab4e5fd47b734 + name: perl-Hash-Util-FieldHash + evr: 1.20-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-I18N-Collate-1.02-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14091 + checksum: sha256:82a82eb1e6765c7b4ec245a624f34e73d6a7b2c9c15a90007bcbb64113332793 + name: perl-I18N-Collate + evr: 1.02-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-I18N-LangTags-0.44-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 55212 + checksum: sha256:f0849fe10730cf503bebfbd82e3dfb39d64ef87667ee9a1a073df8fd231878d6 + name: perl-I18N-LangTags + evr: 0.44-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-I18N-Langinfo-0.19-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22566 + checksum: sha256:57c2c2ffc107be695c5ce4f011d54a4e16274c53aaaad09247c954cfe0385061 + name: perl-I18N-Langinfo + evr: 0.19-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IO-1.43-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 90423 + checksum: sha256:e29f5b38c643882a6b9ab9ddbb77bdd476d1a55e3ab649e886e99dd726b3c822 + name: perl-IO + evr: 1.43-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IO-Compress-2.102-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 280708 + checksum: sha256:ce8f2004395442fe663cb9efc56f9af2102c75d746f2ce393e40af8a26ac6871 + name: perl-IO-Compress + evr: 2.102-4.el9 + sourcerpm: perl-IO-Compress-2.102-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IO-Compress-Lzma-2.101-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 84153 + checksum: sha256:bda4c005c09e886ce2273a3f418f0cd92521ed0b8fdcdaca7b9fc0026f2a6c7b + name: perl-IO-Compress-Lzma + evr: 2.101-4.el9 + sourcerpm: perl-IO-Compress-Lzma-2.101-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IO-Socket-IP-0.41-5.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 46457 + checksum: sha256:4c80030ce256198584c4a58171b9dfe3adb4a8d7593110229e40ece76786a32f + name: perl-IO-Socket-IP + evr: 0.41-5.el9 + sourcerpm: perl-IO-Socket-IP-0.41-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IO-Socket-SSL-2.073-2.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 226003 + checksum: sha256:b52d5b6a5081e3c142b2364b3f1ef58f569b39052df045f24363de9bb4f9cfd2 + name: perl-IO-Socket-SSL + evr: 2.073-2.el9 + sourcerpm: perl-IO-Socket-SSL-2.073-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IO-Zlib-1.11-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 21809 + checksum: sha256:87d7b757a570fb53d72b2dd29558c2b4a8ff33196a80ad10f76999325acaec07 + name: perl-IO-Zlib + evr: 1:1.11-4.el9 + sourcerpm: perl-IO-Zlib-1.11-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IPC-Cmd-1.04-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42803 + checksum: sha256:353b04bed7229ce354a4d63ba213c4e18fe739c4732061957946b84853d5b3ce + name: perl-IPC-Cmd + evr: 2:1.04-461.el9 + sourcerpm: perl-IPC-Cmd-1.04-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IPC-Open3-1.21-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22968 + checksum: sha256:7ea36dcf28da3fc7250eb041ba19f99c87543c0870f5da67da614f5ca8d18b92 + name: perl-IPC-Open3 + evr: 1.21-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IPC-SysV-2.09-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 48576 + checksum: sha256:134cb54df211888941ee8666bd96b9026c73202f4e56e6f664319627d2dbfee3 + name: perl-IPC-SysV + evr: 2.09-4.el9 + sourcerpm: perl-IPC-SysV-2.09-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-IPC-System-Simple-1.30-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 44255 + checksum: sha256:35792b1aa241cb17b881b1e44940bc295329a575a2a2d183757ef1d757062465 + name: perl-IPC-System-Simple + evr: 1.30-6.el9 + sourcerpm: perl-IPC-System-Simple-1.30-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Importer-0.026-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42526 + checksum: sha256:1afb9008ad841ba4fc207af8ec814d06bd78e958cd2b03089c7b82c71a311060 + name: perl-Importer + evr: 0.026-4.el9 + sourcerpm: perl-Importer-0.026-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-JSON-PP-4.06-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 70596 + checksum: sha256:17f547d40976904eb59449f0cdec890e34632a28a083fc46157ac1c67e9e3494 + name: perl-JSON-PP + evr: 1:4.06-4.el9 + sourcerpm: perl-JSON-PP-4.06-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Locale-Maketext-1.29-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 101003 + checksum: sha256:97cfef112a414049f85495cbec570b8c63d7260410f72cb2e1480a67fc7e9e68 + name: perl-Locale-Maketext + evr: 1.29-461.el9 + sourcerpm: perl-Locale-Maketext-1.29-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Locale-Maketext-Simple-0.21-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 17604 + checksum: sha256:206fca125c5520e6e0723c6f8ee4c9b56d5bec95c7d71e4b54fdad36ddf20980 + name: perl-Locale-Maketext-Simple + evr: 1:0.21-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-MIME-Base64-3.16-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 35058 + checksum: sha256:3ae8affe13cc15cfaee1c6dd078ada14891dde5dca263927a9b5ed87f241d2c0 + name: perl-MIME-Base64 + evr: 3.16-4.el9 + sourcerpm: perl-MIME-Base64-3.16-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-MIME-Charset-1.012.2-15.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 54488 + checksum: sha256:cf481c2178bc2a55c5b455749f38f4f96ee71f32dcf458c34d4f1bbcb996feca + name: perl-MIME-Charset + evr: 1.012.2-15.el9 + sourcerpm: perl-MIME-Charset-1.012.2-15.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-MRO-Compat-0.13-15.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22804 + checksum: sha256:7921d8fd6d4dacdfb4a286fe4355516f20d660681abb49af9983f7527429e351 + name: perl-MRO-Compat + evr: 0.13-15.el9 + sourcerpm: perl-MRO-Compat-0.13-15.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Math-BigInt-1.9998.18-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 198900 + checksum: sha256:b90555cc3da95e314e931de2348d7c89da7c16023fb9399cdfbbcf9f1aeade7d + name: perl-Math-BigInt + evr: 1:1.9998.18-460.el9 + sourcerpm: perl-Math-BigInt-1.9998.18-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Math-BigInt-FastCalc-0.500.900-460.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 32582 + checksum: sha256:d09dc3590797f1d5a94baa1f24883e2a2f19b80cfa3276f3f8cec41d4ccd4d93 + name: perl-Math-BigInt-FastCalc + evr: 0.500.900-460.el9 + sourcerpm: perl-Math-BigInt-FastCalc-0.500.900-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Math-BigRat-0.2614-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42414 + checksum: sha256:c31888896769451095c352ea97a1c88e2bbbc27d5bdc1e018dc8bae680967fb0 + name: perl-Math-BigRat + evr: 0.2614-460.el9 + sourcerpm: perl-Math-BigRat-0.2614-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Math-Complex-1.59-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 47421 + checksum: sha256:754d5798c9a2bb21714671fdf0236e5937511bf59c473fdef8117c512410e8b5 + name: perl-Math-Complex + evr: 1.59-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Memoize-1.03-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 57798 + checksum: sha256:f668ee6ce94bab8e3a926587a1ab2f4ed3a4490d911c2e7fc1b2fe074a6cfdcc + name: perl-Memoize + evr: 1.03-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Module-Build-0.42.31-9.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 274094 + checksum: sha256:9e33e1a46048d262ebe06f98c6c7b1579cdf92db57b0bb4228d13883c232d82c + name: perl-Module-Build + evr: 2:0.42.31-9.el9 + sourcerpm: perl-Module-Build-0.42.31-9.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Module-CoreList-5.20240609-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 92615 + checksum: sha256:fe85ea513ac696ce4d4bd5565259d89edde346d5a049d0eed153eac988ef73fd + name: perl-Module-CoreList + evr: 1:5.20240609-1.el9 + sourcerpm: perl-Module-CoreList-5.20240609-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Module-CoreList-tools-5.20240609-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 18135 + checksum: sha256:2df9f5a5329e94c19bab88ba530149a86438756c7404787b03745f711adf3368 + name: perl-Module-CoreList-tools + evr: 1:5.20240609-1.el9 + sourcerpm: perl-Module-CoreList-5.20240609-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Module-Load-0.36-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 20052 + checksum: sha256:ada066ac44fd73ec87ea376a6d6715cf77b086354217fdc7a197c909da3bb099 + name: perl-Module-Load + evr: 1:0.36-4.el9 + sourcerpm: perl-Module-Load-0.36-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Module-Load-Conditional-0.74-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25464 + checksum: sha256:58a5364d77607678e4e628f5bdd3d33641e2f6083c2985c1bc5045401ae65a60 + name: perl-Module-Load-Conditional + evr: 0.74-4.el9 + sourcerpm: perl-Module-Load-Conditional-0.74-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Module-Loaded-0.08-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13245 + checksum: sha256:5873834f46d56066cab07a5386daccf8b4db7ccf23344967dcdc31a893907778 + name: perl-Module-Loaded + evr: 1:0.08-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Module-Metadata-1.000037-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 39221 + checksum: sha256:f053b34c911e5f3daf16c0ffc5ff752f47a0d016e1cc1ac51d4425fbe2a1ac15 + name: perl-Module-Metadata + evr: 1.000037-460.el9 + sourcerpm: perl-Module-Metadata-1.000037-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Module-Signature-0.88-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 89282 + checksum: sha256:1a173631124cdb77ffa2cb11ceb8de813f6e4222e5bf9ae657947211480858e6 + name: perl-Module-Signature + evr: 0.88-1.el9 + sourcerpm: perl-Module-Signature-0.88-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Mozilla-CA-20200520-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14781 + checksum: sha256:99030bfb6a1a2ac41e0720841abaa8ba58c26e91640f4058cc6133e227e928a7 + name: perl-Mozilla-CA + evr: 20200520-6.el9 + sourcerpm: perl-Mozilla-CA-20200520-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-NDBM_File-1.15-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22193 + checksum: sha256:1c340352c349ee46ad071436947a1fa1bd353e984fb3d8d3328f2c287c8c5421 + name: perl-NDBM_File + evr: 1.15-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-NEXT-0.67-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 21043 + checksum: sha256:30c7f7f97f369fb9264c0c01f7f12fe1791c99e920aebdf149d71f945f814ec6 + name: perl-NEXT + evr: 0.67-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Net-1.02-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25539 + checksum: sha256:2bb0dceeec12a995caf29411056c2108a6f09b6bbe6d31090114fa4cbec53454 + name: perl-Net + evr: 1.02-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Net-Ping-2.74-5.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 53027 + checksum: sha256:fb74fb2651f62421538bb05992af5251887013a72c4412f5c2421992204c03bc + name: perl-Net-Ping + evr: 2.74-5.el9 + sourcerpm: perl-Net-Ping-2.74-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Net-SSLeay-1.94-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 428188 + checksum: sha256:d8ed17b9700c4acee11a339c9e0814862ad5b20e072c1414021dcb050c7da90b + name: perl-Net-SSLeay + evr: 1.94-1.el9 + sourcerpm: perl-Net-SSLeay-1.94-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ODBM_File-1.16-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22488 + checksum: sha256:f74b5145fd7c8b37e7f9cc77adf5e8f7cac1be2690e32d00a2c7ca7e43222bf0 + name: perl-ODBM_File + evr: 1.16-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Object-HashBase-0.009-7.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 28938 + checksum: sha256:2144d4c29ea4acfc0d872bf09cb4d9dce14a64e60a45633f1a31ed3a2b125ee8 + name: perl-Object-HashBase + evr: 0.009-7.el9 + sourcerpm: perl-Object-HashBase-0.009-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Opcode-1.48-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 36570 + checksum: sha256:974b83adfbc32831b70041353fa13ecda7834c59d186148eeda4a29687810d25 + name: perl-Opcode + evr: 1.48-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-POSIX-1.94-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 98084 + checksum: sha256:434ef22a697f38f3dda351db9ab427e02e7a1220b2dcbc3046087bd9129b742e + name: perl-POSIX + evr: 1.94-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Package-Generator-1.106-23.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 26822 + checksum: sha256:2c9b4699185c30d1da293add16911555e93b7532d77e59aa07e2c9c8d8eafcf3 + name: perl-Package-Generator + evr: 1.106-23.el9 + sourcerpm: perl-Package-Generator-1.106-23.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Params-Check-0.38-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 24764 + checksum: sha256:a6cf1009e3f1dfe50e00421b11d43c413e7e4ee8c6931195256a3cb40e1baf7b + name: perl-Params-Check + evr: 1:0.38-461.el9 + sourcerpm: perl-Params-Check-0.38-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Params-Util-1.102-5.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 38828 + checksum: sha256:a0a38c672e520e1df5aefa9e5212e0fd5754e3e14f6a6e68b53aba5feb330e99 + name: perl-Params-Util + evr: 1.102-5.el9 + sourcerpm: perl-Params-Util-1.102-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-PathTools-3.78-461.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 94564 + checksum: sha256:0647785b169c4bbdc65adf06d28981ce7fd1c9f93aecaa4e53a4515a21ebbf81 + name: perl-PathTools + evr: 3.78-461.el9 + sourcerpm: perl-PathTools-3.78-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Perl-OSType-1.010-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 26284 + checksum: sha256:64f37a98e22fce4ee9520da6db13ab601e21e34ac9d3ae7f85fc7a63761c492b + name: perl-Perl-OSType + evr: 1.010-461.el9 + sourcerpm: perl-Perl-OSType-1.010-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-PerlIO-via-QuotedPrint-0.09-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25566 + checksum: sha256:31d1284cda8a84f78574ae2380474412788de756613bcb11a85d68c94af9ba0b + name: perl-PerlIO-via-QuotedPrint + evr: 0.09-4.el9 + sourcerpm: perl-PerlIO-via-QuotedPrint-0.09-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Pod-Checker-1.74-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 35171 + checksum: sha256:7410aed54bb1c0a18b7b0ec33b6067475383b557defdd295b48b3277229d31a1 + name: perl-Pod-Checker + evr: 4:1.74-4.el9 + sourcerpm: perl-Pod-Checker-1.74-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Pod-Escapes-1.07-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 22564 + checksum: sha256:42fa08cc02a405933395316610a56e2bff58f6f7be16e9a063ec634747199bc0 + name: perl-Pod-Escapes + evr: 1:1.07-460.el9 + sourcerpm: perl-Pod-Escapes-1.07-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Pod-Functions-1.13-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13531 + checksum: sha256:8afc31372f05f71a11054c7d7318301d3d65547abc7eac3ed56d428843edae0c + name: perl-Pod-Functions + evr: 1.13-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Pod-Html-1.25-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 26780 + checksum: sha256:f692dea024e6ced870a5f792db9e76e06d810dfce9846bb59e5b4442b28820e6 + name: perl-Pod-Html + evr: 1.25-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Pod-Perldoc-3.28.01-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 93727 + checksum: sha256:db3285dbe77ddc822d6bb847f857ea7032786cf7996b26d6c01481903b6d26e0 + name: perl-Pod-Perldoc + evr: 3.28.01-461.el9 + sourcerpm: perl-Pod-Perldoc-3.28.01-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Pod-Simple-3.42-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 234403 + checksum: sha256:2752454ce47a46227c6b7b98a5d9a25dcf3a992f27109a726744a66cd93c7b9a + name: perl-Pod-Simple + evr: 1:3.42-4.el9 + sourcerpm: perl-Pod-Simple-3.42-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Pod-Usage-2.01-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 44477 + checksum: sha256:c170870a2d1ff32048d13497fa67c382fe5aaf3d8d21bae639356ac28003dba9 + name: perl-Pod-Usage + evr: 4:2.01-4.el9 + sourcerpm: perl-Pod-Usage-2.01-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Safe-2.41-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25188 + checksum: sha256:ca9095157a26e3ee611c9b9ef6c075086a2381571fccc1a45ade5f8f88c5a78e + name: perl-Safe + evr: 2.41-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Scalar-List-Utils-1.56-462.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 77262 + checksum: sha256:7ce874bde7d9ad15abf70a3b7edbab77548eb2eb8b529c1e48b2426ee7f948f9 + name: perl-Scalar-List-Utils + evr: 4:1.56-462.el9 + sourcerpm: perl-Scalar-List-Utils-1.56-462.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Search-Dict-1.07-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12900 + checksum: sha256:f57497238bbc4edb96b24f88084e5d21f4e3aebab5d33a6db5e79a2ea53ce70d + name: perl-Search-Dict + evr: 1.07-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-SelectSaver-1.02-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 11553 + checksum: sha256:8ec404df551d6cc4750efa34b9897d2288d07a26d49cd3d3d2315584976932b0 + name: perl-SelectSaver + evr: 1.02-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-SelfLoader-1.26-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 21729 + checksum: sha256:18a1b56a5a1097748cc998cb5305f5d77e253a05bae807b418694805fc413c8e + name: perl-SelfLoader + evr: 1.26-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Socket-2.031-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 59776 + checksum: sha256:762751146305f9aea53b74a21495a610e7bdde956fa3246565d265b1128b56a8 + name: perl-Socket + evr: 4:2.031-4.el9 + sourcerpm: perl-Socket-2.031-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Software-License-0.103014-12.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 147494 + checksum: sha256:c225b78b513fc8b90a0b2b773fadcf65dd2defe2a147fca67c52971d2750f437 + name: perl-Software-License + evr: 0.103014-12.el9 + sourcerpm: perl-Software-License-0.103014-12.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Storable-3.21-460.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 100335 + checksum: sha256:0097fdb40a1f83e56d5bf91160c07151b7cdd64f829fc0e328cdf3b43c2b4fa6 + name: perl-Storable + evr: 1:3.21-460.el9 + sourcerpm: perl-Storable-3.21-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Sub-Exporter-0.987-27.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 78523 + checksum: sha256:4e2535cd4d456f91f346e6d690c9a22c4b2a01318f9a5b5f761e1170d815bed1 + name: perl-Sub-Exporter + evr: 0.987-27.el9 + sourcerpm: perl-Sub-Exporter-0.987-27.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Sub-Install-0.928-28.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25233 + checksum: sha256:4ce03d243d1331188c5a2b0e4103dad6b930ba36362cd353f0f3cd0998784e82 + name: perl-Sub-Install + evr: 0.928-28.el9 + sourcerpm: perl-Sub-Install-0.928-28.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Symbol-1.08-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14061 + checksum: sha256:aa9942be4c837c024c6a0a376b13f9563e16ee8b66631ad6c5ff35cd0124728d + name: perl-Symbol + evr: 1.08-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Sys-Hostname-1.23-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16928 + checksum: sha256:f4ebce9dc84861b5d77a3a4a81a2b3a7275eedc0bda60430ad3e4a7fce3791f6 + name: perl-Sys-Hostname + evr: 1.23-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Sys-Syslog-0.36-461.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 52721 + checksum: sha256:b43b2f00357854a3bf0a15e1d41c0494083bc6550b50796b773f4a98ad126734 + name: perl-Sys-Syslog + evr: 0.36-461.el9 + sourcerpm: perl-Sys-Syslog-0.36-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Term-ANSIColor-5.01-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 52228 + checksum: sha256:996148d460395369394e9d4721e9000c5b2fa34ee800390a4a9d885b6db95b23 + name: perl-Term-ANSIColor + evr: 5.01-461.el9 + sourcerpm: perl-Term-ANSIColor-5.01-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Term-Cap-1.17-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25043 + checksum: sha256:015a6d02b9c84bd353680d4bad61f3c8d297c53c3a43325e08e4ac4b48f97f17 + name: perl-Term-Cap + evr: 1.17-460.el9 + sourcerpm: perl-Term-Cap-1.17-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Term-Complete-1.403-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12886 + checksum: sha256:fe5f8688a2a28327a35be1caa35a9d7b8718531120ddfdb10da6f80d6b577059 + name: perl-Term-Complete + evr: 1.403-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Term-ReadLine-1.17-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 19061 + checksum: sha256:506c2fb3304f36ce437696dea9fb8772424a08345c765b25ac7278e429df1dcf + name: perl-Term-ReadLine + evr: 1.17-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Term-Size-Any-0.002-35.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16309 + checksum: sha256:e83c29bb60e3fdac1c7aa5d3cde8a6b237812a14fe8f711bf6e127ed96d929a4 + name: perl-Term-Size-Any + evr: 0.002-35.el9 + sourcerpm: perl-Term-Size-Any-0.002-35.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Term-Size-Perl-0.031-12.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25188 + checksum: sha256:883408c5c76d852a64893986206330ca362ccbbd3535d5ad2fed94ee6e10473e + name: perl-Term-Size-Perl + evr: 0.031-12.el9 + sourcerpm: perl-Term-Size-Perl-0.031-12.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Term-Table-0.015-8.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 40852 + checksum: sha256:3e0c26e1b0e31d17cc133829ad8d6e22c86e532e9b6a3c26f48b7ec447bdfbb4 + name: perl-Term-Table + evr: 0.015-8.el9 + sourcerpm: perl-Term-Table-0.015-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-TermReadKey-2.38-11.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 41023 + checksum: sha256:5ff266e740a93344e1ce2913f4bec0f38cfdf721841e6762d85ac21d716ee9f8 + name: perl-TermReadKey + evr: 2.38-11.el9 + sourcerpm: perl-TermReadKey-2.38-11.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Test-1.31-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 28830 + checksum: sha256:879484e27419a62c5eb942327570be90f246334000d9e3af1e052155b6e08661 + name: perl-Test + evr: 1.31-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Test-Harness-3.42-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 306138 + checksum: sha256:7980ae9e28aed0aadef4f169e8479812a2a6bacf05ee53001f63d021b065fe40 + name: perl-Test-Harness + evr: 1:3.42-461.el9 + sourcerpm: perl-Test-Harness-3.42-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Test-Simple-1.302183-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 645034 + checksum: sha256:04ae40e07d57934e5dc3946fa638023ee76305dac04bed7813ed338b0a4c2ef2 + name: perl-Test-Simple + evr: 3:1.302183-4.el9 + sourcerpm: perl-Test-Simple-1.302183-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Text-Abbrev-1.02-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12026 + checksum: sha256:7671d9b159be320b1725a11b9ba5a9d15b809ec22ba13e0ae5cacf5ed09fdec1 + name: perl-Text-Abbrev + evr: 1.02-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Text-Balanced-2.04-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 51500 + checksum: sha256:67ff60f60b6dc900e840ed51ff3b1cabef9e43aa48cba81ad97ae9423bdca5af + name: perl-Text-Balanced + evr: 2.04-4.el9 + sourcerpm: perl-Text-Balanced-2.04-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Text-Diff-1.45-13.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 45523 + checksum: sha256:5141fc840dc2989b44df904df2cadfdc3b6b9d38a7e4dba2c2db3c14e3dbc060 + name: perl-Text-Diff + evr: 1.45-13.el9 + sourcerpm: perl-Text-Diff-1.45-13.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Text-Glob-0.11-15.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 15921 + checksum: sha256:079d5eb4a606a131eaeecfcbd7f7d39a21c9c49b97bd6b84f7d08986dd11dc59 + name: perl-Text-Glob + evr: 0.11-15.el9 + sourcerpm: perl-Text-Glob-0.11-15.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Text-ParseWords-3.30-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 18680 + checksum: sha256:4d47f3ba0ce454be5d781e968cfe15f01f393e68a47c415f35c0d88358ab4af9 + name: perl-Text-ParseWords + evr: 3.30-460.el9 + sourcerpm: perl-Text-ParseWords-3.30-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Text-Tabs+Wrap-2013.0523-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25935 + checksum: sha256:5ad6ef70bbb4ba8d5cfd6ee0b3dda0ddc8cf0103199959499944019a66f7edcd + name: perl-Text-Tabs+Wrap + evr: 2013.0523-460.el9 + sourcerpm: perl-Text-Tabs+Wrap-2013.0523-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Text-Template-1.59-5.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 64485 + checksum: sha256:3c7350777e9d26fe4c02d52e8c4d4e0643ee32f8abfb9e22fc28f5325702924e + name: perl-Text-Template + evr: 1.59-5.el9 + sourcerpm: perl-Text-Template-1.59-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Thread-3.05-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 18018 + checksum: sha256:0caef6e47205d0035b3f692010e9f7dcd710e7832da77a2a5abbe930440f7e48 + name: perl-Thread + evr: 3.05-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Thread-Queue-3.14-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 24804 + checksum: sha256:88d838d681ad683970eb8566e8936faabffc3495dd1b555f083a1cd00538291a + name: perl-Thread-Queue + evr: 3.14-460.el9 + sourcerpm: perl-Thread-Queue-3.14-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Thread-Semaphore-2.13-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 15604 + checksum: sha256:136b09ee2841a1b6655f0a29759fe353b7f4b12ea3e559bafd39d4c508644925 + name: perl-Thread-Semaphore + evr: 2.13-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Tie-4.6-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 31837 + checksum: sha256:7144466ebb0d8dc2b7af2deac1dddd8caa23b35bcc0d42829c9b242b18f39d6c + name: perl-Tie + evr: 4.6-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Tie-File-1.06-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 43818 + checksum: sha256:f99032921dc45c8a77f91909b5329a95fc4bade37815e2e866c70bf6f39a7c82 + name: perl-Tie-File + evr: 1.06-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Tie-Memoize-1.1-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14038 + checksum: sha256:1f3395cf1a045adfabf0e9b82bc4676f0dd1d76a985afedb3e069e6e9128c677 + name: perl-Tie-Memoize + evr: 1.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Tie-RefHash-1.40-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 26260 + checksum: sha256:5519a86c145d83a1633a127f7b0b6a371e6b2b8a647dabff45c2754388504a44 + name: perl-Tie-RefHash + evr: 1.40-4.el9 + sourcerpm: perl-Tie-RefHash-1.40-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Time-1.03-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 18651 + checksum: sha256:e23d1ba4c2e8d4283e757a7af563a24038b5829ed55c9bc90b4bae8c498ec5d7 + name: perl-Time + evr: 1.03-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Time-HiRes-1.9764-462.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 62596 + checksum: sha256:ce04253e57c1db4fbbc3a3d3e4c0751af9be7c1c7f236be3690a2b304410b172 + name: perl-Time-HiRes + evr: 4:1.9764-462.el9 + sourcerpm: perl-Time-HiRes-1.9764-462.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Time-Local-1.300-7.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 37469 + checksum: sha256:e8e1e692b6e52cdb69515b2ad44b84ca71917bea5f47908cb9ae89b2bbd145a1 + name: perl-Time-Local + evr: 2:1.300-7.el9 + sourcerpm: perl-Time-Local-1.300-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Time-Piece-1.3401-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 41138 + checksum: sha256:493671a8b07c0c5b6c82b6fc25ad041b386b40b613e3e1af9c649d950daa0aca + name: perl-Time-Piece + evr: 1.3401-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-URI-5.09-3.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 128279 + checksum: sha256:1635b7d818e4f70445f7207f13e058c63c5d1f5aa081cfd2583912ae45f8e1bd + name: perl-URI + evr: 5.09-3.el9 + sourcerpm: perl-URI-5.09-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Unicode-Collate-1.29-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 782467 + checksum: sha256:caf9c911bbe43ca8cae0cbda64acef1ad39ca30ca8d5d9bc9fb26979f5ed0b9d + name: perl-Unicode-Collate + evr: 1.29-4.el9 + sourcerpm: perl-Unicode-Collate-1.29-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Unicode-LineBreak-2019.001-11.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 132083 + checksum: sha256:64b6093e21079433c7d14f0b98a86e8bf032cc312abc1207f4415b8acb00f18b + name: perl-Unicode-LineBreak + evr: 2019.001-11.el9 + sourcerpm: perl-Unicode-LineBreak-2019.001-11.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Unicode-Normalize-1.27-461.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 96049 + checksum: sha256:9254f16bef6a0598320196378370728a4881557f5bfeca1ef864a0a25c93f4c0 + name: perl-Unicode-Normalize + evr: 1.27-461.el9 + sourcerpm: perl-Unicode-Normalize-1.27-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-Unicode-UCD-0.75-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 79927 + checksum: sha256:208f347f513df7c59ab77d90b54d3c9ed4cf67e733887783354a2c6ebeaf6409 + name: perl-Unicode-UCD + evr: 0.75-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-User-pwent-1.03-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 20597 + checksum: sha256:f131ac194a35b3b17f5ff6961e9bb9eb031fd5c7d0055e05a438c11b53931263 + name: perl-User-pwent + evr: 1.03-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-autodie-2.34-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 103286 + checksum: sha256:8c4a7c8fd5074801946cce0b0b2f47337036e7f64e4cb9c833d9cf1de1f14edc + name: perl-autodie + evr: 2.34-4.el9 + sourcerpm: perl-autodie-2.34-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-autouse-1.11-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13668 + checksum: sha256:c2502f538edef3d9b9ad20cdc8c0f8e971ac651df6c07f8555aa315b602c085a + name: perl-autouse + evr: 1.11-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-base-2.27-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16220 + checksum: sha256:0be44f055107893b011ed0e88f39ff202ba451db8a94351ad4472d350c780d0d + name: perl-base + evr: 2.27-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-bignum-0.51-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 48635 + checksum: sha256:a25963adbb78901e2581a041252bfc96f55e534403e4af513d8728c62f0b4800 + name: perl-bignum + evr: 0.51-460.el9 + sourcerpm: perl-bignum-0.51-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-blib-1.07-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12267 + checksum: sha256:50560de5f252c718728c45cb7af3742252581416e0acb9cfacd686dad58c0028 + name: perl-blib + evr: 1.07-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-constant-1.33-461.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25865 + checksum: sha256:8ab94e13cab4e7eee081c7618ea7738b072d8093631d97b8b1f83bff893cf892 + name: perl-constant + evr: 1.33-461.el9 + sourcerpm: perl-constant-1.33-461.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-debugger-1.56-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 136515 + checksum: sha256:0b96f38c73512a61ce84171578bc9fcc5a957ff1fb267749f3af18bc7d1ce1bd + name: perl-debugger + evr: 1.56-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-deprecate-0.04-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14490 + checksum: sha256:033aae2f09a7f78be08ae590f95cbce8025e5d5574cdab2bc77b554ad6e81575 + name: perl-deprecate + evr: 0.04-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-devel-5.32.1-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 692014 + checksum: sha256:8e5928c563c256c62ea09b78b6ac2c90e9e37013e09af1fe120acac64fd84d23 + name: perl-devel + evr: 4:5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-diagnostics-1.37-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 215534 + checksum: sha256:19c65175b0df9d6142bf08d6566b8f10c331735c8b95690adbc300b670a692c4 + name: perl-diagnostics + evr: 1.37-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-doc-5.32.1-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 4798228 + checksum: sha256:d9eb81a356338df906db80c853c092a1fb0de745726e82db44fb343d267b4091 + name: perl-doc + evr: 5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-encoding-3.00-462.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 66000 + checksum: sha256:7c5ea804da141c742d05b6d6627481f05310a37e396a02af07e52877afcb534c + name: perl-encoding + evr: 4:3.00-462.el9 + sourcerpm: perl-Encode-3.08-462.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-encoding-warnings-0.13-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16539 + checksum: sha256:897e244bb8f8800a3ed23d669df746b0bb3672cd6929b06e04e5da63b04a5aa3 + name: perl-encoding-warnings + evr: 0.13-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-experimental-0.022-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 24376 + checksum: sha256:ae48d202863aba2573c70d803a9931de4e3c4b0d3e4f2df561bcc1bf78dc7920 + name: perl-experimental + evr: 0.022-6.el9 + sourcerpm: perl-experimental-0.022-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-fields-2.27-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16096 + checksum: sha256:c2f5157686257ca7b67e566b4d7e86116c6c8b9f590023adf84fde78d35d3ea9 + name: perl-fields + evr: 2.27-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-filetest-1.03-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14556 + checksum: sha256:4556ac1a93588b9b3e3722867ef73680028e53b3aae4af87165a1a70c79530b8 + name: perl-filetest + evr: 1.03-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-if-0.60.800-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13876 + checksum: sha256:ae3ce80bee55e1057ed004ec03a0e826b0cdd90ace4c0784ab2f569a2d81d40c + name: perl-if + evr: 0.60.800-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-inc-latest-0.500-20.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 27665 + checksum: sha256:22c41d7117656dfff8d52bc8e557e6f8d11d2b5ed377173f56037a2ac8bc9139 + name: perl-inc-latest + evr: 2:0.500-20.el9 + sourcerpm: perl-inc-latest-0.500-20.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-interpreter-5.32.1-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 72173 + checksum: sha256:92959263a20ad89d33bc92826cdfed32f507652ff08d0c18b50b604fa5f9f594 + name: perl-interpreter + evr: 4:5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-less-0.03-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13074 + checksum: sha256:8c69534a3a191e28647b5c201dce163f2fa30f0813d54ace2345bbab830d7a9b + name: perl-less + evr: 0.03-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-lib-0.65-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14847 + checksum: sha256:badc59793f32fa6e98fd705101af0b879720db5e0811b46755640d3d64165715 + name: perl-lib + evr: 0.65-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-libnet-3.13-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 137289 + checksum: sha256:79156f91a2ee21fb96f10e331047c55ff913e36f9a13ff89d0a479f0fc4dcb98 + name: perl-libnet + evr: 3.13-4.el9 + sourcerpm: perl-libnet-3.13-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-libnetcfg-5.32.1-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16266 + checksum: sha256:fcb262ee807d950b902ca12744cb2645c52de5aae0d9380a7ff4dd5574aec7fd + name: perl-libnetcfg + evr: 4:5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-libs-5.32.1-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 2303689 + checksum: sha256:aa0e9b31c82b50de7ace1b7e4b85a26ac9572cc77b8ded88866c06915748ccd7 + name: perl-libs + evr: 4:5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-local-lib-2.000024-13.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 73510 + checksum: sha256:c8f58afb9e8eb07bc57f92c384753ee4f4fec10fa7ec7c091ad9f15110a10026 + name: perl-local-lib + evr: 2.000024-13.el9 + sourcerpm: perl-local-lib-2.000024-13.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-locale-1.09-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13543 + checksum: sha256:6b81563677505210a973fd4416f5991bf729c03f3082ac139460290643daef33 + name: perl-locale + evr: 1.09-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-macros-5.32.1-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 10568 + checksum: sha256:e499fae237cea4dcec9480576b64c69afe91c09875a8dfcf9b4daebdbeb9f197 + name: perl-macros + evr: 4:5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-meta-notation-5.32.1-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9577 + checksum: sha256:0b7fb715954c7f67719f00bc7323d4a12453aab37acadba5106758f864c8535a + name: perl-meta-notation + evr: 5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-mro-1.23-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 28410 + checksum: sha256:4ed671f36290bc6c15f37d550f67ce33ced1c27a3e2ea24f0a37038d45d1805a + name: perl-mro + evr: 1.23-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-open-1.12-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16407 + checksum: sha256:f3e192485674a0681320f38c4163460ce0bf4855b7e825f75c371f3b3a7c778f + name: perl-open + evr: 1.12-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-overload-1.31-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 46157 + checksum: sha256:f172df7417780cb61b879effe60ce6b7b4399773c46cb9896a5edf2bfba6dbda + name: perl-overload + evr: 1.31-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-overloading-0.02-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12747 + checksum: sha256:4aae487e802df60e1e2d778b264592290ad492078877784771299561d45dfd47 + name: perl-overloading + evr: 0.02-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-parent-0.238-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 16286 + checksum: sha256:a9b2ccc25a5ed5cc024935ef573772e203ed363f67dd5acc0d2ad5907498c463 + name: perl-parent + evr: 1:0.238-460.el9 + sourcerpm: perl-parent-0.238-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-perlfaq-5.20210520-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 388755 + checksum: sha256:e5588c37edf2bb614ffb7526deb663bc406effb86492637b4c906c5fe06f0b98 + name: perl-perlfaq + evr: 5.20210520-1.el9 + sourcerpm: perl-perlfaq-5.20210520-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-ph-5.32.1-481.1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 45698 + checksum: sha256:6f29f5eff09005371dda94e8ba980af8e8db07446d2a039f4aba2dc6856cb1f4 + name: perl-ph + evr: 5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-podlators-4.14-460.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 121317 + checksum: sha256:0401f715522a14b53956bccb60954025ad18a73802f7144ab0160d8504951a98 + name: perl-podlators + evr: 1:4.14-460.el9 + sourcerpm: perl-podlators-4.14-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-sigtrap-1.09-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 15624 + checksum: sha256:5b7215d5421f381137e867678492848574c2ceb58e56d47d7833d182923e92c6 + name: perl-sigtrap + evr: 1.09-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-sort-2.04-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 13408 + checksum: sha256:554155e6ff38d091ea388b1f19fc0b0950522b4c4ffe87cfee3676c4f03c046d + name: perl-sort + evr: 2.04-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-srpm-macros-1-41.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9639 + checksum: sha256:fa6a45cf7cb8b6f8a28ce85be31483eacc7b0b4c01d598123ec649867b67c8f4 + name: perl-srpm-macros + evr: 1-41.el9 + sourcerpm: perl-srpm-macros-1-41.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-subs-1.03-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 11525 + checksum: sha256:0a7ef4a9a174ab981949d27a4acdc8cec87fd3513e9e607f5869851dc1c74deb + name: perl-subs + evr: 1.03-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-threads-2.25-460.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 62702 + checksum: sha256:22546db61ccd2c69020c7ec3b04449b3589e1220dd3a02ad38e6d6c773ae126f + name: perl-threads + evr: 1:2.25-460.el9 + sourcerpm: perl-threads-2.25-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-threads-shared-1.61-460.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 48850 + checksum: sha256:3ee2cd37764da3452fbaa301f9bdf3ae1a2dba47b77cafb0ae5d31a10196b971 + name: perl-threads-shared + evr: 1.61-460.el9 + sourcerpm: perl-threads-shared-1.61-460.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-utils-5.32.1-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 55943 + checksum: sha256:5c21992a23a63139c0c73ce0b9866cd9064ab2efc8d9414bb45edc6c72996162 + name: perl-utils + evr: 5.32.1-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-vars-1.05-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 12885 + checksum: sha256:5d3c58094c0158b6193d7f4ba7a4bb7ae06a78738393b31255da8b7aadb10e38 + name: perl-vars + evr: 1.05-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-version-0.99.28-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 68996 + checksum: sha256:8804f201f3e2fb54f75735683c65a571f17b6ea8715e84eb813907ec5027fcc5 + name: perl-version + evr: 7:0.99.28-4.el9 + sourcerpm: perl-version-0.99.28-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/perl-vmsish-1.04-481.1.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14031 + checksum: sha256:af9db38df1c1843277ebd8c6bb8d766017be043eea28246252788b055f19764d + name: perl-vmsish + evr: 1.04-481.1.el9_6 + sourcerpm: perl-5.32.1-481.1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/pixman-0.40.0-6.el9_3.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 277483 + checksum: sha256:40581f27200096a57adc25a51d3d373a81f55d3abc0529cbe057c2c458318145 + name: pixman + evr: 0.40.0-6.el9_3 + sourcerpm: pixman-0.40.0-6.el9_3.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/pyproject-srpm-macros-1.16.2-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 14828 + checksum: sha256:1bec3715412a73295a9cd2cdbc147ebee0fe23b50f4146bddc08a5761ed3928d + name: pyproject-srpm-macros + evr: 1.16.2-1.el9 + sourcerpm: pyproject-rpm-macros-1.16.2-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python-srpm-macros-3.9-54.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 18705 + checksum: sha256:cc14196e07f9c6383f5bdf2c1171e7d41256326324c4a03c98d62d81413f3fb3 + name: python-srpm-macros + evr: 3.9-54.el9 + sourcerpm: python-rpm-macros-3.9-54.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python-unversioned-command-3.9.21-2.el9_6.2.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9102 + checksum: sha256:7aec11632e430e2d0ee4a4a4e60336ce36ebdd023e6a5645175654e3e339e688 + name: python-unversioned-command + evr: 3.9.21-2.el9_6.2 + sourcerpm: python3.9-3.9.21-2.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3-pip-21.3.1-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 2133958 + checksum: sha256:2ff41d5bbfb5bf09378a499b56d9854e9389e3a8648897426d144f4b385f8730 + name: python3-pip + evr: 21.3.1-1.el9 + sourcerpm: python-pip-21.3.1-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-3.11.11-2.el9_6.2.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 25148 + checksum: sha256:01129c3d24e06a4fadb253af466f145f1e82abb524e82670eb8ac155abc479a4 + name: python3.11 + evr: 3.11.11-2.el9_6.2 + sourcerpm: python3.11-3.11.11-2.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-charset-normalizer-2.1.0-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 108311 + checksum: sha256:ef4b682449ac49a93d7d6c031fcb26e7d007b55912399c2eb7befed7381d1a50 + name: python3.11-charset-normalizer + evr: 2.1.0-1.el9 + sourcerpm: python3.11-charset-normalizer-2.1.0-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-devel-3.11.11-2.el9_6.2.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 282615 + checksum: sha256:3de45385b33e14a35d16f305ca288b3a2fdcc3f1654c07870f04e4884d68c213 + name: python3.11-devel + evr: 3.11.11-2.el9_6.2 + sourcerpm: python3.11-3.11.11-2.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-idna-3.4-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 115495 + checksum: sha256:9e6ca76b36ca3c0dedd3c10c1eb0c037e5d585d4ee546b7abeab8c59251a148c + name: python3.11-idna + evr: 3.4-1.el9 + sourcerpm: python3.11-idna-3.4-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-libs-3.11.11-2.el9_6.2.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 10702100 + checksum: sha256:d3c49fc65788e11ee5375511d726e3c6ed6cf4be7206c57c0b7e73a5278a91cb + name: python3.11-libs + evr: 3.11.11-2.el9_6.2 + sourcerpm: python3.11-3.11.11-2.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-pip-22.3.1-5.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 3358530 + checksum: sha256:c5c12f2941e65ea36b645ea215a62883fcfafc45931f0370153fecf752bde885 + name: python3.11-pip + evr: 22.3.1-5.el9 + sourcerpm: python3.11-pip-22.3.1-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-pip-wheel-22.3.1-5.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 1490893 + checksum: sha256:c7c531cbc553b7cbec0a3a61ed396aede78ec663ff77a118a60829b9505383ab + name: python3.11-pip-wheel + evr: 22.3.1-5.el9 + sourcerpm: python3.11-pip-22.3.1-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-pysocks-1.7.1-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 44030 + checksum: sha256:1d1500bdc2ff2aa52235e404054ebcbef8db53e09ba89715907fa814cf6d29a8 + name: python3.11-pysocks + evr: 1.7.1-1.el9 + sourcerpm: python3.11-pysocks-1.7.1-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-requests-2.28.1-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 163237 + checksum: sha256:d150df800a960a2f9a722a857a80bcab7f6345eed8d52514c99c4252c181010a + name: python3.11-requests + evr: 2.28.1-1.el9 + sourcerpm: python3.11-requests-2.28.1-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-setuptools-65.5.1-4.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 1794566 + checksum: sha256:15b72546d2964e02c54f0f9ed45dec5e7a5c179899668e020f920357705f7455 + name: python3.11-setuptools + evr: 65.5.1-4.el9_6 + sourcerpm: python3.11-setuptools-65.5.1-4.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-setuptools-wheel-65.5.1-4.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 729097 + checksum: sha256:0887cbc9f8c1d8f73d6292d6ae4ac21db8da6fade83279fc40cd35f884cfcb70 + name: python3.11-setuptools-wheel + evr: 65.5.1-4.el9_6 + sourcerpm: python3.11-setuptools-65.5.1-4.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-six-1.16.0-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 47945 + checksum: sha256:74127dc01665a183d17e62293b6b3b2f27d4edd86e2d9f47ea03ed4f9e196361 + name: python3.11-six + evr: 1.16.0-1.el9 + sourcerpm: python3.11-six-1.16.0-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/p/python3.11-urllib3-1.26.12-5.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 269978 + checksum: sha256:67ed166e90a19da81638118cad2b8801388105ca0831d8f206940c70aa1cfdc4 + name: python3.11-urllib3 + evr: 1.26.12-5.el9 + sourcerpm: python3.11-urllib3-1.26.12-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/q/qt5-srpm-macros-5.15.9-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9344 + checksum: sha256:1dbb5db859d110aa275cbacd07e2576dcbe321ab0803f04d85dc3fa1a203ef10 + name: qt5-srpm-macros + evr: 5.15.9-1.el9 + sourcerpm: qt5-5.15.9-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/r/redhat-rpm-config-209-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 77658 + checksum: sha256:a9e214f1085628ce546a11eebab20e0fc769bf15208bb12b947efa109b1d4dd7 + name: redhat-rpm-config + evr: 209-1.el9 + sourcerpm: redhat-rpm-config-209-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/r/rpm-plugin-systemd-inhibit-4.16.1.3-37.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 18084 + checksum: sha256:bad0137ad0f9dca0eb001feacf881a0e1613a47a69f018217584eb05e159b106 + name: rpm-plugin-systemd-inhibit + evr: 4.16.1.3-37.el9 + sourcerpm: rpm-4.16.1.3-37.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/r/rust-srpm-macros-17-4.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 11243 + checksum: sha256:8e91d6d5122b9effe0e3539ef0d55e57c4b3eff68544e46a413129cb961d5941 + name: rust-srpm-macros + evr: 17-4.el9 + sourcerpm: rust-srpm-macros-17-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/s/scl-utils-2.0.3-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42223 + checksum: sha256:164d245bec95c7dcbba881fd88ee567bc6d5859329c91ae05a6ad5429700bdbc + name: scl-utils + evr: 1:2.0.3-4.el9 + sourcerpm: scl-utils-2.0.3-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/s/skopeo-1.18.1-2.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 9530108 + checksum: sha256:039405094c2d9a353471b7c14a4cd1acde857472f2692b33ca486386a56f8cdc + name: skopeo + evr: 2:1.18.1-2.el9_6 + sourcerpm: skopeo-1.18.1-2.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/s/slirp4netns-1.3.2-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 50387 + checksum: sha256:25a2a6c5cee50c6f4693ee66c782e9644f4ba1fe410c795391afcc07546496e7 + name: slirp4netns + evr: 1.3.2-1.el9 + sourcerpm: slirp4netns-1.3.2-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/s/sombok-2.4.0-16.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 52190 + checksum: sha256:830082e28c0d9a2a1e055f0b01e460e5aa54336f57c2a6885a1f4c748f55fe11 + name: sombok + evr: 2.4.0-16.el9 + sourcerpm: sombok-2.4.0-16.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/s/systemtap-sdt-devel-5.2-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 79141 + checksum: sha256:e02a565f7999c72dfb631838b52893942f63076997f276ccd4fefb6c4ccd46e0 + name: systemtap-sdt-devel + evr: 5.2-2.el9 + sourcerpm: systemtap-5.2-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/x/xkeyboard-config-2.33-2.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 886685 + checksum: sha256:8575107a4292036df4c33b34b98b459897d2f4b0fdf8385e342eced93102497c + name: xkeyboard-config + evr: 2.33-2.el9 + sourcerpm: xkeyboard-config-2.33-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/x/xml-common-0.6.3-58.el9.noarch.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 37016 + checksum: sha256:2278e3b1ce7ddd4ff394064e5dc5404ac2799e51f9441a056b334d518bb51af4 + name: xml-common + evr: 0.6.3-58.el9 + sourcerpm: sgml-common-0.6.3-58.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/y/yajl-2.1.0-25.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 42487 + checksum: sha256:f7503f34d5095303db5c57c70c5edb890dab7d0bba5920f3dcc44d7835449555 + name: yajl + evr: 2.1.0-25.el9 + sourcerpm: yajl-2.1.0-25.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/os/Packages/z/zlib-devel-1.2.11-40.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-appstream-rpms + size: 48017 + checksum: sha256:9775022716a2b6dd51d151a40aa4a6bcb466edeb01b747f48072703e509be097 + name: zlib-devel + evr: 1.2.11-40.el9 + sourcerpm: zlib-1.2.11-40.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/a/acl-2.3.1-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 77226 + checksum: sha256:150d7232faa90f84a09268f8998ee32670eef59cba98612aeb996ab75c4dfcc4 + name: acl + evr: 2.3.1-4.el9 + sourcerpm: acl-2.3.1-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/a/attr-2.5.1-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 66700 + checksum: sha256:49f7baeb53e07a4b9b5739e36932f17f014abb765b3fa6c0c0f8af6a8ebf4d9b + name: attr + evr: 2.5.1-3.el9 + sourcerpm: attr-2.5.1-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/a/avahi-libs-0.8-22.el9_6.1.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 68928 + checksum: sha256:10ae9d5f9015c58dbc2a42b4af47497c3e1436753700898d56b8fb41b4a90ee3 + name: avahi-libs + evr: 0.8-22.el9_6.1 + sourcerpm: avahi-0.8-22.el9_6.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/b/binutils-2.35.2-63.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 4818636 + checksum: sha256:4eb918b63dee7daf32117df2e3fcb02ad4ba3d96cb25677cf55315deceb7e22a + name: binutils + evr: 2.35.2-63.el9 + sourcerpm: binutils-2.35.2-63.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/b/binutils-gold-2.35.2-63.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 753176 + checksum: sha256:339d9bb2dc0e41c4756f1a4f82e82f6654818b72de74f1f0377c76277617352b + name: binutils-gold + evr: 2.35.2-63.el9 + sourcerpm: binutils-2.35.2-63.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/c/cracklib-2.9.6-27.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 100903 + checksum: sha256:8551b711718596fbfef6622bbf32f785864959af9d06a76da2545ec9f3a126e7 + name: cracklib + evr: 2.9.6-27.el9 + sourcerpm: cracklib-2.9.6-27.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/c/cracklib-dicts-2.9.6-27.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 3821230 + checksum: sha256:ab4356c86bdc996dc9e55703a7ae936e3e46aec6ebf6d6f008e126ff06e83df2 + name: cracklib-dicts + evr: 2.9.6-27.el9 + sourcerpm: cracklib-2.9.6-27.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/c/crypto-policies-scripts-20250128-1.git5269e22.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 103762 + checksum: sha256:a5dcaf7174b134ab01a3b586cf883a31c1eb86cb252501e46a2ce5dc2f549fc2 + name: crypto-policies-scripts + evr: 20250128-1.git5269e22.el9 + sourcerpm: crypto-policies-20250128-1.git5269e22.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/c/cups-libs-2.3.3op2-33.el9_6.1.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 266700 + checksum: sha256:d430a82961d9d79cc3325cd662cc91d64d4479965462431b4244cb782c3647f4 + name: cups-libs + evr: 1:2.3.3op2-33.el9_6.1 + sourcerpm: cups-2.3.3op2-33.el9_6.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/d/dbus-1.12.20-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 8073 + checksum: sha256:96b1daa4de0a635ab760a8431fb005022bb7cb48d2d1d3ec9a8adb1798c0e10e + name: dbus + evr: 1:1.12.20-8.el9 + sourcerpm: dbus-1.12.20-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/d/dbus-broker-28-7.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 179634 + checksum: sha256:de9869c08df7f6952787d0335b9bf1a09b328bea920556a59af07c8e085dd3cb + name: dbus-broker + evr: 28-7.el9 + sourcerpm: dbus-broker-28-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/d/dbus-common-1.12.20-8.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 18551 + checksum: sha256:298f1cada3cbcef6713098b9925694a0e30e8566f7a5bdbd72384520cf6c8360 + name: dbus-common + evr: 1:1.12.20-8.el9 + sourcerpm: dbus-1.12.20-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/d/dbus-libs-1.12.20-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 157201 + checksum: sha256:10e1bc01835d6b2185782f7202abb494af81158ec35755ddf3eb98c022f07e08 + name: dbus-libs + evr: 1:1.12.20-8.el9 + sourcerpm: dbus-1.12.20-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/d/diffutils-3.7-12.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 411559 + checksum: sha256:2d4c4fdfc10215af3c957c24995b79a26e27e6d76de4ed1f5198d25bf7ef9671 + name: diffutils + evr: 3.7-12.el9 + sourcerpm: diffutils-3.7-12.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/d/dmidecode-3.6-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 108516 + checksum: sha256:4b594f260608ed2d7c81097a0af147a1805c30a8698f9ed6363293ac8eabce94 + name: dmidecode + evr: 1:3.6-1.el9 + sourcerpm: dmidecode-3.6-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/d/dnf-4.14.0-25.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 494210 + checksum: sha256:b13e385796f68e45acf995bf9faa38bbf23f87b56135245244b711b89c58b485 + name: dnf + evr: 4.14.0-25.el9 + sourcerpm: dnf-4.14.0-25.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/e/elfutils-debuginfod-client-0.192-6.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 47122 + checksum: sha256:0fcab0370abc33e8df4686dad91ff390dd6dd3437b601c3911efd83ec7603168 + name: elfutils-debuginfod-client + evr: 0.192-6.el9_6 + sourcerpm: elfutils-0.192-6.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/e/elfutils-default-yama-scope-0.192-6.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 9980 + checksum: sha256:847f0cbedaef67673aadcd1bc5b8f6b9b8cb5e0cb6896c6586abe89829469c99 + name: elfutils-default-yama-scope + evr: 0.192-6.el9_6 + sourcerpm: elfutils-0.192-6.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/e/elfutils-libelf-0.192-6.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 212613 + checksum: sha256:9c9e2bc6ea19cda24a73f95ef9f439d61fd4480ae1889ac7e0730ee67432fd64 + name: elfutils-libelf + evr: 0.192-6.el9_6 + sourcerpm: elfutils-0.192-6.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/e/elfutils-libs-0.192-6.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 269588 + checksum: sha256:8071e26f2c44c4941dec0ed2296ec79485f9276f4abaa9464da2d1e625ddd31e + name: elfutils-libs + evr: 0.192-6.el9_6 + sourcerpm: elfutils-0.192-6.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/e/environment-modules-5.3.0-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 605644 + checksum: sha256:0bf2c48686d2c9f4d0f4d2cbe80a64f7d3c26559dd3cf6ca798a6615407a58ae + name: environment-modules + evr: 5.3.0-1.el9 + sourcerpm: environment-modules-5.3.0-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/e/expat-2.5.0-5.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 121835 + checksum: sha256:63522da84934e944305c9e206894031988ab9e561bba2e6c131d76093d1a0211 + name: expat + evr: 2.5.0-5.el9_6 + sourcerpm: expat-2.5.0-5.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/f/file-5.39-16.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 53222 + checksum: sha256:64f29bc71f9c26e6460abaff21d8e43738077cde4fbd6d1b96825a50ba0abd74 + name: file + evr: 5.39-16.el9 + sourcerpm: file-5.39-16.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/f/freetype-2.10.4-10.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 398342 + checksum: sha256:712719db8e6aecc252ce30ac0418226f0ea7828d596084fe7da88937df9b72a1 + name: freetype + evr: 2.10.4-10.el9_5 + sourcerpm: freetype-2.10.4-10.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/f/fuse-common-3.10.2-9.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 8750 + checksum: sha256:548265cbee787fa659bc79c07e15a12007f39eb70e905bf660ec488f0bb8820f + name: fuse-common + evr: 3.10.2-9.el9 + sourcerpm: fuse3-3.10.2-9.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/g/gettext-0.21-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 1193150 + checksum: sha256:febf6aec8699ca352aba5a7a249ed0cb011b68c5bab17f6178f09b1035974dde + name: gettext + evr: 0.21-8.el9 + sourcerpm: gettext-0.21-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/g/gettext-libs-0.21-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 313328 + checksum: sha256:b319325e941e03e3e7381161889ab39473398194786a52fc1653d025211b6e1a + name: gettext-libs + evr: 0.21-8.el9 + sourcerpm: gettext-0.21-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/g/glibc-gconv-extra-2.34-168.el9_6.23.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 1753998 + checksum: sha256:065f2e745d62034fa3f72cb138ba599338c491921d5c0a9ad4900725721f0507 + name: glibc-gconv-extra + evr: 2.34-168.el9_6.23 + sourcerpm: glibc-2.34-168.el9_6.23.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/g/glibc-langpack-en-2.34-168.el9_6.23.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 672229 + checksum: sha256:1c8fd029085d95ef17fb60675ec638024078bede2fb28656835131c7f42c214d + name: glibc-langpack-en + evr: 2.34-168.el9_6.23 + sourcerpm: glibc-2.34-168.el9_6.23.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/g/graphite2-1.3.14-9.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 100358 + checksum: sha256:15c9ec729831ec8f511cb8595d5bbe7cf5b178dde909e48daed72652d416d54c + name: graphite2 + evr: 1.3.14-9.el9 + sourcerpm: graphite2-1.3.14-9.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/g/groff-base-1.22.4-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 1133828 + checksum: sha256:4d8ff13569b3b231b3fb847e9e22615c6e08215d1f2c0c78eac2e345b9efd394 + name: groff-base + evr: 1.22.4-10.el9 + sourcerpm: groff-1.22.4-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/g/gzip-1.12-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 171206 + checksum: sha256:c8b3e0414d55b1eedb0185a564ac6cb2368bee2fd5f995447d045f6a714488ac + name: gzip + evr: 1.12-1.el9 + sourcerpm: gzip-1.12-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/h/harfbuzz-2.7.4-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 643610 + checksum: sha256:ccbdbf1ccae7f9c1315c3a33c103c6d27916e6fdc62756083fe3207474c51537 + name: harfbuzz + evr: 2.7.4-10.el9 + sourcerpm: harfbuzz-2.7.4-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/h/hwdata-0.348-9.18.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 1724460 + checksum: sha256:3f50d2d645126aab5407531cdfa813544c85c44d312bc19dcc3378460b9eb03d + name: hwdata + evr: 0.348-9.18.el9 + sourcerpm: hwdata-0.348-9.18.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/i/ima-evm-utils-1.5-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 75273 + checksum: sha256:656c8fa4da9792b3f8dd4515ad4dbb2a0f81f08125371bedc1c1ae55182372d5 + name: ima-evm-utils + evr: 1.5-3.el9 + sourcerpm: ima-evm-utils-1.5-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/i/iproute-6.11.0-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 855648 + checksum: sha256:8fdbd5d311c7002f6553c31406f642ed136e94008b49376d581286646648d11d + name: iproute + evr: 6.11.0-1.el9 + sourcerpm: iproute-6.11.0-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/k/keyutils-1.6.3-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 79682 + checksum: sha256:756fb606dfbf6c6f92fcd3316ba902b5e09232102cb6371d9bccd983b8d4bbdf + name: keyutils + evr: 1.6.3-1.el9 + sourcerpm: keyutils-1.6.3-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/k/kmod-28-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 132888 + checksum: sha256:e9ccad17d4c6c30524ec5c2aab8d8d351f2776ab564baccdbd2df9b54e28baea + name: kmod + evr: 28-10.el9 + sourcerpm: kmod-28-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/k/kmod-libs-28-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 66607 + checksum: sha256:9ae0b89812908ee50ec654ba35f74dc478057e8981afd4a5cc8d2befd987b342 + name: kmod-libs + evr: 28-10.el9 + sourcerpm: kmod-28-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/less-590-5.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 170758 + checksum: sha256:a726061c966a134a5e5b42b60e4162ee85a2cef8843b6fd28e08264ceebb54f4 + name: less + evr: 590-5.el9 + sourcerpm: less-590-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libbpf-1.5.0-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 191098 + checksum: sha256:488a913a5f10debb4fb27756f59da75c61c6fefac403ea62d50b8071625d5cf3 + name: libbpf + evr: 2:1.5.0-1.el9 + sourcerpm: libbpf-1.5.0-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libcbor-0.7.0-5.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 60575 + checksum: sha256:588e8736af3376abfb3cdf372c10baef02c40d916a55958f3bee9767f9ad8526 + name: libcbor + evr: 0.7.0-5.el9 + sourcerpm: libcbor-0.7.0-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libcomps-0.1.18-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 81851 + checksum: sha256:89c2c46e83f100481ecc279ee886ab0f38a4b4668adff7d779089037f4b19d4f + name: libcomps + evr: 0.1.18-1.el9 + sourcerpm: libcomps-0.1.18-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libdb-5.3.28-57.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 755192 + checksum: sha256:3246e76f197e2b60eb470b9b55d3e0dda2301b029f295fed9c38ff70b87c5b6b + name: libdb + evr: 5.3.28-57.el9_6 + sourcerpm: libdb-5.3.28-57.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libdnf-plugin-subscription-manager-1.29.45.1-1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 34029 + checksum: sha256:0be17d982fc6edea35a675e3c63ff614b625917e1ce877cb961d051b327e0150 + name: libdnf-plugin-subscription-manager + evr: 1.29.45.1-1.el9_6 + sourcerpm: subscription-manager-1.29.45.1-1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libeconf-0.4.1-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 30371 + checksum: sha256:f7998382ca1be7836f6af05d42dc03f88799abcb10aa7a761e16f74058598012 + name: libeconf + evr: 0.4.1-4.el9 + sourcerpm: libeconf-0.4.1-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libedit-3.1-38.20210216cvs.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 109330 + checksum: sha256:9e41ff5754a5dca1308adf9617828934d56cb60d8d08f128f80e4328f69bc78c + name: libedit + evr: 3.1-38.20210216cvs.el9 + sourcerpm: libedit-3.1-38.20210216cvs.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libfdisk-2.37.4-21.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 159417 + checksum: sha256:81c7676b72b85d8b5822888c510952ec0996b3d89bf8cddaf76dba31bc72a4a1 + name: libfdisk + evr: 2.37.4-21.el9 + sourcerpm: util-linux-2.37.4-21.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libfido2-1.13.0-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 102746 + checksum: sha256:6da940c0528f3e4453db84cb85b402c8f4293a197b1921158df9651edb4845e0 + name: libfido2 + evr: 1.13.0-2.el9 + sourcerpm: libfido2-1.13.0-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libgomp-11.5.0-5.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 269396 + checksum: sha256:da7af36960df4b59178f4d7c42353d48c53fbe231e7e62d734a4319748f897a9 + name: libgomp + evr: 11.5.0-5.el9_5 + sourcerpm: gcc-11.5.0-5.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libmnl-1.0.4-16.el9_4.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 30949 + checksum: sha256:badfd4eb5b7cd3622da84168674002ec718ef810ce615a1113d3e19e265b777e + name: libmnl + evr: 1.0.4-16.el9_4 + sourcerpm: libmnl-1.0.4-16.el9_4.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libnl3-3.11.0-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 376137 + checksum: sha256:89728a253a5bf1c8e01c40573f1283d40188e003bdbd4ac565f8b0f05bced55c + name: libnl3 + evr: 3.11.0-1.el9 + sourcerpm: libnl3-3.11.0-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libpciaccess-0.16-7.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 29603 + checksum: sha256:8ae47c34ab3df3a3be4c1693454149677454ff911e971a3af06644016e065ba2 + name: libpciaccess + evr: 0.16-7.el9 + sourcerpm: libpciaccess-0.16-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libpipeline-1.5.3-4.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 52912 + checksum: sha256:c972030a8fbaa2d981f0e5fdfc42d6d5173dd047c94d86ab7732e3e53fc4e97a + name: libpipeline + evr: 1.5.3-4.el9 + sourcerpm: libpipeline-1.5.3-4.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libpkgconf-1.7.3-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 38387 + checksum: sha256:4feae5941b73640bd86b8d506a657cac5b770043db1464fbcd207721b2159dda + name: libpkgconf + evr: 1.7.3-10.el9 + sourcerpm: pkgconf-1.7.3-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libpng-1.6.37-12.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 121655 + checksum: sha256:42e7addb96958b293571949829378c054d6a1a762dccb78d5a777f8c531fc811 + name: libpng + evr: 2:1.6.37-12.el9 + sourcerpm: libpng-1.6.37-12.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libpwquality-1.4.4-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 126104 + checksum: sha256:14b7ff2f7fdaf8ebec90261f4619ea7f7c3564c4de8483666de7ed4b1f49b66f + name: libpwquality + evr: 1.4.4-8.el9 + sourcerpm: libpwquality-1.4.4-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libseccomp-2.5.2-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 76200 + checksum: sha256:e2015f60dbe784330d5df43f3f05c68c307694600a636a1706bf86527cc82e82 + name: libseccomp + evr: 2.5.2-2.el9 + sourcerpm: libseccomp-2.5.2-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libselinux-utils-3.6-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 198410 + checksum: sha256:e5d79885864cd5b2a307065b43ba1af1523ec7ac26eace2717c70ede1b6e4c56 + name: libselinux-utils + evr: 3.6-3.el9 + sourcerpm: libselinux-3.6-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libtirpc-1.3.3-9.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 98934 + checksum: sha256:f82cd69dc3aac881d5b574930c7d274687054cb5b03d3a8e3affa7bbcd5950b1 + name: libtirpc + evr: 1.3.3-9.el9 + sourcerpm: libtirpc-1.3.3-9.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libuser-0.63-16.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 424494 + checksum: sha256:a17e6412943a153295709642fa53b31c53c573c9c21599c6946ac93924afcced + name: libuser + evr: 0.63-16.el9 + sourcerpm: libuser-0.63-16.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/l/libutempter-1.2.1-6.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 30354 + checksum: sha256:0f1df5e0d48c2ac9914bfffa7ed569cd58e42b17ba96bb3f7cf74d1e80de2597 + name: libutempter + evr: 1.2.1-6.el9 + sourcerpm: libutempter-1.2.1-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/m/make-4.3-8.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 553896 + checksum: sha256:561f0c2251e9217c81a6c88de4d2d9231a039aaab37e8a0d2559d36ce9fa85fd + name: make + evr: 1:4.3-8.el9 + sourcerpm: make-4.3-8.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/m/man-db-2.9.3-7.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 1245006 + checksum: sha256:1eb7770a27102f59012f704e90aa04b130ab4f46fec983a7441ec9e8810f2da4 + name: man-db + evr: 2.9.3-7.el9 + sourcerpm: man-db-2.9.3-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/n/ncurses-6.2-10.20210508.el9_6.2.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 416227 + checksum: sha256:4f1dbaed64ecaf650d47613b86ea787d92b7fad23e8a75e8b86cc436ee949f49 + name: ncurses + evr: 6.2-10.20210508.el9_6.2 + sourcerpm: ncurses-6.2-10.20210508.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/o/openssh-8.7p1-45.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 474534 + checksum: sha256:d43f19d3e736943bdadbda47db016e9da81ce1900f50ecfe470f7a8bc9bce243 + name: openssh + evr: 8.7p1-45.el9 + sourcerpm: openssh-8.7p1-45.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/o/openssh-clients-8.7p1-45.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 735750 + checksum: sha256:309d1c9c176bf35b494c8b31a0f3eeceddd0b27be1dfc9defbe9838b9d5a707c + name: openssh-clients + evr: 8.7p1-45.el9 + sourcerpm: openssh-8.7p1-45.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/pam-1.5.1-26.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 636788 + checksum: sha256:247027fa7a2236c1fb46756ed372637f85cf85886603a2ad5ba918e4231324bc + name: pam + evr: 1.5.1-26.el9_6 + sourcerpm: pam-1.5.1-26.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/passwd-0.80-12.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 129243 + checksum: sha256:e5d8869dbc34672bb6bc94e00045f659b7d2415172cd27ee9f949e1769f71bb8 + name: passwd + evr: 0.80-12.el9 + sourcerpm: passwd-0.80-12.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/pkgconf-1.7.3-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 45675 + checksum: sha256:bb47b4ecc499c308f41031a99e723827d152d5d750f59849d0c265d820944a26 + name: pkgconf + evr: 1.7.3-10.el9 + sourcerpm: pkgconf-1.7.3-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/pkgconf-m4-1.7.3-10.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 16054 + checksum: sha256:91bafd6e06099451f60288327b275cfcc651822f6145176a157c6b0fa5131e02 + name: pkgconf-m4 + evr: 1.7.3-10.el9 + sourcerpm: pkgconf-1.7.3-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/pkgconf-pkg-config-1.7.3-10.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 12438 + checksum: sha256:9a502d81d73d3303ceb53a06ad7ce525c97117ea64352174a33708bf3429283d + name: pkgconf-pkg-config + evr: 1.7.3-10.el9 + sourcerpm: pkgconf-1.7.3-10.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/policycoreutils-3.6-2.1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 251967 + checksum: sha256:8dcd39960d3103f7a4ad2b9f7a0e15469ebf4da98f6c215cddfffdb830dc12b5 + name: policycoreutils + evr: 3.6-2.1.el9 + sourcerpm: policycoreutils-3.6-2.1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/procps-ng-3.3.17-14.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 361526 + checksum: sha256:506ad778f63821e8d9647ca8e0a3ff21b8af9c1666060d5200f9b26ee718333c + name: procps-ng + evr: 3.3.17-14.el9 + sourcerpm: procps-ng-3.3.17-14.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/protobuf-c-1.3.3-13.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 38224 + checksum: sha256:9669f5bed1c9532ede399cd1ea6f8937ae7d18cfb56d59f2939a4b456390035f + name: protobuf-c + evr: 1.3.3-13.el9 + sourcerpm: protobuf-c-1.3.3-13.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/psmisc-23.4-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 253357 + checksum: sha256:30ad5408417c7f06fb945dc321bef3ce31f813f25389707dd1efa7c1d337b806 + name: psmisc + evr: 23.4-3.el9 + sourcerpm: psmisc-23.4-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-3.9.21-2.el9_6.2.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 26190 + checksum: sha256:2572fc0f6c65dc5201c65a48f7d962a04a09669feae2fcdc4e5f9e910b9195c6 + name: python3 + evr: 3.9.21-2.el9_6.2 + sourcerpm: python3.9-3.9.21-2.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-chardet-4.0.0-5.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 248522 + checksum: sha256:49b0ab23d8436b6f0313cf69cd4992acd3b1ab3394753218cbd4d61dbbf5b2ae + name: python3-chardet + evr: 4.0.0-5.el9 + sourcerpm: python-chardet-4.0.0-5.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-cloud-what-1.29.45.1-1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 55150 + checksum: sha256:2824678f73a2c64345057ae1df69056ce136ed5e9b9ba80279f26066ab4feb86 + name: python3-cloud-what + evr: 1.29.45.1-1.el9_6 + sourcerpm: subscription-manager-1.29.45.1-1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-dateutil-2.8.1-7.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 312260 + checksum: sha256:d09386154d85f487aafcf2b88d5c3766f44684b0bf7df8ea35f8d6a45d994f16 + name: python3-dateutil + evr: 1:2.8.1-7.el9 + sourcerpm: python-dateutil-2.8.1-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-dbus-1.2.18-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 151901 + checksum: sha256:adf8aafd3b5a7c590e2350c52e172e4b373158d76925c89db59ad201ec68bd27 + name: python3-dbus + evr: 1.2.18-2.el9 + sourcerpm: dbus-python-1.2.18-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-decorator-4.4.2-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 32068 + checksum: sha256:298a276622e42061af13cd50820ece993a463f657a6145cb957518c7b8765286 + name: python3-decorator + evr: 4.4.2-6.el9 + sourcerpm: python-decorator-4.4.2-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-dnf-4.14.0-25.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 480011 + checksum: sha256:85bdaa101978e4cc1ade26a6c3d024e221e21ee035f4274ebb8ecaa7ef0cd706 + name: python3-dnf + evr: 4.14.0-25.el9 + sourcerpm: dnf-4.14.0-25.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-dnf-plugins-core-4.3.0-20.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 274864 + checksum: sha256:c5dd87574e699b09d37d180de6101f2709af160cf73f20ae4811e6fe356e8b0e + name: python3-dnf-plugins-core + evr: 4.3.0-20.el9 + sourcerpm: dnf-plugins-core-4.3.0-20.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-gobject-base-3.40.1-6.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 191543 + checksum: sha256:85912dbd3c57a6b5186b911498a7e7528865e24376ce7b1b6c05751929f97f7e + name: python3-gobject-base + evr: 3.40.1-6.el9 + sourcerpm: pygobject3-3.40.1-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-gobject-base-noarch-3.40.1-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 168699 + checksum: sha256:f17b28b2e02016e13f5ae88256315a2817ef229ca53e67c251afbd5e541e91ef + name: python3-gobject-base-noarch + evr: 3.40.1-6.el9 + sourcerpm: pygobject3-3.40.1-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-gpg-1.15.1-6.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 291563 + checksum: sha256:0fd96e53e678f92418c859d8fb95087dd989c7eacb399157768be0daef08cf8f + name: python3-gpg + evr: 1.15.1-6.el9 + sourcerpm: gpgme-1.15.1-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-hawkey-0.69.0-13.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 107800 + checksum: sha256:29471b28015f59dc95ffe2fd65c1e4d8a5cfba6e936757bef6291050420986f6 + name: python3-hawkey + evr: 0.69.0-13.el9 + sourcerpm: libdnf-0.69.0-13.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-idna-2.10-7.el9_4.1.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 108201 + checksum: sha256:af52887cccc937de789a399ba991cb49c5e98ab26742d017e2f58ed2d9eb5d0d + name: python3-idna + evr: 2.10-7.el9_4.1 + sourcerpm: python-idna-2.10-7.el9_4.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-iniparse-0.4-45.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 51931 + checksum: sha256:2d963fbff4044e88673c52fb03cc11d9395dcc2a0c27a26844477bf6eb1e8160 + name: python3-iniparse + evr: 0.4-45.el9 + sourcerpm: python-iniparse-0.4-45.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-inotify-0.9.6-25.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 57334 + checksum: sha256:219825121d761bf163e746f0ca424e4dfe071aece87c22ccd632abcf78ab4920 + name: python3-inotify + evr: 0.9.6-25.el9 + sourcerpm: python-inotify-0.9.6-25.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-libcomps-0.1.18-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 53345 + checksum: sha256:39d6fe73373ae5692e510b7c6219ad1ffadad0f1bc59cb7095faf6e095811768 + name: python3-libcomps + evr: 0.1.18-1.el9 + sourcerpm: libcomps-0.1.18-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-libdnf-0.69.0-13.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 800686 + checksum: sha256:331ce2bf00b96671e73e5889d98f38d46bf61d22c051d3634dae1e76ea49181f + name: python3-libdnf + evr: 0.69.0-13.el9 + sourcerpm: libdnf-0.69.0-13.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-librepo-1.14.5-2.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 51462 + checksum: sha256:8dc96dbaa89461b37c96743e49cc62b0494862aef78d2a80bbaac04fd065afe3 + name: python3-librepo + evr: 1.14.5-2.el9 + sourcerpm: librepo-1.14.5-2.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-libs-3.9.21-2.el9_6.2.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 8474800 + checksum: sha256:a8a433346daa16f25d8f672bdc6cbee9277631c60378006fb1056b4443ce505d + name: python3-libs + evr: 3.9.21-2.el9_6.2 + sourcerpm: python3.9-3.9.21-2.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-pip-wheel-21.3.1-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 1193706 + checksum: sha256:75c46aab03898c66ce16be556432b71aed7efcedce02b9263339c14f57b4fdc0 + name: python3-pip-wheel + evr: 21.3.1-1.el9 + sourcerpm: python-pip-21.3.1-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-pysocks-1.7.1-12.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 39172 + checksum: sha256:1e7586cb9918e6c365105d452b9efedfaf5bb7c80309c5d0151043da847dc15f + name: python3-pysocks + evr: 1.7.1-12.el9 + sourcerpm: python-pysocks-1.7.1-12.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-requests-2.25.1-10.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 129490 + checksum: sha256:d8dc5b2edb7ed0eb14e3d41d126c68374354f4aaed82f87f14327af73ea2c1a1 + name: python3-requests + evr: 2.25.1-10.el9_6 + sourcerpm: python-requests-2.25.1-10.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-rpm-4.16.1.3-37.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 69939 + checksum: sha256:f33881afbad42a5ef4b8f592fa02d674a68f8ea906eaa0045d73af7fb3a927f3 + name: python3-rpm + evr: 4.16.1.3-37.el9 + sourcerpm: rpm-4.16.1.3-37.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-setuptools-53.0.0-13.el9_6.1.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 965161 + checksum: sha256:66ce16176d9c1b4d6db34aa579f2c1c26850ded0534c3ed26f67be8cc976e2f0 + name: python3-setuptools + evr: 53.0.0-13.el9_6.1 + sourcerpm: python-setuptools-53.0.0-13.el9_6.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-setuptools-wheel-53.0.0-13.el9_6.1.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 479114 + checksum: sha256:99807cec6f3941b1ec963813a5eaf7cf7922690cda6b35cd0f1fe0a3bdc1459f + name: python3-setuptools-wheel + evr: 53.0.0-13.el9_6.1 + sourcerpm: python-setuptools-53.0.0-13.el9_6.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-six-1.15.0-9.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 41373 + checksum: sha256:76c760f7e4ed054d158a31ef7927130baf917703c80eda92b0202b613aa81ef2 + name: python3-six + evr: 1.15.0-9.el9 + sourcerpm: python-six-1.15.0-9.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-subscription-manager-rhsm-1.29.45.1-1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 142401 + checksum: sha256:b5a061a1a35df2c2161f01d06f516eca4409800a26c1f10f5a31b110389e3f55 + name: python3-subscription-manager-rhsm + evr: 1.29.45.1-1.el9_6 + sourcerpm: subscription-manager-1.29.45.1-1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-systemd-234-19.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 95185 + checksum: sha256:70e0833c8e067d737a296ff89810c5ce11ae4b9099c1101b0d0533c3d60bfe2e + name: python3-systemd + evr: 234-19.el9 + sourcerpm: python-systemd-234-19.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/p/python3-urllib3-1.26.5-6.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 223946 + checksum: sha256:458494f58101f73fdae0330abe88f34b9a648f66a7ab40500bd1b99fc6d321ab + name: python3-urllib3 + evr: 1.26.5-6.el9 + sourcerpm: python-urllib3-1.26.5-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/r/rpm-build-libs-4.16.1.3-37.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 92449 + checksum: sha256:b98fbdc053c915848bedb008aa93127efc64192359aba59fd094d245fba7e4a0 + name: rpm-build-libs + evr: 4.16.1.3-37.el9 + sourcerpm: rpm-4.16.1.3-37.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/r/rpm-plugin-selinux-4.16.1.3-37.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 18109 + checksum: sha256:1e21fe626bb81ccf59e8de8194395017e3a5fa929cbf6c6da82ba1598f6bb27f + name: rpm-plugin-selinux + evr: 4.16.1.3-37.el9 + sourcerpm: rpm-4.16.1.3-37.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/r/rpm-sign-libs-4.16.1.3-37.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 22416 + checksum: sha256:98b7dbb2711f41e4c55612a4e6e03f17a59a8e98df866ff644b9c85620aff0d0 + name: rpm-sign-libs + evr: 4.16.1.3-37.el9 + sourcerpm: rpm-4.16.1.3-37.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/r/rsync-3.2.5-3.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 421930 + checksum: sha256:b1d90c38b613f2d66dfe0c7c3d067a3ce429f7b2ec5224e560f326fc2fd8d1e5 + name: rsync + evr: 3.2.5-3.el9 + sourcerpm: rsync-3.2.5-3.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/s/selinux-policy-38.1.53-5.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 46473 + checksum: sha256:e397424c237fb3b0b19f7ba7b1d59ec5a54e8c184ae8be1b1d12223f5ec1f3b7 + name: selinux-policy + evr: 38.1.53-5.el9_6 + sourcerpm: selinux-policy-38.1.53-5.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/s/selinux-policy-targeted-38.1.53-5.el9_6.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 7251875 + checksum: sha256:e5a1a2e4ca35e6639ac12a651c3fcb4aede1b62755d71920c9819c7939430b5b + name: selinux-policy-targeted + evr: 38.1.53-5.el9_6 + sourcerpm: selinux-policy-38.1.53-5.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/s/shadow-utils-subid-4.9-12.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 90389 + checksum: sha256:342ced93b6ca9b0fd884f990177f7b1e8a6bc35e0bb2a6d4b6684cf8f0062760 + name: shadow-utils-subid + evr: 2:4.9-12.el9 + sourcerpm: shadow-utils-4.9-12.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/s/subscription-manager-1.29.45.1-1.el9_6.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 917239 + checksum: sha256:9095bac6daaaeef14e315ec44f015a0ae2a102b0986d883706741680a10f2cee + name: subscription-manager + evr: 1.29.45.1-1.el9_6 + sourcerpm: subscription-manager-1.29.45.1-1.el9_6.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/s/subscription-manager-rhsm-certificates-20220623-1.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 22460 + checksum: sha256:66c73c5e907040a6e67f70452a1c00ebc4d07cf4c7cf2e2b2795a8260795fb2a + name: subscription-manager-rhsm-certificates + evr: 20220623-1.el9 + sourcerpm: subscription-manager-rhsm-certificates-20220623-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/s/systemd-252-51.el9_6.2.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 4397767 + checksum: sha256:b7acb6861d52c368eeb23afe3413f4de4ba60281598e55f931b2a4882b5ae239 + name: systemd + evr: 252-51.el9_6.2 + sourcerpm: systemd-252-51.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/s/systemd-pam-252-51.el9_6.2.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 285233 + checksum: sha256:bb438d85cdf5dc7a53cf1309fa48d7be8814e9cfaec846efe8bb559720325fb7 + name: systemd-pam + evr: 252-51.el9_6.2 + sourcerpm: systemd-252-51.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/s/systemd-rpm-macros-252-51.el9_6.2.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 68125 + checksum: sha256:a9d98e4240645fa96c953218bc89dbda221e33247f2890790dead31b53adff49 + name: systemd-rpm-macros + evr: 252-51.el9_6.2 + sourcerpm: systemd-252-51.el9_6.2.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/t/tcl-8.6.10-7.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 1152092 + checksum: sha256:2062dce4bed26d3684de4dad68f32307ebacf5c7d50d3aa7bf6470e66fb36df5 + name: tcl + evr: 1:8.6.10-7.el9 + sourcerpm: tcl-8.6.10-7.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/t/tpm2-tss-3.2.3-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 621714 + checksum: sha256:b1f148136e6cf67ac5f86a601d41a1b2798e7b5ef32e684358987d77c9ed424b + name: tpm2-tss + evr: 3.2.3-1.el9 + sourcerpm: tpm2-tss-3.2.3-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/u/unzip-6.0-58.el9_5.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 190785 + checksum: sha256:009698f3b4432b9df219fd2f894234aad1cee8c4e4e61384b4e293ef8e28e9c2 + name: unzip + evr: 6.0-58.el9_5 + sourcerpm: unzip-6.0-58.el9_5.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/u/usermode-1.114-6.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 196850 + checksum: sha256:3ed0329cb946c18a6925a20651ea175befdc05593e01b6381ab0b88c4a6f3182 + name: usermode + evr: 1.114-6.el9 + sourcerpm: usermode-1.114-6.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/u/util-linux-2.37.4-21.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 2395065 + checksum: sha256:61c795084ae4b7745b904347d4643110cd62558fce2978bd4f025ff83524e55f + name: util-linux + evr: 2.37.4-21.el9 + sourcerpm: util-linux-2.37.4-21.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/u/util-linux-core-2.37.4-21.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 480619 + checksum: sha256:36389814fcec56d9b9d4bd1a4a63efb1cefa00bc8bacab73f89ef8f8be04b1cd + name: util-linux-core + evr: 2.37.4-21.el9 + sourcerpm: util-linux-2.37.4-21.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/v/vim-filesystem-8.2.2637-22.el9_6.1.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 13249 + checksum: sha256:9298e32061a3bce9b94f8c1bd1ac3ee0bfa67a68863cc3a0cd97c5432b6e89ed + name: vim-filesystem + evr: 2:8.2.2637-22.el9_6.1 + sourcerpm: vim-8.2.2637-22.el9_6.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/v/vim-minimal-8.2.2637-22.el9_6.1.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 685329 + checksum: sha256:4e635f5e27f44f9c08521502d29d6c57a7be3db192b9bc533caaf8f72e9bdf3b + name: vim-minimal + evr: 2:8.2.2637-22.el9_6.1 + sourcerpm: vim-8.2.2637-22.el9_6.1.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/v/virt-what-1.27-1.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 46721 + checksum: sha256:4fba6a4bc2ee8a56c3c21c555e2fc930155f91862a22301883a73ae22d3beb7f + name: virt-what + evr: 1.27-1.el9 + sourcerpm: virt-what-1.27-1.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/x/xz-5.2.5-8.el9_0.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 235693 + checksum: sha256:f16d17c26a241400586ddc3d734ce863e3f19d433881ec640a47bedf0dafd07b + name: xz + evr: 5.2.5-8.el9_0 + sourcerpm: xz-5.2.5-8.el9_0.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/y/yum-4.14.0-25.el9.noarch.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 93904 + checksum: sha256:cf8b191674efee22dc2f01e8932a6edc26f9ec2fdcc1f1cbe303b06d1958d439 + name: yum + evr: 4.14.0-25.el9 + sourcerpm: dnf-4.14.0-25.el9.src.rpm + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/os/Packages/z/zip-3.0-35.el9.x86_64.rpm + repoid: ubi-9-for-x86_64-baseos-rpms + size: 276200 + checksum: sha256:ef28011ba191f53260cebb1e42b0148ae65d9029940146699e802f501dba009c + name: zip + evr: 3.0-35.el9 + sourcerpm: zip-3.0-35.el9.src.rpm + source: + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/a/alsa-lib-1.2.13-2.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 1215277 + checksum: sha256:1b9db2aa1e09cb40372bdcd1dfe6f613d20b7eaed88028687c96c934379e7d6f + name: alsa-lib + evr: 1.2.13-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/a/annobin-12.92-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 998524 + checksum: sha256:65ee4ea686dfa6a8da136896ff590fb476248e998a14c38b28713a34a23cf1b9 + name: annobin + evr: 12.92-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/a/at-spi2-atk-2.38.0-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 111112 + checksum: sha256:5713e30db407b1debad820ea89e57f3db5fe9c4e222ce44ab45d9e38ce52fe5a + name: at-spi2-atk + evr: 2.38.0-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/a/at-spi2-core-2.40.3-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 213364 + checksum: sha256:3a5717b63603264a184a1ef26f606898c7f0ecc4b57ebd996d05b73a77bb8336 + name: at-spi2-core + evr: 2.40.3-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/a/atk-2.36.0-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 313725 + checksum: sha256:171734f6cf9638497ccaccb73ab79b49d37085930e0c03d4c954aac2eaddbdc9 + name: atk + evr: 2.36.0-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/c/cairo-1.17.4-7.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 41864767 + checksum: sha256:0185c51c6c00b3a238e9038addfa1be86fee1b3cc3933efdd4f05f8c5db775d6 + name: cairo + evr: 1.17.4-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/c/cmake-3.26.5-2.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 10671338 + checksum: sha256:2f86bb96562eaf679969c2716738fbdfcc8a3966ecc3bb6317596fe2e214ea2b + name: cmake + evr: 3.26.5-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/c/container-selinux-2.237.0-2.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 49556 + checksum: sha256:9a124671483d654c1b9d5ef38683a04cc7d6082579aaacbaeae3a60a2b43946e + name: container-selinux + evr: 4:2.237.0-2.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/c/containers-common-1-117.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 168528 + checksum: sha256:3ae3f5c20849053dcd2d8dfc378f1687f63c19280045df9af39071d83d329834 + name: containers-common + evr: 2:1-117.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/c/criu-3.19-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 1397103 + checksum: sha256:e9d46b1c6c4ffa968a235504c57a721185ebc89bbc59e700589c908d0c1872f6 + name: criu + evr: 3.19-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/c/crun-1.23.1-2.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 845345 + checksum: sha256:8fcfe0507a43ab0de2194e4d973b4f18ff24750fd56b5edbcb22ca626d07a6af + name: crun + evr: 1.23.1-2.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/d/dwz-0.14-3.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 159459 + checksum: sha256:7565e0aed6cfb90c2c4be4ae2b33536fc4cf9b1b05a6a07da940ec564475580f + name: dwz + evr: 0.14-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/e/emacs-27.2-14.el9_6.2.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 44824139 + checksum: sha256:50a3faee5df3fd8d39609d97a62ef1297f668733105f4871d41a9257840269a3 + name: emacs + evr: 1:27.2-14.el9_6.2 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/f/fontconfig-2.14.0-2.el9_1.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 1460194 + checksum: sha256:623ac6b43061ad2f2b5d07861dfeb9b83ef70ead8df02319d375e71bc0110b67 + name: fontconfig + evr: 2.14.0-2.el9_1 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/f/fribidi-1.0.10-6.el9.2.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 1177189 + checksum: sha256:d5e12deb110f7a5a8776435efa8f6c5e42ecf990e0ed27f95293020b65891254 + name: fribidi + evr: 1.0.10-6.el9.2 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/f/fuse-overlayfs-1.14-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 114235 + checksum: sha256:ed1f6fd4c4c9efc2e499ffcb86c63d0f82657395e579a3f7b8525a4087ba5ece + name: fuse-overlayfs + evr: 1.14-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/g/gdb-14.2-4.1.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 24789075 + checksum: sha256:627574c44fb4f472d557cf9b0581aa1ffe5009316c09c69b0619eac1ec1496c9 + name: gdb + evr: 14.2-4.1.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/g/ghc-srpm-macros-1.5.0-6.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 10180 + checksum: sha256:2d980af2311afd353583b200783cb39a5da7e89b6dbb9e67aa7d77a2c53e0cab + name: ghc-srpm-macros + evr: 1.5.0-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/g/git-2.47.3-1.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 7707656 + checksum: sha256:815c2ae9574006ecb596000492929264de785444736ee3968d5ee34cb6e75159 + name: git + evr: 2.47.3-1.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/g/go-rpm-macros-3.6.0-10.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 134995 + checksum: sha256:6c475fcaeb2eef79bb8d37bdc2d1e8ad07ec44be137fce4c677fd0ea11add375 + name: go-rpm-macros + evr: 3.6.0-10.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/k/kernel-srpm-macros-1.0-13.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 28536 + checksum: sha256:6607ae4cf2e0ee6971a740ef64937853e4e636179822de40e709e8e3e0c7853b + name: kernel-srpm-macros + evr: 1.0-13.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libX11-1.7.0-11.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 2436722 + checksum: sha256:8720840bc38af119d62734144a5e8c95c1400ba42bd877e4279a786120d878d7 + name: libX11 + evr: 1.7.0-11.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXau-1.0.9-8.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 335512 + checksum: sha256:3a52f0d37183b84a7f8d37d6ca314ec17a32c1d4167c9131cf4000285d82c59a + name: libXau + evr: 1.0.9-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXcomposite-0.4.5-7.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 329141 + checksum: sha256:10f74555246a4a992de429bf1139b762ca6b8d754d092a5eb85f0c55f576a9db + name: libXcomposite + evr: 0.4.5-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXdamage-1.1.5-7.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 315892 + checksum: sha256:15c2c0d99190985a2a7d376b0cbb2d9f6172ebdcb1a3305ac0bbd7a394942e8c + name: libXdamage + evr: 1.1.5-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXext-1.3.4-8.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 401955 + checksum: sha256:7f50b5d07f8e1782c4ad2c485416f210004db0477588465167c257aa62fd0b6c + name: libXext + evr: 1.3.4-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXfixes-5.0.3-16.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 306511 + checksum: sha256:3c8feb2710a52fe119d58369895cb2a17a10097a0a6b3a2bf469f0e34cf58db6 + name: libXfixes + evr: 5.0.3-16.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXft-2.3.3-8.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 365800 + checksum: sha256:b1ef5a942e759207022bf9bff3d122bc9596914d8dd7ab92ea56ebcad96ee9a6 + name: libXft + evr: 2.3.3-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXi-1.7.10-8.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 498271 + checksum: sha256:1de8a31cbe5edf8d10fe85fd96c1ebd1d0525c08a3ec75599ef12bad2945545c + name: libXi + evr: 1.7.10-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXrandr-1.5.2-8.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 343241 + checksum: sha256:a565d64c7ff4b9c46cfc916097b1c8c9d886c006a7c18eac085f4ca6b4e8d310 + name: libXrandr + evr: 1.5.2-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXrender-0.9.10-16.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 320828 + checksum: sha256:5fc0f3794b08cc71d89bf24c19a4a02c2d15c63850225327af9f20b45e1250e8 + name: libXrender + evr: 0.9.10-16.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libXtst-1.2.3-16.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 332563 + checksum: sha256:59a99e7e1af8762969b9212aa5375be77a7bdafce73f416be82694b16ec388d5 + name: libXtst + evr: 1.2.3-16.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libdatrie-0.2.13-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 325692 + checksum: sha256:c9a3acd383ebb5f8d5d2c069dca717f147fddc461155cc12f07572972a82e7fe + name: libdatrie + evr: 0.2.13-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libdrm-2.4.123-2.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 500530 + checksum: sha256:8fd4b075f14ade405808c1ae309270aad50709f615bcd24d93aa39ae65e3a977 + name: libdrm + evr: 2.4.123-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libmpc-1.2.1-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 846236 + checksum: sha256:47774c27b65e63251f3a1cea99efbe8caed86448a573e34a44ab28ad88cc3ece + name: libmpc + evr: 1.2.1-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libnet-1.2-7.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 611553 + checksum: sha256:bc2724e7061c48e2038f4f47b433bebccedb4ffc227dc351baaf3d5a52f03b08 + name: libnet + evr: 1.2-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libnsl2-2.0.0-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 56885 + checksum: sha256:28fda2510dfa3d80c6f227354c3e917a104374e97566419e71ef5e246887c4e2 + name: libnsl2 + evr: 2.0.0-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libslirp-4.4.0-8.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 128699 + checksum: sha256:5e740382ebf1511fc7c4fa0c1db0bc72fad624329ff9e359cea75cccbed503e4 + name: libslirp + evr: 4.4.0-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libthai-0.1.28-8.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 426287 + checksum: sha256:1bff93f9076778b16fea27d75a7434caf8e9fb5e9bcabbf2cf8f7f0069302d73 + name: libthai + evr: 0.1.28-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libuv-1.42.0-2.el9_4.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 1300269 + checksum: sha256:f9dfa0dc965675730184604570c6a2aa95ddc2dfa6a7cb209514b1e744a4e3d7 + name: libuv + evr: 1:1.42.0-2.el9_4 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libxcb-1.13.1-9.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 519787 + checksum: sha256:6e79beeac5762cb0f4eca5a4e09aaf9f607b8d54a8154e68a672c4d42e5a617b + name: libxcb + evr: 1.13.1-9.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libxkbcommon-1.0.3-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 446799 + checksum: sha256:47b1254e062547a0e553b4e072498a91bf3c7364c8499c15a2762858197c50de + name: libxkbcommon + evr: 1.0.3-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/libxshmfence-1.3-10.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 319069 + checksum: sha256:9a36c33eafdf600040cb41cc1d8ca40395a3e00f2fd6a41a28ad66644d90edaa + name: libxshmfence + evr: 1.3-10.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/llvm-19.1.7-2.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 141371853 + checksum: sha256:2da62e4083e0f9ff5ca3d5ffc794682ff16004b2f0b38b4a103e34d18dbd322e + name: llvm + evr: 19.1.7-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/l/lua-rpm-macros-1-6.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 12116 + checksum: sha256:19fdee3aa469d583a7f48dce71513da47c5046018bc35bfbe57c818b7aae21d0 + name: lua-rpm-macros + evr: 1-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/m/mesa-24.2.8-3.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 33249517 + checksum: sha256:760b844c1e67f3828e6ab02ed567df44e276887a092ef6e7d76843927f4adb7b + name: mesa + evr: 24.2.8-3.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/m/mpdecimal-2.5.1-3.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 3334137 + checksum: sha256:2f5ece89d6a8d892816f386462d8be291ad83f1500b4c4b3655dcc7ed5192c0d + name: mpdecimal + evr: 2.5.1-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/n/nss-3.112.0-4.el9_4.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 81951225 + checksum: sha256:2c03ead1e23a8a81cc6e28fbc46fa51b7cd085ab84186117ecb78dc86d0632f2 + name: nss + evr: 3.112.0-4.el9_4 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/n/nss_wrapper-1.1.13-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 199854 + checksum: sha256:70665df15ed2534a7216880efc46d4073c61580e6929cfb6e033a9739f487aab + name: nss_wrapper + evr: 1.1.13-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/o/ocaml-srpm-macros-6-6.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 10233 + checksum: sha256:198f33946c3b1c1e104109073449ac03fd59035e6c3f646ad847626aa646e336 + name: ocaml-srpm-macros + evr: 6-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/o/openblas-srpm-macros-2-11.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 9345 + checksum: sha256:fe7a59edc21a63ddabfc48585a536d7c97dbcf27d46fa1e8b723df87a3c76bb3 + name: openblas-srpm-macros + evr: 2-11.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/pango-1.48.7-3.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 2073489 + checksum: sha256:4efddadb4bf304a47e2cce96d6d63d1643f5bdcb06dace3c04f8d37410f8bc22 + name: pango + evr: 1.48.7-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-5.32.1-481.1.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 12786537 + checksum: sha256:cef69403d27b100525c0e630fb17d1ef1d598c608241ea07ba0975b559a42858 + name: perl + evr: 4:5.32.1-481.1.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Algorithm-Diff-1.2010-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 43626 + checksum: sha256:5bdfea020bfb4ee04c5fd3a5552724f21af7df49d8bf9b774060f1dd47c6b972 + name: perl-Algorithm-Diff + evr: 1.2010-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Archive-Tar-2.38-6.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 79758 + checksum: sha256:c543a9be1a2e718e3fa282b16fc058a4e3e3c21d75513591ed170a63c9944e37 + name: perl-Archive-Tar + evr: 2.38-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Archive-Zip-1.68-6.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 177506 + checksum: sha256:0bc6505ab7fe87129f423e887a65153d015c38ddc68115ccf2149ebff5db92e1 + name: perl-Archive-Zip + evr: 1.68-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-CPAN-2.29-5.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 913914 + checksum: sha256:ce91adec7194b6d7b65079f712418469db4b4d657251ddcf6643299b232644a1 + name: perl-CPAN + evr: 2.29-5.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-CPAN-DistnameInfo-0.12-23.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 26900 + checksum: sha256:2dde7ae0e396bf60d579f1c711a0ce6845c5a6dc8a3069fc125e64709c03e764 + name: perl-CPAN-DistnameInfo + evr: 0.12-23.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-CPAN-Meta-2.150010-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 129946 + checksum: sha256:b93a6beedf64a4270dc4281fd9ea6fc5fabc08511bfd7ec95582bdcd5a3f50f3 + name: perl-CPAN-Meta + evr: 2.150010-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-CPAN-Meta-Requirements-2.140-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 45057 + checksum: sha256:cae76684fe68e4ef068523036a12aa65aa9ff697908aa448af0b5842507c8f11 + name: perl-CPAN-Meta-Requirements + evr: 2.140-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-CPAN-Meta-YAML-0.018-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 63081 + checksum: sha256:b0ae0d2859a6dbf7cd77de0e547370f85489f617319d8f55eb3b3533c22ea943 + name: perl-CPAN-Meta-YAML + evr: 0.018-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Carp-1.50-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 37030 + checksum: sha256:67ec8f31b0276573adc231a83abb15d42f31f56c2520f377da39e6dc9904ccf9 + name: perl-Carp + evr: 1.50-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Compress-Bzip2-2.28-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 908406 + checksum: sha256:fd5ed562b1231e74f8dd6856e8b4494872a1afc84a11dc4b26eb3f59193cf78f + name: perl-Compress-Bzip2 + evr: 2.28-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Compress-Raw-Bzip2-2.101-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 154607 + checksum: sha256:06e2c818ae4ac7823ae67869037edb071cedb745bce8e010a268d1850999ac38 + name: perl-Compress-Raw-Bzip2 + evr: 2.101-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Compress-Raw-Lzma-2.101-3.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 133511 + checksum: sha256:e73434426813ed9db9b82bdd301f4d0717b613fc8db3ff48e2e198d3b1e20fad + name: perl-Compress-Raw-Lzma + evr: 2.101-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Compress-Raw-Zlib-2.101-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 271620 + checksum: sha256:f815738f7e64cb1912a188a57f32b9e3416192bdc2c80a61308cf668a0cb6ba9 + name: perl-Compress-Raw-Zlib + evr: 2.101-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Config-Perl-V-0.33-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 35359 + checksum: sha256:77f7dbd94351b5cbe86859d557eb08525cb50bad76a344c7e4f5b16decb97be1 + name: perl-Config-Perl-V + evr: 0.33-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-DB_File-1.855-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 158812 + checksum: sha256:b0db40023b1387c9e1cb5f4a28914e4e7426e112132fd9e03a21a78c08a91bd9 + name: perl-DB_File + evr: 1.855-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Data-Dumper-2.174-462.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 131573 + checksum: sha256:554ef703b9510fdfc7fb7439f20e5b5be6bc05f720ad81fc4cf3973111532d7e + name: perl-Data-Dumper + evr: 2.174-462.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Data-OptList-0.110-17.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 31802 + checksum: sha256:e2b75b4859a73491af1aa145027a54aeda204f31508f98c264ec719f0759fef0 + name: perl-Data-OptList + evr: 0.110-17.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Data-Section-0.200007-14.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 35026 + checksum: sha256:29b50e2e9fcfd3ef490fde575e5651dd185d7bc10f62c97b2d7b6b525ecdd746 + name: perl-Data-Section + evr: 0.200007-14.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Devel-PPPort-3.62-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 469970 + checksum: sha256:1c4181c874720056a80d1ee015196f36ceef296709fe93d5d2b5282d6b90f80f + name: perl-Devel-PPPort + evr: 3.62-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Devel-Size-0.83-10.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 88128 + checksum: sha256:5d65648105f4b21ba27f516113c995f25d19df091820d1fe6e99d72a6e89783c + name: perl-Devel-Size + evr: 0.83-10.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Digest-1.19-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 22653 + checksum: sha256:cfac6eec4d3564b4a9a46df943e5e3b11434673dccfe095e2f631978636d61d1 + name: perl-Digest + evr: 1.19-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Digest-MD5-2.58-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 60213 + checksum: sha256:759005f7d3a3ee7a97da1af8f4c4e30a6d8592f1bc5ca95e6e065c6793f8ea17 + name: perl-Digest-MD5 + evr: 2.58-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Digest-SHA-6.02-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 60965 + checksum: sha256:6223e7b6ee3e168987685a0432eb30908b88a4e33503c4f71ffd1f4202be64d5 + name: perl-Digest-SHA + evr: 1:6.02-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Digest-SHA1-2.13-34.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 51532 + checksum: sha256:24cb3be49a88473ca75fb773cca161a32a081afb243cd8b737aa7d3b6399a7f0 + name: perl-Digest-SHA1 + evr: 2.13-34.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Encode-3.08-462.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 1915541 + checksum: sha256:f5a4058ed88a2763aad3a39a13d7cbe68d0d76f8d7a98b634cb7de63f747e407 + name: perl-Encode + evr: 4:3.08-462.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Encode-Locale-1.05-21.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 19941 + checksum: sha256:4c7446c8690a0dc5a7e80a703ab32be8d7f8819493aec5e15a9468e5972f9070 + name: perl-Encode-Locale + evr: 1.05-21.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Env-1.04-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 22963 + checksum: sha256:f7872c1ec5309090bab03ab984ef49e7ab108f6e7f7a7acddc718e67847f2489 + name: perl-Env + evr: 1.04-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Error-0.17029-7.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 46570 + checksum: sha256:387afa8f708f97fd2f72e8d54db80a6554340eefaec6ce36b05055fc1eabd004 + name: perl-Error + evr: 1:0.17029-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Exporter-5.74-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 32709 + checksum: sha256:67cf67c052ac12e234811589fe0a446a8ad79d4ab09da1187b422397d5f41440 + name: perl-Exporter + evr: 5.74-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-ExtUtils-CBuilder-0.280236-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 54700 + checksum: sha256:c4825f03bd2f125d4a7b9c361fdbae58e3eb888b40792d6ca740d4c9796529a3 + name: perl-ExtUtils-CBuilder + evr: 1:0.280236-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-ExtUtils-Install-2.20-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 52908 + checksum: sha256:a5a00213a6c11ebfe564f890525323981c10bb990ce06a1ad05163ccce239a54 + name: perl-ExtUtils-Install + evr: 2.20-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-ExtUtils-MakeMaker-7.60-3.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 504754 + checksum: sha256:8f17335d16783c182512dfc1af5cd8a762b41944f024f456849f2dd475ad2648 + name: perl-ExtUtils-MakeMaker + evr: 2:7.60-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-ExtUtils-Manifest-1.73-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 51571 + checksum: sha256:db9319ce19481088c58205d252bc03fc816711399ac54b9cb90a0f12cc7a24c4 + name: perl-ExtUtils-Manifest + evr: 1:1.73-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-ExtUtils-ParseXS-3.40-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 138437 + checksum: sha256:aaa28538e07c7df4eb6e0d3ca1aa6d2806f7977116839c0605bf49962332e16b + name: perl-ExtUtils-ParseXS + evr: 1:3.40-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-File-Fetch-1.00-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 32628 + checksum: sha256:ee5ddafaff74bc4cbaafb81de847a4e5fcafe7d55ea39a3aad8acce1d3cfd9a2 + name: perl-File-Fetch + evr: 1.00-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-File-HomeDir-1.006-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 48314 + checksum: sha256:9324fc77f0cae4a487865f7168e58fefaf2a45dd44d5acb0c0ffd607bc79e972 + name: perl-File-HomeDir + evr: 1.006-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-File-Path-2.18-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 43503 + checksum: sha256:2523a27381e16676442f21d6c90a0ebabeb65eb37d0ef4a2dacc02155bad183b + name: perl-File-Path + evr: 2.18-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-File-Temp-0.231.100-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 89500 + checksum: sha256:540bfbab1936e66314c0eac3a0880cd4a6ad55242055d7492a398868653d2d89 + name: perl-File-Temp + evr: 1:0.231.100-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-File-Which-1.23-10.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 35149 + checksum: sha256:fd089f060aea15adcd7fe380a388fa8feb40daa0820b3d50dd20616c56bd6c68 + name: perl-File-Which + evr: 1.23-10.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Filter-1.60-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 108315 + checksum: sha256:a9b8bb8bef551453366fab1f66883904c8ba996926d906fd32b759880a588dad + name: perl-Filter + evr: 2:1.60-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Filter-Simple-0.96-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 32804 + checksum: sha256:a070b22cd4c09d06fa4078588f0a2a8735490defc6a93ebea7599ae5ee1ee557 + name: perl-Filter-Simple + evr: 0.96-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Getopt-Long-2.52-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 55697 + checksum: sha256:c5260e60a5d3e4a6ba1ac7aad158322bfc7af0e9e85c10a4426860620cefda28 + name: perl-Getopt-Long + evr: 1:2.52-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-HTTP-Tiny-0.076-462.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 93389 + checksum: sha256:fe6eea19db536fbb948f3bbaf2d334bce7c39638342b8c6b79df7b3cc0a3a103 + name: perl-HTTP-Tiny + evr: 0.076-462.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-IO-Compress-2.102-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 311395 + checksum: sha256:6a4d183d03c58572ad99c44427d4f80174a74e88f82e815ef9b68ee367949414 + name: perl-IO-Compress + evr: 2.102-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-IO-Compress-Lzma-2.101-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 117388 + checksum: sha256:b98fc6c2bba6a5310eeea99c39c4eb4b4c9c5f6f115c1ca391ff9f983b3603b6 + name: perl-IO-Compress-Lzma + evr: 2.101-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-IO-Socket-IP-0.41-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 58169 + checksum: sha256:820b50e8bbd44baeb36fb2c4996d88909043fb26333c16a0f4f5335d1bc1d04a + name: perl-IO-Socket-IP + evr: 0.41-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-IO-Socket-SSL-2.073-2.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 295384 + checksum: sha256:f70d650d6e7f244491287e88d0f95637461c3fbd4e6a6124d285520eb0606924 + name: perl-IO-Socket-SSL + evr: 2.073-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-IO-Zlib-1.11-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 22007 + checksum: sha256:e83d2fcd26cbbac178ae8a77d75bb1e35ae697a0a1ebd9838787b0e7355b476f + name: perl-IO-Zlib + evr: 1:1.11-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-IPC-Cmd-1.04-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 45145 + checksum: sha256:d36b285269c9f8f186899296e922527b0d5efedae08d8ecef5e928369f344f04 + name: perl-IPC-Cmd + evr: 2:1.04-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-IPC-SysV-2.09-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 80187 + checksum: sha256:f3d99435bdc3bb3066a79ccf7e0e15b91ce2503a7ef2ef8a228238e03fd41b09 + name: perl-IPC-SysV + evr: 2.09-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-IPC-System-Simple-1.30-6.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 46334 + checksum: sha256:13c06559e1d68b47019a9e4ae4387d5962f0dd85a6ee77f2ed23ebcea92a7990 + name: perl-IPC-System-Simple + evr: 1.30-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Importer-0.026-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 52799 + checksum: sha256:52f89eb0a2d5f0a6a668679aa2d9adb4fb92e35fdd06e87d0b9d169d43d2e7ce + name: perl-Importer + evr: 0.026-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-JSON-PP-4.06-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 66646 + checksum: sha256:25990b7a748140b948e4ad9a6aad236f7c82dc7a5c6eab6c2fb370de45d582d5 + name: perl-JSON-PP + evr: 1:4.06-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Locale-Maketext-1.29-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 68578 + checksum: sha256:eb34611f4a8b295e9ba09f63b102db48b152e4915f90d9a9c33dba6e3331b3ed + name: perl-Locale-Maketext + evr: 1.29-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-MIME-Base64-3.16-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 43653 + checksum: sha256:b48266a93fef844c4b3ee3ff3d61df0cc497558b12e2b7be9e8a87fd3bd3a88b + name: perl-MIME-Base64 + evr: 3.16-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-MIME-Charset-1.012.2-15.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 68860 + checksum: sha256:375a66d8aadbde800a204d0681df4b0146dbd2cbcca577762162708d772095f4 + name: perl-MIME-Charset + evr: 1.012.2-15.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-MRO-Compat-0.13-15.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 21684 + checksum: sha256:145780b93fce797e44ceb5911d79d150830ef976551d2a2dea4a64368002cd59 + name: perl-MRO-Compat + evr: 0.13-15.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Math-BigInt-1.9998.18-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 3013100 + checksum: sha256:6dc7b0f22726602de1368de52d7f4eae6c5144971ba6bf9dd6fe17a293f8da6d + name: perl-Math-BigInt + evr: 1:1.9998.18-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Math-BigInt-FastCalc-0.500.900-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 2419116 + checksum: sha256:b1221f5ccb5a07e8f87ba1397e17eea89ae9d9e152a724feb666985e76738e45 + name: perl-Math-BigInt-FastCalc + evr: 0.500.900-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Math-BigRat-0.2614-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 62659 + checksum: sha256:9e90c3abafc7b3b556ba1e1054834d95c79b698d4d72d31ad0d846ce9f8ba166 + name: perl-Math-BigRat + evr: 0.2614-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Module-Build-0.42.31-9.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 321930 + checksum: sha256:203f542dbb18437a7d0f30cfc819eb2b719f191b3a4e2b0456f20a291f68a0da + name: perl-Module-Build + evr: 2:0.42.31-9.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Module-CoreList-5.20240609-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 139931 + checksum: sha256:f40d3b1814a4a9d35a071732892b188cfe5ca7546f477944fb54b8ddc19676a5 + name: perl-Module-CoreList + evr: 1:5.20240609-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Module-Load-0.36-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 20494 + checksum: sha256:d48889d7e5f4606b8de8d7886988274da466b047cb2434dc91bfe4d4339d1e24 + name: perl-Module-Load + evr: 1:0.36-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Module-Load-Conditional-0.74-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 26054 + checksum: sha256:69741f661710264f9aa8d97cdbde828b80323503bfa7da5c91330987a00d89ba + name: perl-Module-Load-Conditional + evr: 0.74-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Module-Metadata-1.000037-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 65016 + checksum: sha256:f3816981e19fb56a34bf13f1e288c01ef18613693bae505aa5ee0dc372d7aad1 + name: perl-Module-Metadata + evr: 1.000037-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Module-Signature-0.88-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 113588 + checksum: sha256:2777705793dd0cf55ac736f06632c02a93c47e5ef38c5eb0cd7603c3f2c76ec1 + name: perl-Module-Signature + evr: 0.88-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Mozilla-CA-20200520-6.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 151174 + checksum: sha256:488e0f8b1f3d167a5eb3c0156045adea8d1dbe668b24c83b988fa42250690b0d + name: perl-Mozilla-CA + evr: 20200520-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Net-Ping-2.74-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 70563 + checksum: sha256:e4a27ae525d6bf274e4f1612f3c5dc81e4557467bda40bd63ce8e5723e00a8cb + name: perl-Net-Ping + evr: 2.74-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Net-SSLeay-1.94-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 693539 + checksum: sha256:f31ac8a6104047329d21a8594231b8966eada47009adc44737771dad0e4286df + name: perl-Net-SSLeay + evr: 1.94-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Object-HashBase-0.009-7.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 32480 + checksum: sha256:5e8e5fb82b0a685c85f86490924ea1e0e3ac6364b07f43e087175d3f587c0e64 + name: perl-Object-HashBase + evr: 0.009-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Package-Generator-1.106-23.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 29367 + checksum: sha256:6a5be4bb4322abe97c45c84cb26368b594b9d90a7e66d4841b74d179ecd72c9a + name: perl-Package-Generator + evr: 1.106-23.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Params-Check-0.38-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 23416 + checksum: sha256:aa052e7b8c96f6c4610ab34686928f0f7adbb41044e29378620e3d5e827cce76 + name: perl-Params-Check + evr: 1:0.38-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Params-Util-1.102-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 207956 + checksum: sha256:a7eb296be9dc11401756128d84ae57a6e2e98fd0231cb5a52d7e86d42153ee56 + name: perl-Params-Util + evr: 1.102-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-PathTools-3.78-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 141038 + checksum: sha256:3457f843826ffa381deea36e926b9c89e78b024bb0d7877d3eaf0ce9af414d1d + name: perl-PathTools + evr: 3.78-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Perl-OSType-1.010-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 32465 + checksum: sha256:dd1ff7c7ef5ad251b1af9029f0555b4d21f3d96dd589ebb0d5989bd185f9abed + name: perl-Perl-OSType + evr: 1.010-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-PerlIO-via-QuotedPrint-0.09-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 24579 + checksum: sha256:d06492c280011cd128a3e84fe071584470de288053375da173a6304ebafc0e87 + name: perl-PerlIO-via-QuotedPrint + evr: 0.09-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Pod-Checker-1.74-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 35413 + checksum: sha256:ce262ff36c0f737cd181b4e8974ded778cffcc6a6ca949b98b716e2a822b41fe + name: perl-Pod-Checker + evr: 4:1.74-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Pod-Escapes-1.07-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 22192 + checksum: sha256:278a6249918084e23053e4847fd00c417de61ecf551ae11c6eaca2068b136ded + name: perl-Pod-Escapes + evr: 1:1.07-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Pod-Perldoc-3.28.01-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 225409 + checksum: sha256:5ee087f47aa3f1f317069a5c5914f78caea706b0c5690baf6245c5fc9579d71a + name: perl-Pod-Perldoc + evr: 3.28.01-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Pod-Simple-3.42-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 318605 + checksum: sha256:0519c7d5391807d300f0490e57ef0402a6831f6820045f6faec44c60b47e110c + name: perl-Pod-Simple + evr: 1:3.42-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Pod-Usage-2.01-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 91508 + checksum: sha256:82e3309aa8a5b9967dd1bdae4c0e3855e91722244bec647cc95499709aec7bc9 + name: perl-Pod-Usage + evr: 4:2.01-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Scalar-List-Utils-1.56-462.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 187594 + checksum: sha256:2b9117c65c6939ee02a54d235897441f826ec331eec1db4b674f37e06fc6638a + name: perl-Scalar-List-Utils + evr: 4:1.56-462.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Socket-2.031-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 57721 + checksum: sha256:cbd4a46e548d84325929c4fc205c20239359f1562729281247265d780fd375ad + name: perl-Socket + evr: 4:2.031-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Software-License-0.103014-12.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 135074 + checksum: sha256:27c65fae4f13a24c6e3634b70f39b439bf5b90b8892b2987d4498dbb4ba2780f + name: perl-Software-License + evr: 0.103014-12.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Storable-3.21-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 225886 + checksum: sha256:ec9eda9094c07d88067eda454000dfd55465b9dcc3f675599df828044317aa63 + name: perl-Storable + evr: 1:3.21-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Sub-Exporter-0.987-27.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 59528 + checksum: sha256:a552bfe187044ae29d0dc667e6e0a29c6340bf308d32d4b0c902f19d124e2c39 + name: perl-Sub-Exporter + evr: 0.987-27.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Sub-Install-0.928-28.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 30662 + checksum: sha256:224662bdabe9c803615622a3adcb891165ddcdc3eb58aedfed1789576f9048f1 + name: perl-Sub-Install + evr: 0.928-28.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Sys-Syslog-0.36-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 97885 + checksum: sha256:8f3db804c924748fc7f7f3a10e093bd1195661657a404ab102a9c1fbb8fe5cb4 + name: perl-Sys-Syslog + evr: 0.36-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Term-ANSIColor-5.01-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 69123 + checksum: sha256:40014939aeafb292b2baea665a8a3b1ee227dac7ecaac540c5fb537a6f8c3824 + name: perl-Term-ANSIColor + evr: 5.01-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Term-Cap-1.17-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 23367 + checksum: sha256:52658f861201f1947d07040968098fa9d31433c46bb8b38cd33ca2cd1fdb3b67 + name: perl-Term-Cap + evr: 1.17-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Term-Size-Any-0.002-35.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 15436 + checksum: sha256:f9aa001a28f500b09632dc321a4b46780f0cd02aa02ac8de8529684960fea05f + name: perl-Term-Size-Any + evr: 0.002-35.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Term-Size-Perl-0.031-12.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 24324 + checksum: sha256:c0283217d4d0998f3c2b24f42d956de7bc0c0c41478f40bdf6ef868748e003ec + name: perl-Term-Size-Perl + evr: 0.031-12.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Term-Table-0.015-8.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 42326 + checksum: sha256:a51423376f857f9720d3ad0e706db782758ac19bc3a28a0feaba80442ea7bd81 + name: perl-Term-Table + evr: 0.015-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-TermReadKey-2.38-11.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 98184 + checksum: sha256:d4f5da01fc7692c6b65a9cd180c7cc05f29163b4b580ef06118f3246621ee228 + name: perl-TermReadKey + evr: 2.38-11.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Test-Harness-3.42-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 226770 + checksum: sha256:9c62f68a4bb3b0c1e6fbdfbbf2a840e50d93e1f6e0f8936931153725e0593c53 + name: perl-Test-Harness + evr: 1:3.42-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Test-Simple-1.302183-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 355537 + checksum: sha256:9b4b7c9a1a8723a1d4c1c353060ddb7f57e48343552506af10066d9ebaed37e6 + name: perl-Test-Simple + evr: 3:1.302183-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Text-Balanced-2.04-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 52612 + checksum: sha256:41dca789e663140111944d257574c4eaa74b66d6169f256a9ffe407fa8070d27 + name: perl-Text-Balanced + evr: 2.04-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Text-Diff-1.45-13.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 41875 + checksum: sha256:df1478044a0c7fb575b1324c0e9311a51e883ca61ff39952d0042ee1b2eb5fd1 + name: perl-Text-Diff + evr: 1.45-13.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Text-Glob-0.11-15.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 16200 + checksum: sha256:9aa6c8502f05a42e5048063c2aff09e15cf8a44f6d00b3f8f154e58f051ff4cc + name: perl-Text-Glob + evr: 0.11-15.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Text-ParseWords-3.30-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 18773 + checksum: sha256:68425a0a7b9566b14abb56211c43f55146ac20c70a6dc69f983729505c94379c + name: perl-Text-ParseWords + evr: 3.30-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Text-Tabs+Wrap-2013.0523-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 30727 + checksum: sha256:e3728f77c64a1dc3edae34554fdcb1f6c940b54f665c8529b730f4afff6f1543 + name: perl-Text-Tabs+Wrap + evr: 2013.0523-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Text-Template-1.59-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 62651 + checksum: sha256:71bd67c547eec1d910a9c549be0ed7959a0f8e52a09e37d000a76bab1fd73cd3 + name: perl-Text-Template + evr: 1.59-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Thread-Queue-3.14-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 27710 + checksum: sha256:d844642772b9a505fc9bd5aaf94b597f1cf66ba2a890462f33f0fa226ccde79b + name: perl-Thread-Queue + evr: 3.14-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Tie-RefHash-1.40-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 43611 + checksum: sha256:d21a4a6ac093c7622f28c5ac2bd6aa7fae86c5b4c150249d9ca696b5461f3f6a + name: perl-Tie-RefHash + evr: 1.40-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Time-HiRes-1.9764-462.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 124567 + checksum: sha256:c9e00767aec7da2661ca2785530bc7f35c120e7411cfcd6889437c20add7ade1 + name: perl-Time-HiRes + evr: 4:1.9764-462.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Time-Local-1.300-7.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 54755 + checksum: sha256:f9d3745fb10235d5097536f81976f8234921de7a5c4b5cd599aa2b790f4ad18b + name: perl-Time-Local + evr: 2:1.300-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-URI-5.09-3.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 123780 + checksum: sha256:20fa38e20285da9712b42fdb9a5dffbc72644c4d608db827e2a10e9d8055dce2 + name: perl-URI + evr: 5.09-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Unicode-Collate-1.29-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 915935 + checksum: sha256:9f5cd2c294c8f4383e9d6d8ea9b7e2c2a1e913c5a27d39e041885548a570dff4 + name: perl-Unicode-Collate + evr: 1.29-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Unicode-LineBreak-2019.001-11.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 320828 + checksum: sha256:52d4dd85581dfa68c432cab3bde847ee4f62285bbc18ee04fdd5fc5e87dd9a2d + name: perl-Unicode-LineBreak + evr: 2019.001-11.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-Unicode-Normalize-1.27-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 55458 + checksum: sha256:514286df911a40dad2269810466a25279f07d2efab97db7479de337cfcedd971 + name: perl-Unicode-Normalize + evr: 1.27-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-autodie-2.34-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 106197 + checksum: sha256:82f0f75aaf2ac269983fc0c5a4a8c436e0382963ea15dd3e6b1b983865a6ae9b + name: perl-autodie + evr: 2.34-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-bignum-0.51-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 40019 + checksum: sha256:065483710b985ef93e23a0a9d69826d777ac3b3580429b011ecc1db4b03f6f8d + name: perl-bignum + evr: 0.51-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-constant-1.33-461.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 32045 + checksum: sha256:c68aeb1a1dbcf82f3be9b0b23a8fcbaaa9083d46328a76b6646af5412eaeedca + name: perl-constant + evr: 1.33-461.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-experimental-0.022-6.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 24159 + checksum: sha256:72d8e178ae3d2c2607e9ac4875957f841af9511398ddf07279b5e02a0e38034c + name: perl-experimental + evr: 0.022-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-inc-latest-0.500-20.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 28925 + checksum: sha256:3ac7d9dbcf90cfa75334d84853688e714b67a2982e4c9a33afac0ea4f79b1fb4 + name: perl-inc-latest + evr: 2:0.500-20.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-libnet-3.13-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 110461 + checksum: sha256:e473459e582b0cf07d4ecb9c7045547ad3543b24b5796f06ff8b42184d4a0fad + name: perl-libnet + evr: 3.13-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-local-lib-2.000024-13.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 78260 + checksum: sha256:4f60f5abc65be4e926262251a0a8d6ed0a86ac650dba678411b148c6a4ea34fd + name: perl-local-lib + evr: 2.000024-13.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-parent-0.238-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 23463 + checksum: sha256:cb61d28f218c1b1f51be254fa0282270b54fb051e4a164e7937411d7023d8c66 + name: perl-parent + evr: 1:0.238-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-perlfaq-5.20210520-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 212379 + checksum: sha256:9d33eccd67de62a9793105ef005f4865af5d931471697c9aaf4fd6e2f3da3a16 + name: perl-perlfaq + evr: 5.20210520-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-podlators-4.14-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 150048 + checksum: sha256:71e7c3e0eb8d62e314cf45b89d5be318ddb507399a96018079dd5fffe2b18de9 + name: perl-podlators + evr: 1:4.14-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-srpm-macros-1-41.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 10651 + checksum: sha256:05990bf148e58515223b0936ee7b621e5d39bb875e2481a4d84522bd4b57d4e3 + name: perl-srpm-macros + evr: 1-41.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-threads-2.25-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 130514 + checksum: sha256:92008f60b397b2e4380eddfe58aa788f78245a8fc44352d68bfa324fbec46655 + name: perl-threads + evr: 1:2.25-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-threads-shared-1.61-460.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 119822 + checksum: sha256:1b348ea3a479412c1236b95dc2d5d651a42e1c144626c38b8c08ef190b0c137b + name: perl-threads-shared + evr: 1.61-460.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/perl-version-0.99.28-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 180220 + checksum: sha256:123e4f54296116246dfd22b4c6628fab4537c62c8a95394194085e6f60b3763c + name: perl-version + evr: 7:0.99.28-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/pixman-0.40.0-6.el9_3.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 647633 + checksum: sha256:0bd62940984b88bfd5914463d948999e29665450e6850ad5c9c4fbc129f3c3d0 + name: pixman + evr: 0.40.0-6.el9_3 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/pyproject-rpm-macros-1.16.2-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 289973 + checksum: sha256:cb7775937762f5ab13165854b5fab8d1e1ea8003451ccb02faaf60b4590c1949 + name: pyproject-rpm-macros + evr: 1.16.2-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python-rpm-macros-3.9-54.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 32761 + checksum: sha256:b48fc9a942da394ad4cefd19dd2ebf4c5839d0267a41c797fb04dc6173b5f296 + name: python-rpm-macros + evr: 3.9-54.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-3.11.11-2.el9_6.2.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 20172726 + checksum: sha256:6bab124a4aae66c56d8e1e8ec13cf73daabd6e4a26285720df1b0ca010dc8848 + name: python3.11 + evr: 3.11.11-2.el9_6.2 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-charset-normalizer-2.1.0-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 95122 + checksum: sha256:40eb84c10d4c782c4b94521fd6da46571089b3469929a01070c86f088b7ed8be + name: python3.11-charset-normalizer + evr: 2.1.0-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-idna-3.4-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 189422 + checksum: sha256:e10ade754bd9cb27bfe035a261ba687e7d241abe05030b07a3eacf167881f9f1 + name: python3.11-idna + evr: 3.4-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-pip-22.3.1-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 9344698 + checksum: sha256:5bf6cb4965960cdb7f0191426f26acb9d08f207259c5b3cb1a9ee5bbc42f719b + name: python3.11-pip + evr: 22.3.1-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-pysocks-1.7.1-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 287308 + checksum: sha256:445ccd059e048dc740336ef765e8397bef4492774e7b5c318cd756d8e217f51d + name: python3.11-pysocks + evr: 1.7.1-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-requests-2.28.1-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 4048621 + checksum: sha256:ef21d050c9239587a3d0e3640a036554bc9a94716c2319fbd98039419010ed9b + name: python3.11-requests + evr: 2.28.1-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-setuptools-65.5.1-4.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 2631332 + checksum: sha256:68d30af3e04b3b482217b1d0cc48b59329da592fc9fc0c10fe5242cff18340fd + name: python3.11-setuptools + evr: 65.5.1-4.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-six-1.16.0-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 44753 + checksum: sha256:29cec169e93ff35fa41d958a61e4b7bef874ee2ea77c3080aefa8f2ea121e5e9 + name: python3.11-six + evr: 1.16.0-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/p/python3.11-urllib3-1.26.12-5.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 289008 + checksum: sha256:6874e5f1a06de82f23178bcec7902c78ebc3fa94a84b608f4f09e5ce9c93fb4e + name: python3.11-urllib3 + evr: 1.26.12-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/q/qt5-5.15.9-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 13771 + checksum: sha256:149c54e64307cb3da96287a068f09c4ea5d3968bf2ba088383069f294695cc6d + name: qt5 + evr: 5.15.9-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/r/redhat-rpm-config-209-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 96708 + checksum: sha256:a6f4aa2f37f5c6205cca36ea99c640c6509587aa29732a3e145d7c3af304868f + name: redhat-rpm-config + evr: 209-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/r/rust-srpm-macros-17-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 35132 + checksum: sha256:dfb94bc23f8c1be02f7d94e4b6d6dc05e98c7d4a162f5ef64f407bf6af738d42 + name: rust-srpm-macros + evr: 17-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/s/scl-utils-2.0.3-4.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 51970 + checksum: sha256:af49314f37d7414b3c214b0a85d7adbbbf74d4b8d7eb7bc5bc38ee869c951726 + name: scl-utils + evr: 1:2.0.3-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/s/sgml-common-0.6.3-58.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 111961 + checksum: sha256:ca6fe92503402d24ebc976123288ec2169e75632bd63dd1c146e8d310eb5ee01 + name: sgml-common + evr: 0.6.3-58.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/s/skopeo-1.18.1-2.el9_6.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 10643546 + checksum: sha256:1903a01e852401b8f0949fd1292da3c4e54816472a51ce6471e7704efbba1aac + name: skopeo + evr: 2:1.18.1-2.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/s/slirp4netns-1.3.2-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 76240 + checksum: sha256:9f048c86095d12608596b30fc60180fd0cc5ae4f4e5c25d26567f82b15cafede + name: slirp4netns + evr: 1.3.2-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/s/sombok-2.4.0-16.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 318398 + checksum: sha256:5f192b4d26bb9550982e644248f675017ec3d85af2fc721c6509c329c6e1c2bc + name: sombok + evr: 2.4.0-16.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/s/systemtap-5.2-2.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 6601838 + checksum: sha256:82d6c1b0bd2514e8879c01c265f99359168a8bd503f4c5bc8af69a3f74e2e184 + name: systemtap + evr: 5.2-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/w/wayland-1.21.0-1.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 239785 + checksum: sha256:f26f7fc3c60e1c5fe67abd6b6a0c26bb435e869f8451f092805eafe440b23172 + name: wayland + evr: 1.21.0-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/x/xkeyboard-config-2.33-2.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 1768610 + checksum: sha256:fc472164cec4c2e4794081a476f00448bc8defadb7a863d079d4a782ba1f23c7 + name: xkeyboard-config + evr: 2.33-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/appstream/source/SRPMS/Packages/y/yajl-2.1.0-25.el9.src.rpm + repoid: ubi-9-for-x86_64-appstream-source-rpms + size: 101373 + checksum: sha256:08182ae11608d0ad5d9ef01c558a39489f331fe449f9be6df1a91c5e950163f9 + name: yajl + evr: 2.1.0-25.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/a/acl-2.3.1-4.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 535332 + checksum: sha256:cb449bc6c85e0b50fa0bb98c969ff8481fee40517d8ebec5e28b72e5360fbe1e + name: acl + evr: 2.3.1-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/a/attr-2.5.1-3.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 482234 + checksum: sha256:5171534e7de11df197f3c5e08658544983198288e04624c739b5c3d9db07b59c + name: attr + evr: 2.5.1-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/a/avahi-0.8-22.el9_6.1.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1629705 + checksum: sha256:8e0cd07caf638b2d935ecc76fecc8d77adf5e399dbfb48958eacacb395b013d9 + name: avahi + evr: 0.8-22.el9_6.1 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/b/binutils-2.35.2-63.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 22426920 + checksum: sha256:7e8e6c0116f7e862225990df4faaa664fe3b86198538cd350f01b3e5bd16cf41 + name: binutils + evr: 2.35.2-63.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/b/brotli-1.0.9-7.el9_5.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 498766 + checksum: sha256:0c54d337221bca2bfeafaa7ce372aed7a2fcdb1f800be609ed8579bc1187bcd4 + name: brotli + evr: 1.0.9-7.el9_5 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/c/cracklib-2.9.6-27.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 6414228 + checksum: sha256:56a815a100d75c1d42c07090b632f05e51ea6d17df097d2936ab25d9aca49310 + name: cracklib + evr: 2.9.6-27.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/c/crypto-policies-20250128-1.git5269e22.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 102787 + checksum: sha256:0f6081ad96e9d7cb80aa18736e3a06bbf7d2c19bdc0f95a707a4f3ed0926b878 + name: crypto-policies + evr: 20250128-1.git5269e22.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/c/cups-2.3.3op2-33.el9_6.1.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 8125712 + checksum: sha256:d47b1ed7a8374a9881475617f7d1779e73960fbdc5a1402fd1327a144de06136 + name: cups + evr: 1:2.3.3op2-33.el9_6.1 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/d/dbus-1.12.20-8.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 2143916 + checksum: sha256:3fe74a2b4fb4485c93e974010d9376e30a63dfcc628bfd6c01837c27b4953912 + name: dbus + evr: 1:1.12.20-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/d/dbus-broker-28-7.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 254475 + checksum: sha256:aced3097fbb8a424ca1816b8cb3e79960a9ccf7ba139538282886e692c317b29 + name: dbus-broker + evr: 28-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/d/dbus-python-1.2.18-2.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 604976 + checksum: sha256:c1af733518b6d651fb1c80c65a852611ddaf250a4e8ef17b5a1defa7bba6211a + name: dbus-python + evr: 1.2.18-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/d/diffutils-3.7-12.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1477522 + checksum: sha256:7a10e2d961f8d755f8ccf51a1fb7f68687671b82d9486e4b8d648561af1a185e + name: diffutils + evr: 3.7-12.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/d/dmidecode-3.6-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 82438 + checksum: sha256:36383b31f643c92b47d960c473ed2196f5ae0682de67d1fd88d2d2ee47afe2e8 + name: dmidecode + evr: 1:3.6-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/d/dnf-4.14.0-25.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 2209081 + checksum: sha256:aedf694415ee951a80c681e684deb023ce162ac93dfcdf43cc1c406251a45333 + name: dnf + evr: 4.14.0-25.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/d/dnf-plugins-core-4.3.0-20.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 549118 + checksum: sha256:5ce98bd128f106adbc45e541a5b2e9d7c0317efddd15c1762f0e2ccad724799d + name: dnf-plugins-core + evr: 4.3.0-20.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/e/elfutils-0.192-6.el9_6.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 11944670 + checksum: sha256:afe7c9bef952ed086637fe83ac77bfafa70bf2ba28c1d7aaa51a18c9a75146b6 + name: elfutils + evr: 0.192-6.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/e/environment-modules-5.3.0-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1683625 + checksum: sha256:bb8384e5542c6aaa65aed2a1b823f67b9b4f542ca0683792eca29bc704a2c3c5 + name: environment-modules + evr: 5.3.0-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/e/expat-2.5.0-5.el9_6.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 8369732 + checksum: sha256:736df300c50aad5de613ee8322bedb9522042024a95df9c886089e225bc764f7 + name: expat + evr: 2.5.0-5.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/f/file-5.39-16.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1003666 + checksum: sha256:e8261cbcd55b85efdcd12ce1a2c6e63a72c64c872d618de4ba24557a1fda63c0 + name: file + evr: 5.39-16.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/f/fonts-rpm-macros-2.0.5-7.el9.1.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 50762 + checksum: sha256:6da7d722d419e6e9ce5abb4f6adcb82613d0629261011ec42134cfe092078e83 + name: fonts-rpm-macros + evr: 1:2.0.5-7.el9.1 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/f/freetype-2.10.4-10.el9_5.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 4767581 + checksum: sha256:b5f1bbbd25b22e01fc2508188b49a97fdf5f72d069039358cb5837dffcf9f2c1 + name: freetype + evr: 2.10.4-10.el9_5 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/f/fuse3-3.10.2-9.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 799367 + checksum: sha256:ddfcd07bcdcc07bdabe0f05b2c5c3bb1d6582af9c6b127632dd74f8ca78d56c9 + name: fuse3 + evr: 3.10.2-9.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/g/gcc-11.5.0-5.el9_5.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 81877102 + checksum: sha256:ed35dd39cd89aec444199a916667169638150fd12199dbb3c3d2638e43121565 + name: gcc + evr: 11.5.0-5.el9_5 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/g/gettext-0.21-8.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 9750918 + checksum: sha256:1b4dc42c4afa9d998cd13750e0aa73e0d3a16f6792bfc5e17d39aabd9c68426d + name: gettext + evr: 0.21-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/g/glibc-2.34-168.el9_6.23.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 19844337 + checksum: sha256:2495e3b229885e01ffd5dec87ea83d52022235c081e8fb19f6744a9e821b044f + name: glibc + evr: 2.34-168.el9_6.23 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/g/gpgme-1.15.1-6.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1737968 + checksum: sha256:ceeb7d42bc8ddf6f09013439bfed4e591411b81293fe3db5e4edb06cbe1879fb + name: gpgme + evr: 1.15.1-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/g/graphite2-1.3.14-9.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 6312801 + checksum: sha256:5e2022500d0c9129817bb77916e6b55375344ed2737e05cc82e0f53f295cf2d6 + name: graphite2 + evr: 1.3.14-9.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/g/groff-1.22.4-10.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 4138121 + checksum: sha256:16d1628338ede3c55a795782f05848112d47816ba073978af6fcd90ecce08f5c + name: groff + evr: 1.22.4-10.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/g/gzip-1.12-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 856147 + checksum: sha256:a05f582ec42e89258ee5e10af96dee4300bcb2a6a69a76bfb5b46f79e6a6a47b + name: gzip + evr: 1.12-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/h/harfbuzz-2.7.4-10.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 9551851 + checksum: sha256:d0ea2d865c05da90d7a32c6ad835bc3ba2067e759aaec2b0ca94a148735e43f8 + name: harfbuzz + evr: 2.7.4-10.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/h/hwdata-0.348-9.18.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 2508307 + checksum: sha256:af6cdae99470d14fa48057ac70a01cc8ab8567577eb74fc8c8be32ac080ad0ba + name: hwdata + evr: 0.348-9.18.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/i/ima-evm-utils-1.5-3.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 174698 + checksum: sha256:3f3bbe8ce7fd448357d30297adb3689869f498644258ed15c30160c021798555 + name: ima-evm-utils + evr: 1.5-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/i/iproute-6.11.0-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 937429 + checksum: sha256:11bfd8c1de1c26b8510340b467a933a800134d2e6e6f58a215d729a0727eee58 + name: iproute + evr: 6.11.0-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/k/keyutils-1.6.3-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 150790 + checksum: sha256:6afa567438acd0d3a6a66bc6a3c68ec2f4ae5ed9c7230c3f0478d2281a092688 + name: keyutils + evr: 1.6.3-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/k/kmod-28-10.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 582431 + checksum: sha256:28b89be6334167a3a6b3d73c82c11301e1ca065c853b18509eca456c4ee06508 + name: kmod + evr: 28-10.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/less-590-5.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 385311 + checksum: sha256:345830f76771e7e7a6b2a7af0b0374d2c39d970de4578379070aed36fd59d4bb + name: less + evr: 590-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libarchive-3.5.3-6.el9_6.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 7047682 + checksum: sha256:4e936a7bb7e593fab81247b88b97fc07a03bf24c4c3ed8188060dcf7af83b348 + name: libarchive + evr: 3.5.3-6.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libbpf-1.5.0-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 143177750 + checksum: sha256:ee50dc55ea737d1d7969b07da6b02fc093fbbc533498649570b08b3fa9caaa90 + name: libbpf + evr: 2:1.5.0-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libcbor-0.7.0-5.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 276760 + checksum: sha256:0fe4d1387cdb9c79ee26a6677df578b4d30facf4afa06cfa674fb686c3fa754a + name: libcbor + evr: 0.7.0-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libcomps-0.1.18-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 3723982 + checksum: sha256:65158204d46f288501cd32c6ba3dc23341d07d0fd20fa8022ee36744ea295f70 + name: libcomps + evr: 0.1.18-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libdb-5.3.28-57.el9_6.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 35290920 + checksum: sha256:6a74a3d96bd4657659524050945e2a47e93779addf2de374a13e1baf32b4ab8d + name: libdb + evr: 5.3.28-57.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libdnf-0.69.0-13.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1246710 + checksum: sha256:016b19eb7dd7f3db1dc05425631432952e360462d57af4c30d6ea010a86f756a + name: libdnf + evr: 0.69.0-13.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libeconf-0.4.1-4.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 201501 + checksum: sha256:4541a0915eca1e6fd1440253cf6bdfc5482c7b6dd3d3c7310a77faf852b7671a + name: libeconf + evr: 0.4.1-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libedit-3.1-38.20210216cvs.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 531597 + checksum: sha256:067e19c3ad8c9254119e7918ef7d2af3c3d33d364d34016f4b65fb71eb1676b3 + name: libedit + evr: 3.1-38.20210216cvs.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libfido2-1.13.0-2.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 865138 + checksum: sha256:c3f125f8b3242600cc1013183930e990b4b791c0d6c6544bf371a28c7abfebe1 + name: libfido2 + evr: 1.13.0-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libmnl-1.0.4-16.el9_4.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 313835 + checksum: sha256:ebfb5c801e7a3a2b83b4c4612ea923b9dd155428e738ff52b03e8966b78d2c08 + name: libmnl + evr: 1.0.4-16.el9_4 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libnl3-3.11.0-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 5068824 + checksum: sha256:13f6ea90f26fbc96e3754584a576c03ca41221fc939164f5a7b6341a6372fd7a + name: libnl3 + evr: 3.11.0-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libpciaccess-0.16-7.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 382367 + checksum: sha256:1db6df2f1176960c34a4c87ee533b039ea2db8a2e2f1cb0312399a2ec5d37f8b + name: libpciaccess + evr: 0.16-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libpipeline-1.5.3-4.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1006052 + checksum: sha256:f1a40821328b6e3fd7264c78c18f8c2045e7a30a05ef9f8b2934d5ca15724ce3 + name: libpipeline + evr: 1.5.3-4.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libpng-1.6.37-12.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1527840 + checksum: sha256:41f1d58a05cafaa0e6e8cf82f5a3a0f00afa47a082f093364da7cc279576d2fc + name: libpng + evr: 2:1.6.37-12.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libpwquality-1.4.4-8.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 447225 + checksum: sha256:14fbf335e2c6f22b441a9750a69b7c41e197c4dd21adac701fd81f17660ee0b4 + name: libpwquality + evr: 1.4.4-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/librepo-1.14.5-2.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 831344 + checksum: sha256:96889cee62cfeea42671f21a5186ac36ae4f0bb80f6a3fa22e73d7de763c8384 + name: librepo + evr: 1.14.5-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libseccomp-2.5.2-2.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 653169 + checksum: sha256:43dd0fa2cd26306e2017704075e628bbe675c8731b17848df82f3b59337f1be8 + name: libseccomp + evr: 2.5.2-2.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libselinux-3.6-3.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 271153 + checksum: sha256:a08a84389665ef614eb6d9b06a53128eab89b650c799c0558f3ae04df97c4b13 + name: libselinux + evr: 3.6-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libtirpc-1.3.3-9.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 589716 + checksum: sha256:95d684042f4c5f63ac57923639fd1e7d6d278766b4ee99feb24baa5567fe4b7e + name: libtirpc + evr: 1.3.3-9.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libuser-0.63-16.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 827135 + checksum: sha256:8335200b5423b09ea0b11138e59f61df8bae6533b46c4fb28722eeccff7d26dd + name: libuser + evr: 0.63-16.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libutempter-1.2.1-6.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 30093 + checksum: sha256:e48843d2734fefad084a86165860ea9575bdc53f63bb5845d8807ce9ccb4f914 + name: libutempter + evr: 1.2.1-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/l/libxcrypt-4.4.18-3.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 543970 + checksum: sha256:d18f72eb41ecd0370e2e47f1dc5774be54e9ff3b4dd333578017666c7c488f40 + name: libxcrypt + evr: 4.4.18-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/m/make-4.3-8.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 2335546 + checksum: sha256:a5cc45d6c158b255cda528c496dbb8bc7783acb9898b97a39a1811230e102d7c + name: make + evr: 1:4.3-8.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/m/man-db-2.9.3-7.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1910721 + checksum: sha256:bc6830986c1500ac2a8cf36dd575e53731b0160be2bc208ab141c52c292ac54b + name: man-db + evr: 2.9.3-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/n/ncurses-6.2-10.20210508.el9_6.2.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 3587058 + checksum: sha256:2c3309af9b6637047a8dec3f7e84c03da6fa4ab9570d78cad92c045bfd0fa1e3 + name: ncurses + evr: 6.2-10.20210508.el9_6.2 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/o/openssh-8.7p1-45.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 2415807 + checksum: sha256:2cc10ea59a3685a9752db18962e69e87257a862bc283b7dd233d7ffdf2fa0281 + name: openssh + evr: 8.7p1-45.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/o/openssl-3.2.2-6.el9_5.1.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 17985138 + checksum: sha256:56c0b951be3e5ad6a1da594f9d4f09b8b752e2fb3d6827bcc03892f22f622b22 + name: openssl + evr: 1:3.2.2-6.el9_5.1 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/pam-1.5.1-26.el9_6.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1130406 + checksum: sha256:9a351f0455da788ff63026af9a8ee30e744017941c82283f970d1ed066000bb6 + name: pam + evr: 1.5.1-26.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/passwd-0.80-12.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 294731 + checksum: sha256:ee9ed53ab4bbea3f477855225c541f9e40e34fac54004872d57e9ddecbffd779 + name: passwd + evr: 0.80-12.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/pkgconf-1.7.3-10.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 310904 + checksum: sha256:4d53718592b298ca7c49665b1f4e7bd32dcb42cad15c89345585da9f20d4fcae + name: pkgconf + evr: 1.7.3-10.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/policycoreutils-3.6-2.1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 7982064 + checksum: sha256:3ee0c11e4cb602eb81993a8492688246c3d750bc0f592ba895dbce0aa734580a + name: policycoreutils + evr: 3.6-2.1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/procps-ng-3.3.17-14.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1054334 + checksum: sha256:acfd5c270ba5724a0f5f2a84cc47ee222d6a03095421fddbf6932375ec7d67f0 + name: procps-ng + evr: 3.3.17-14.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/protobuf-c-1.3.3-13.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 513224 + checksum: sha256:d4d82978c58a2f9ca8e24b953fd9ac74efee41572ec9649c4f2f183cda98b33f + name: protobuf-c + evr: 1.3.3-13.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/psmisc-23.4-3.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 386002 + checksum: sha256:9e65fd323b6c88f71e05576b931a10ba4bdce9314114ba88e436482efa77d6bd + name: psmisc + evr: 23.4-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/pygobject3-3.40.1-6.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 576452 + checksum: sha256:1ad25647ca3d35d691c4dc118cedc4bb82911ce6ccffdc648ca0eed21b2007a3 + name: pygobject3 + evr: 3.40.1-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-chardet-4.0.0-5.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1917985 + checksum: sha256:1088982b6cf2baa4aa11ed199f3cda785fe3002b3b7c5a74e9d65ba3969559b8 + name: python-chardet + evr: 4.0.0-5.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-dateutil-2.8.1-7.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 346032 + checksum: sha256:c99e212cb37d9266acd89f55807aef83bb1443b0afad21c9e6c9a0ea2b5fc75a + name: python-dateutil + evr: 1:2.8.1-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-decorator-4.4.2-6.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 45990 + checksum: sha256:a218b1f0d66b0d9d69624ec77a9eee8d476650b587574ffc9817af0891536cf7 + name: python-decorator + evr: 4.4.2-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-idna-2.10-7.el9_4.1.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 195340 + checksum: sha256:175a3c6c98d0e56721eef1237529c11c2caca4c6fbbc0d9c30c28489e014388b + name: python-idna + evr: 2.10-7.el9_4.1 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-iniparse-0.4-45.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 50707 + checksum: sha256:12ec23b9a41dc8e239d8bc76d70db8ab428ac6d472c49418a26c9068ce0a9d91 + name: python-iniparse + evr: 0.4-45.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-inotify-0.9.6-25.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 73889 + checksum: sha256:f75505a3d5d26682703ba38308a4e534149316f3a976abc73ac634d7191be0ff + name: python-inotify + evr: 0.9.6-25.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-pip-21.3.1-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 8984717 + checksum: sha256:cb9e0cca3bd8dc24798cf1fb333d574774ce8288598331d44994d768f33648d3 + name: python-pip + evr: 21.3.1-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-pysocks-1.7.1-12.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 289343 + checksum: sha256:31a68e258ececf1a34326a898bff562070721ed64a69c6f033defde4371766ee + name: python-pysocks + evr: 1.7.1-12.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-requests-2.25.1-10.el9_6.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 3751447 + checksum: sha256:24bc309d5ef2e9d6733a4247c880deac877088247de320d8f00d230864a477c5 + name: python-requests + evr: 2.25.1-10.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-setuptools-53.0.0-13.el9_6.1.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 2080099 + checksum: sha256:9cd7d11ed9e7fe2fa274de10d803f6fecd53cc1101bd0cbae386dbb66ce03824 + name: python-setuptools + evr: 53.0.0-13.el9_6.1 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-six-1.15.0-9.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 47236 + checksum: sha256:a13be570131c132697c1bdae9042ed20c0a1963db8d9037a5fdb90e80532a979 + name: python-six + evr: 1.15.0-9.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-systemd-234-19.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 68399 + checksum: sha256:c61068568df2e7e2f5623e7825a95ce27e7facf3f7415b56c7bd82ab97cbe102 + name: python-systemd + evr: 234-19.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python-urllib3-1.26.5-6.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 286060 + checksum: sha256:1710e562d5982b0035f987303e48a4ca87e437f3202a66ba259a94146fb4e282 + name: python-urllib3 + evr: 1.26.5-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/p/python3.9-3.9.21-2.el9_6.2.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 20294169 + checksum: sha256:9911695a9765085c3a6e72e929e9d9d8e78309823967e1f6dd7fb97696aa0d01 + name: python3.9 + evr: 3.9.21-2.el9_6.2 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/r/rpm-4.16.1.3-37.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 4490587 + checksum: sha256:b15a51773d702299bc9d83245544b60c8e733c0404f49e7badc5fa815449d151 + name: rpm + evr: 4.16.1.3-37.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/r/rsync-3.2.5-3.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1306931 + checksum: sha256:a1fd44e58d1fb5b52b72586c5ef2e12c040428f771cde1d1350b36d3b9155db0 + name: rsync + evr: 3.2.5-3.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/s/selinux-policy-38.1.53-5.el9_6.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1165990 + checksum: sha256:d2d67cbefde4402aaf8d4ea0e0820683f183d388c43c3bc7841beefceca1af68 + name: selinux-policy + evr: 38.1.53-5.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/s/shadow-utils-4.9-12.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1715281 + checksum: sha256:26fa86de6d2a5c08e93fc51ec4859635e74bcaec9480641bbb69cfce12ca21ab + name: shadow-utils + evr: 2:4.9-12.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/s/subscription-manager-1.29.45.1-1.el9_6.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1977838 + checksum: sha256:a04fb8bbeea4190ee8a0b23ab2043649d8eca0a845de768b3adc365e66b2be76 + name: subscription-manager + evr: 1.29.45.1-1.el9_6 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/s/subscription-manager-rhsm-certificates-20220623-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 25124 + checksum: sha256:a814ce978afe85327fd03829047ce04181d5d3f76bad8cfe8d24adfbd9be38a2 + name: subscription-manager-rhsm-certificates + evr: 20220623-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/s/systemd-252-51.el9_6.2.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 43219722 + checksum: sha256:6c70ed2f22b9db562555f5fa817669a31c685e60d758ad12529968a731c634b9 + name: systemd + evr: 252-51.el9_6.2 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/t/tcl-8.6.10-7.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 6000353 + checksum: sha256:cffe1533560f76cbddb6b75d0f76f8b7e98e975e911ae9873c80c0b386b40dfd + name: tcl + evr: 1:8.6.10-7.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/t/tpm2-tss-3.2.3-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1660943 + checksum: sha256:11c9b6951d6823d120d310243f500f78ce13f9e206134309692e4a761294f3b9 + name: tpm2-tss + evr: 3.2.3-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/u/unzip-6.0-58.el9_5.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1436757 + checksum: sha256:49de0234c5e8f588c94b435c35225bcccd4cc94bb19cac94110d9aa0c5060f69 + name: unzip + evr: 6.0-58.el9_5 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/u/usermode-1.114-6.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 311956 + checksum: sha256:83ef7f9db116529917b163f8c575968c27dbc12cc55f5128a7c6a9ba2b040f94 + name: usermode + evr: 1.114-6.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/u/util-linux-2.37.4-21.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 6281028 + checksum: sha256:cde2d6a98345d49de9d225fc3acf7542fb35fde32832f1361415486a7839c222 + name: util-linux + evr: 2.37.4-21.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/v/vim-8.2.2637-22.el9_6.1.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 12811310 + checksum: sha256:dd52d42c4fa9c93cbe2f48ebfd202ead2e44f75046162e999d402a2e33d52dd4 + name: vim + evr: 2:8.2.2637-22.el9_6.1 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/v/virt-what-1.27-1.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 565157 + checksum: sha256:89d192c8a955de5cafde424d031f2c4c3d481b14677104a6ed5fe4a7d322133c + name: virt-what + evr: 1.27-1.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/x/xz-5.2.5-8.el9_0.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1168293 + checksum: sha256:bce98f3a307e75a8ac28f909e29b41d64b15461fa9ddf0bf4ef3c2f6de946b46 + name: xz + evr: 5.2.5-8.el9_0 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/z/zip-3.0-35.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 1137410 + checksum: sha256:416b6957a4365204cfb2ba9e5b9b9f21075b615114c6afe46c83166de258bb5d + name: zip + evr: 3.0-35.el9 + - url: https://cdn-ubi.redhat.com/content/public/ubi/dist/ubi9/9/x86_64/baseos/source/SRPMS/Packages/z/zlib-1.2.11-40.el9.src.rpm + repoid: ubi-9-for-x86_64-baseos-source-rpms + size: 561153 + checksum: sha256:e47b884c132983fd0cc40c761de72e1a34ada9ee395cfe50997f9fb9257669d8 + name: zlib + evr: 1.2.11-40.el9 + module_metadata: [] diff --git a/scripts/check_package_yaml_consistency.py b/scripts/check_package_yaml_consistency.py new file mode 100755 index 0000000000..8ae6973763 --- /dev/null +++ b/scripts/check_package_yaml_consistency.py @@ -0,0 +1,282 @@ +import json +import yaml +import os +import sys +from pathlib import Path +from typing import Dict, List, Optional, Tuple + + +class PackageYamlChecker: + def __init__(self, repo_root: str): + self.repo_root = Path(repo_root) + self.dynamic_plugins_dir = self.repo_root / "dynamic-plugins" / "wrappers" + self.marketplace_dir = self.repo_root / "catalog-entities" / "marketplace" / "packages" + self.results = [] + + def find_package_json_files(self) -> List[Path]: + """Find all package.json files in dynamic-plugins/wrappers/""" + package_files = [] + for item in self.dynamic_plugins_dir.iterdir(): + if item.is_dir(): + package_json = item / "package.json" + if package_json.exists(): + package_files.append(package_json) + return package_files + + def extract_keywords_from_package_json(self, package_path: Path) -> Dict[str, str]: + """Extract support and lifecycle keywords from package.json""" + try: + with open(package_path, 'r') as f: + data = json.load(f) + + keywords = data.get('keywords', []) + result = {} + + for keyword in keywords: + if keyword.startswith('support:'): + result['support'] = keyword.replace('support:', '') + elif keyword.startswith('lifecycle:'): + result['lifecycle'] = keyword.replace('lifecycle:', '') + + return result + except Exception as e: + print(f"Error reading {package_path}: {e}") + return {} + + def find_corresponding_yaml(self, package_name: str) -> Optional[Path]: + """ + Find the corresponding YAML file for a package + Assisted-by: Cursor + """ + # First try exact match + yaml_file = self.marketplace_dir / f"{package_name}.yaml" + if yaml_file.exists(): + return yaml_file + + # If package name ends with -dynamic, try without the suffix + # This handles backend plugins where directory is name-dynamic but YAML is just name + if package_name.endswith('-dynamic'): + yaml_name_without_dynamic = package_name[:-8] # Remove '-dynamic' + yaml_file = self.marketplace_dir / f"{yaml_name_without_dynamic}.yaml" + if yaml_file.exists(): + return yaml_file + + # fuzzy: try prefix/suffix relations and common aliasing + # Assisted-by: Cursor - since the naming convention is not consistent + alias_name = package_name.replace('red-hat-developer-hub', 'rhdh') + for p in self.marketplace_dir.glob('*.yaml'): + stem = p.stem + if ( + stem.endswith(package_name) + or package_name.endswith(stem) + or stem.startswith(package_name) + or package_name.startswith(stem) + or stem == alias_name + or stem.startswith(alias_name) + or alias_name.startswith(stem) + ): + return p + + return None + + def extract_spec_from_yaml(self, yaml_path: Path) -> Dict[str, str]: + """Extract support and lifecycle from YAML spec""" + try: + with open(yaml_path, 'r') as f: + data = yaml.safe_load(f) + + spec = data.get('spec', {}) + result = {} + + if 'support' in spec: + result['support'] = spec['support'] + if 'lifecycle' in spec: + result['lifecycle'] = spec['lifecycle'] + + return result + except Exception as e: + print(f"Error reading {yaml_path}: {e}") + return {} + + def get_package_name_from_path(self, package_path: Path) -> str: + """Extract package name from the directory path""" + return package_path.parent.name + + def check_consistency(self, verbose: bool = False) -> None: + """Main method to check consistency between all package.json and YAML files""" + package_files = self.find_package_json_files() + + if verbose: + print(f"Found {len(package_files)} package.json files to check\n") + + for package_path in package_files: + package_name = self.get_package_name_from_path(package_path) + + # Extract keywords from package.json + json_keywords = self.extract_keywords_from_package_json(package_path) + + # Find and read corresponding YAML + yaml_path = self.find_corresponding_yaml(package_name) + + if not yaml_path: + self.results.append({ + 'package': package_name, + 'status': 'NO_YAML', + 'message': f"No corresponding YAML file found for {package_name}", + 'json_path': str(package_path), + 'yaml_path': None + }) + continue + + # Track if we used the -dynamic mapping + used_dynamic_mapping = package_name.endswith('-dynamic') and not (self.marketplace_dir / f"{package_name}.yaml").exists() + + yaml_spec = self.extract_spec_from_yaml(yaml_path) + + # Compare the values + issues = [] + + # Check support + json_support = json_keywords.get('support') + yaml_support = yaml_spec.get('support') + + if json_support != yaml_support: + issues.append(f"Support mismatch: JSON='{json_support}' vs YAML='{yaml_support}'") + + # Check lifecycle + json_lifecycle = json_keywords.get('lifecycle') + yaml_lifecycle = yaml_spec.get('lifecycle') + + if json_lifecycle != yaml_lifecycle: + issues.append(f"Lifecycle mismatch: JSON='{json_lifecycle}' vs YAML='{yaml_lifecycle}'") + + # Check for missing fields + if json_support is None and yaml_support is not None: + issues.append(f"Support missing in JSON but present in YAML: '{yaml_support}'") + if json_lifecycle is None and yaml_lifecycle is not None: + issues.append(f"Lifecycle missing in JSON but present in YAML: '{yaml_lifecycle}'") + if json_support is not None and yaml_support is None: + issues.append(f"Support present in JSON but missing in YAML: '{json_support}'") + if json_lifecycle is not None and yaml_lifecycle is None: + issues.append(f"Lifecycle present in JSON but missing in YAML: '{json_lifecycle}'") + + self.results.append({ + 'package': package_name, + 'status': 'MISMATCH' if issues else 'OK', + 'issues': issues, + 'json_keywords': json_keywords, + 'yaml_spec': yaml_spec, + 'json_path': str(package_path), + 'yaml_path': str(yaml_path), + 'used_dynamic_mapping': used_dynamic_mapping + }) + + def print_report(self, verbose: bool = False) -> None: + """ + Print a detailed report of the findings + Assisted-by: Cursor + """ + if verbose: + print("=" * 80) + print("PACKAGE.JSON vs marketplace catalog entity CONSISTENCY CHECK REPORT") + print("=" * 80) + + ok_count = 0 + mismatch_count = 0 + no_yaml_count = 0 + backend_plugin_count = 0 + frontend_plugin_count = 0 + backends_without_dynamic: List[str] = [] + + for result in self.results: + status = result['status'] + package_name = result['package'] + + # Count plugin types based on naming patterns + is_backend = ('-backend' in package_name) or package_name.endswith('-dynamic') + if is_backend: + backend_plugin_count += 1 + if not package_name.endswith('-dynamic'): + backends_without_dynamic.append(package_name) + else: + frontend_plugin_count += 1 + + if status == 'OK': + ok_count += 1 + elif status == 'MISMATCH': + mismatch_count += 1 + elif status == 'NO_YAML': + no_yaml_count += 1 + + print(f"\nSUMMARY:") + print(f"✅ Consistent packages: {ok_count}") + print(f"❌ Inconsistent packages: {mismatch_count}") + print(f"⚠️ Missing marketplace catalog entity files: {no_yaml_count}") + print(f"📁 Total packages checked: {len(self.results)}") + print(f"🔧 Backend/module plugins: {backend_plugin_count}") + print(f"🎨 Frontend plugins: {frontend_plugin_count}") + if verbose and backends_without_dynamic: + print(f"\n💡 Note: {len(backends_without_dynamic)} backend plugins without -dynamic suffix:") + for p in sorted(backends_without_dynamic): + print(f" - {p}") + + if mismatch_count > 0: + if verbose: + print(f"\n{'='*50}") + print("INCONSISTENT PACKAGES:") + print(f"{'='*50}") + + for result in self.results: + if result['status'] == 'MISMATCH': + print(f"\n📦 {result['package']}") + if verbose: + print(f" JSON: {result['json_path']}") + print(f" YAML: {result['yaml_path']}") + for issue in result['issues']: + print(f" ❌ {issue}") + + if no_yaml_count > 0: + if verbose: + print(f"\n{'='*50}") + print("MISSING marketplace catalog entity FILES:") + print(f"{'='*50}") + + for result in self.results: + if result['status'] == 'NO_YAML': + print(f"⚠️ {result['package']}") + + if verbose and ok_count > 0: + print(f"\n{'='*50}") + print("CONSISTENT PACKAGES:") + print(f"{'='*50}") + + for result in self.results: + if result['status'] == 'OK': + print(f"✅ {result['package']}") + + +def main(): + """Main function""" + # Get the repository root (assuming script is in scripts/ directory) + script_dir = Path(__file__).parent + repo_root = script_dir.parent + + if not (repo_root / "dynamic-plugins").exists(): + print("Error: Could not find dynamic-plugins directory. Make sure you're running from the correct location.") + sys.exit(1) + + parser = None + # add a lightweight flag without changing external callers + verbose = '--verbose' in sys.argv + checker = PackageYamlChecker(str(repo_root)) + checker.check_consistency(verbose=verbose) + checker.print_report(verbose=verbose) + + # Exit with error code if there are mismatches + mismatches = [r for r in checker.results if r['status'] == 'MISMATCH'] + if mismatches: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/scripts/generate-index-template.mjs b/scripts/generate-index-template.mjs new file mode 100644 index 0000000000..8d7a5c7af3 --- /dev/null +++ b/scripts/generate-index-template.mjs @@ -0,0 +1,43 @@ +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; +import { JSDOM } from "jsdom"; + +// __dirname replacement in ESM +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// Resolve dist directory relative to current working package +const distDir = path.resolve(process.cwd(), "dist"); +const publicDir = path.resolve(process.cwd(), "public"); +const publicFile = path.join(publicDir, "index.html"); +const distFile = path.join(distDir, "index.html"); +const tmplFile = path.join(distDir, "index.html.tmpl"); + +if (!fs.existsSync(publicFile)) { + console.error(`Missing ${publicFile}`); + process.exit(1); +} +if (!fs.existsSync(distFile)) { + console.error(`Missing ${distFile}`); + process.exit(1); +} + +// Read both files as raw text +const publicHtml = fs.readFileSync(publicFile, "utf-8"); +const distHtml = fs.readFileSync(distFile, "utf-8"); + +// Use JSDOM to parse dist/index.html +const dom = new JSDOM(distHtml); +const document = dom.window.document; + +// Extract all