Skip to content

feat(x2a): change the project to be source-technology agnostic#2953

Open
mareklibra wants to merge 3 commits intoredhat-developer:mainfrom
mareklibra:FLPATH-3431.avoidExplicitChef
Open

feat(x2a): change the project to be source-technology agnostic#2953
mareklibra wants to merge 3 commits intoredhat-developer:mainfrom
mareklibra:FLPATH-3431.avoidExplicitChef

Conversation

@mareklibra
Copy link
Copy Markdown
Member

@mareklibra mareklibra commented Apr 29, 2026

Fixes: FLPATH-3431

Rephrasing all texts from being Chef-oriented to more generic variants.

There is newly explicit mapping from free-form agentic findings to the new SourceTechnology enum (normalizeSourceTechnology.ts). This became the input for the x2a-convertor parameter.

@rhdh-gh-app
Copy link
Copy Markdown

rhdh-gh-app Bot commented Apr 29, 2026

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-x2a workspaces/x2a/plugins/scaffolder-backend-module-x2a patch v0.3.1
@red-hat-developer-hub/backstage-plugin-x2a-backend workspaces/x2a/plugins/x2a-backend patch v1.4.2
@red-hat-developer-hub/backstage-plugin-x2a-common workspaces/x2a/plugins/x2a-common patch v1.2.1
@red-hat-developer-hub/backstage-plugin-x2a-node workspaces/x2a/plugins/x2a-node patch v0.2.2
@red-hat-developer-hub/backstage-plugin-x2a workspaces/x2a/plugins/x2a patch v1.2.2

@mareklibra mareklibra force-pushed the FLPATH-3431.avoidExplicitChef branch 2 times, most recently from 1be7a8b to a2241b1 Compare April 29, 2026 11:07
@mareklibra mareklibra marked this pull request as ready for review April 29, 2026 11:08
@mareklibra mareklibra force-pushed the FLPATH-3431.avoidExplicitChef branch from a2241b1 to 7930e25 Compare April 29, 2026 11:09
@@ -1,2 +1,2 @@
name,description,abbreviation,ownedByGroup,sourceRepoUrl,sourceRepoBranch,targetRepoUrl,targetRepoBranch
my-examples,Convert chef-examples to Ansible,mex,,https://github.com/x2ansible/chef-examples,main,https://github.com/my-converted-projects/my-examples,target
my-examples,Convert legacy config to Ansible,mex,,https://github.com/x2ansible/config-examples,main,https://github.com/my-converted-projects/my-examples,target
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should decide on a standard way for this. legacy config? legacy infra code? legacy sources?

/**
* @public
*/
export type SourceTechnology = 'chef' | 'puppet' | 'salt' | 'legacy-ansible';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

powershell?

Comment on lines +1181 to +1185
"enum": [
"chef",
"puppet",
"salt",
"legacy-ansible"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

powershell

Comment on lines +851 to +855
enum:
- chef
- puppet
- salt
- legacy-ansible
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

powershell

# Strip git tokens from files before committing to prevent secret leaks.
# The x2a tool may embed SOURCE_REPO_TOKEN in generated files (e.g., Policyfile.lock.json)
# when Chef resolves cookbook sources using authenticated URLs.
# when the source tool resolves dependencies using authenticated URLs.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the "source tool"?

# Usage: app.py init [OPTIONS] USER_REQUIREMENTS
# --source-dir DIRECTORY Source directory to analyze
USER_REQ="${USER_PROMPT:-Analyze the Chef cookbooks and create a migration plan}"
USER_REQ="${USER_PROMPT:-Analyze the source configuration and create a migration plan}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

source configurations? legacy config? see my comment above

/**
* @public
*/
export type SourceTechnology = 'chef' | 'puppet' | 'salt' | 'legacy-ansible';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

powershell

chef: ['chef'],
puppet: ['puppet'],
salt: ['salt', 'saltstack'],
'legacy-ansible': ['legacy-ansible', 'ansible'],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

powershell

type: string
enum:
- chef
- puppet
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would nto add yet chef or salt, it's not yet created

@mareklibra mareklibra force-pushed the FLPATH-3431.avoidExplicitChef branch from 7930e25 to 7f0b32b Compare April 30, 2026 08:54
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

❌ Patch coverage is 37.50000% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.72%. Comparing base (4522d8c) to head (48710fd).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2953      +/-   ##
==========================================
+ Coverage   57.12%   60.72%   +3.59%     
==========================================
  Files        2065     2066       +1     
  Lines       63363    63751     +388     
  Branches    16624    16631       +7     
==========================================
+ Hits        36199    38713    +2514     
+ Misses      25495    23537    -1958     
+ Partials     1669     1501     -168     
Flag Coverage Δ *Carryforward flag
adoption-insights 83.58% <ø> (ø) Carriedforward from 4522d8c
ai-integrations 69.58% <ø> (ø) Carriedforward from 4522d8c
app-defaults 69.60% <ø> (ø) Carriedforward from 4522d8c
augment 69.36% <ø> (ø) Carriedforward from 4522d8c
bulk-import 72.43% <ø> (ø) Carriedforward from 4522d8c
cost-management 16.49% <ø> (ø) Carriedforward from 4522d8c
dcm 32.85% <ø> (ø) Carriedforward from 4522d8c
extensions 61.42% <ø> (ø) Carriedforward from 4522d8c
global-floating-action-button 73.75% <ø> (ø) Carriedforward from 4522d8c
global-header 61.62% <ø> (ø) Carriedforward from 4522d8c
homepage 50.84% <ø> (ø) Carriedforward from 4522d8c
konflux 91.01% <ø> (ø) Carriedforward from 4522d8c
lightspeed 69.64% <ø> (ø) Carriedforward from 4522d8c
mcp-integrations 81.59% <ø> (ø) Carriedforward from 4522d8c
orchestrator 33.07% <ø> (ø) Carriedforward from 4522d8c
quickstart 62.64% <ø> (ø) Carriedforward from 4522d8c
sandbox 79.42% <ø> (ø) Carriedforward from 4522d8c
scorecard 83.61% <ø> (ø) Carriedforward from 4522d8c
theme 64.54% <ø> (ø) Carriedforward from 4522d8c
translations 8.49% <ø> (ø) Carriedforward from 4522d8c
x2a 81.92% <37.50%> (+63.91%) ⬆️

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4522d8c...48710fd. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread workspaces/x2a/docs/csv-bulk-import.md Outdated

1. Open the Backstage instance and navigate to `/create`.
2. Select the **Chef-to-Ansible Conversion Project** template (`chef-conversion-project-template`).
2. Select the **Legacy-to-Ansible Conversion Project** template (`x2a-conversion-project-template`).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Older versions of Ansible? Legacy sounds like we're understimated what it's doing.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was -to-.

But I missed that in the second round of rename, changing to Infrastructure Conversion Project now.

Comment thread workspaces/x2a/docs/csv-bulk-import.md Outdated
web-app,wapp,https://github.com/myorg/web-app-chef,main,https://github.com/myorg/web-app-ansible,main,Convert web app cookbook,team-platform
db-setup,dbset,gitlab.com?owner=myorg&repo=db-chef,develop,gitlab.com?owner=myorg&repo=db-ansible,main,,
cache-svc,cache,bitbucket.org?workspace=myws&project=x2a&repo=cache-chef,main,,main,Cache service conversion,
web-app,wapp,https://github.com/myorg/web-app-legacy,main,https://github.com/myorg/web-app-ansible,main,Convert web app configuration,team-platform
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep here the chef example to be honest, add a bit more "clear" context

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense, reverting

title: Chef-to-Ansible Conversion Project
description: Initiate a conversion of a Chef cookbook or directory into a new Ansible Playbook repository.
name: x2a-conversion-project-template
title: Legacy-to-Ansible Conversion Project
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Infraestructure conversion project?

/**
* @public
*/
export type SourceTechnology = 'chef' | 'legacy-ansible' | 'powershell';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use Ansible as we used in the types in the Input agent: https://github.com/x2ansible/x2a-convertor/blob/main/src/types/technology.py#L4

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, changing to ansible.

ansible is easier for using but our flow is about conversion older version to a newer one.

? [
{
name: 'SOURCE_TECHNOLOGY',
value: params.sourceTechnology,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be aware that you're using legacy-ansible, and we using ansible on input agents, the thing will break here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saying this, why this line is currently working is a totally unknown to me

run_x2a uv run app.py migrate \
--source-dir "${SOURCE_BASE}" \
--source-technology Chef \
--high-level-migration-plan "${PROJECT_PATH}/migration-plan.md" \
--module-migration-plan "${OUTPUT_DIR}/migration-plan-${MODULE_NAME_SANITIZED}.md" \
"${USER_REQ}"

cd /app
echo "Working directory: $(pwd)"

if [ -z "${SOURCE_TECHNOLOGY:-}" ]; then
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do one line here on the default no?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to log that we are using something unknown to simplify debugging.

Having the logging and setting of the default as a one-liner would be more cryptic.

-H "Authorization: Bearer ${TOKEN}" \
-d '{
"name": "My Chef Migration",
"name": "My Legacy Project Migration",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my source automation project

*
* @public
*/
export const SOURCE_TECHNOLOGY_ALIASES: Record<SourceTechnology, string[]> = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be a few ValueObjects to be honest and an Enum on technology, it's going to be much cleaner and easy to follow in the future.
https://martinfowler.com/bliki/ValueObject.html

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are always more to achieve something.

IMHO, the Value Objects would bring more boilerplate here and provide no/limited benefits.
We do not have any rich logic to be encapsulated with the data, just one function for simple alias-to-canonical comparison. It's easy to maintain this way.

If we encapsulate this by value objects, we would need to write more dummy code when adding a new technology. And still maintaining a sort of an array for the desired canonical mapping.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, for me this is simpler, has a pourpose, and can be simpler to understand and add in the future:

abstract class SourceTechnology {
  abstract readonly canonical: string;
  abstract readonly aliases: ReadonlySet<string>;

  matches(raw: string): boolean {
    return this.aliases.has(raw.trim().toLocaleLowerCase('en-US'));
  }

  toString(): string {
    return this.canonical;
  }
}


class ChefTechnology extends SourceTechnology {
  readonly canonical = 'chef';
  readonly aliases = new Set(['chef']);
}

class AnsibleTechnology extends SourceTechnology {
  readonly canonical = 'ansible';
  readonly aliases = new Set(['ansible', 'legacy-ansible']);
}

class PowerShellTechnology extends SourceTechnology {
  readonly canonical = 'powershell';
  readonly aliases = new Set(['powershell', 'powershell-dsc', 'dsc']);
}


```

And after, we can have a registry like that:


```
class SourceTechnologyRegistry {
  private readonly technologies: ReadonlyMap<string, SourceTechnology>;

  constructor(technologies: SourceTechnology[]) {
    // Pre-build the alias → technology map at construction time
    const map = new Map<string, SourceTechnology>();
    for (const tech of technologies) {
      for (const alias of tech.aliases) {
        if (map.has(alias)) {
          throw new Error(
            `Duplicate alias "${alias}" registered by "${tech.canonical}" and "${map.get(alias)!.canonical}"`
          );
        }
        map.set(alias, tech);
      }
    }
    this.technologies = map;
  }

  normalize(raw: string | undefined): SourceTechnology | undefined {
    if (!raw) return undefined;
    return this.technologies.get(raw.trim().toLocaleLowerCase('en-US'));
  }

  has(raw: string): boolean {
    return this.normalize(raw) !== undefined;
  }

  all(): SourceTechnology[] {
    return [...new Set(this.technologies.values())];
  }

  canonicals(): string[] {
    return this.all().map(t => t.canonical);
  }

  findByCanonical(canonical: string): SourceTechnology | undefined {
    return this.all().find(t => t.canonical === canonical);
  }
}
```

that for me, it's simpler, and can be compose one thing on top of another. 

mareklibra added 3 commits May 4, 2026 15:11
Rephrasing all texts from being Chef-oriented to more generic variants.
There is explicit mapping from free-form agentic findings to a new SourceTechnology enum (normalizeSourceTechnology.ts).

Signed-off-by: Marek Libra <marek.libra@gmail.com>
@mareklibra mareklibra force-pushed the FLPATH-3431.avoidExplicitChef branch from 7f0b32b to 48710fd Compare May 4, 2026 13:55
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 4, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants