Skip to content

chore: add reusable workflow for publishing OCM component versions#1901

Merged
morri-son merged 13 commits into
open-component-model:mainfrom
morri-son:add-cv-creation-workflow
Mar 6, 2026
Merged

chore: add reusable workflow for publishing OCM component versions#1901
morri-son merged 13 commits into
open-component-model:mainfrom
morri-son:add-cv-creation-workflow

Conversation

@morri-son

@morri-son morri-son commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

On-behalf-of: Gerald Morrison (SAP) gerald.morrison@sap.com

What this PR does / why we need it

Create a reusable workflow that can build component versions based on a component constructor that can be used in cli/controller build and cli/controller promotion step.

Summary by CodeRabbit

  • Chores
    • Added a CI workflow to publish OCM component versions: verifies artifacts, handles GHCR auth, supports configurable repository/CLI image and optional conflict policy, runs the publish step, and appends a Markdown summary with a link to the published package.
  • Tests
    • Added unit tests covering constructor parsing, name/version extraction, URL construction, and constructor patching logic.

@morri-son morri-son requested a review from a team as a code owner March 5, 2026 13:52
@morri-son morri-son added the kind/chore chore, maintenance, etc. label Mar 5, 2026
@github-actions github-actions Bot added component/github-actions Changes on GitHub Actions or within `.github/` directory size/m Medium labels Mar 5, 2026
@coderabbitai

coderabbitai Bot commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a GitHub Actions workflow to publish OCM component versions and accompanying Node.js utilities plus tests that parse/patch component-constructor YAML, build package URLs, and write GitHub Actions summaries.

Changes

Cohort / File(s) Summary
Publish OCM Component Workflow
.github/workflows/publish-ocm-component-version.yml
New GitHub Actions workflow that downloads constructor/build artifacts, validates files, logs into GHCR, generates an OCM config, runs an OCM CLI container to publish a component version (with optional conflict policy), and appends a Markdown summary linking the published package.
Component constructor utilities
.github/scripts/component-constructor.js
New JS module: parse constructor YAML, extract component name/version, build GitHub Packages URL, patch constructors to rewrite CLI resource paths and convert local image resources to OCI artifacts, and action entrypoint to write a GitHub summary.
Unit tests for constructor utilities
.github/scripts/component-constructor.test.js
New comprehensive tests covering extraction, URL building, constructor patching, file parsing, error cases, and round-trip behaviors.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant GH Actions as "GitHub Actions (workflow)"
  participant ArtifactSvc as "Artifact storage (actions/artifact)"
  participant Runner as "Actions runner"
  participant GHCR as "GitHub Container Registry"
  participant Docker as "Docker (runs CLI image)"
  participant OCM_CLI as "OCM CLI inside container"
  participant Scripts as "component-constructor.js"

  rect rgba(100,150,240,0.5)
    GH Actions->>ArtifactSvc: download constructor artifact
    GH Actions->>ArtifactSvc: optionally download build artifact
  end

  rect rgba(120,200,80,0.5)
    GH Actions->>Runner: validate files (constructor/component-constructor.yaml, resources/bin)
    Runner->>Scripts: parse & extract name/version
    Scripts->>Runner: return name, version, package URL
  end

  rect rgba(240,140,60,0.5)
    GH Actions->>GHCR: docker/login-action (authenticate using GITHUB_TOKEN)
    GH Actions->>Docker: run CLI image with mounted constructor
    Docker->>OCM_CLI: ocm add component-version --repository ...
    OCM_CLI-->>Docker: publish result
    Docker-->>GH Actions: exit status
  end

  GH Actions->>Runner: append Markdown summary with package link
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I parsed the YAML, hopped through the night,
I patched the image and set the bytes right,
I nudged GHCR’s door with a tiny CLI tap,
Now versions are published — a celebratory nap! 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: a reusable workflow for publishing OCM component versions. It directly matches the primary additions (workflow file, supporting scripts, and tests).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/publish-ocm-component-version.yml:
- Around line 117-123: The workflow builds COMPONENT_REF using values parsed
into COMPONENT_NAME and COMPONENT_VERSION from CONSTRUCTOR_FILE but doesn't
guard against empty parses; add a validation after extracting COMPONENT_NAME and
COMPONENT_VERSION (the variables in the diff) that checks both are non-empty,
and if either is empty echo a clear error including CONSTRUCTOR_FILE and the
missing field(s) then exit 1 so the job fails early instead of composing an
invalid COMPONENT_REF/PKG_PATH/PACKAGE_URL.
- Around line 56-58: The workflow currently hardcodes a check for
"${GITHUB_WORKSPACE}/constructor/resources/bin" when inputs.build_artifact_name
is set, which rejects valid artifacts that place resources elsewhere; change the
verification in the conditional that checks inputs.build_artifact_name to
validate the generic constructor resources presence (e.g., test that
"${GITHUB_WORKSPACE}/constructor/resources" exists and is non-empty or that at
least one entry matches "${GITHUB_WORKSPACE}/constructor/resources/*") instead
of specifically testing for "constructor/resources/bin" so arbitrary file-based
resources are accepted.
- Around line 14-18: The workflow currently assumes GHCR in
inputs.ocm_repository and hardcodes GHCR auth and a GitHub package URL shape;
add a fail-fast guard at the start of the workflow to validate
inputs.ocm_repository is the GHCR host (e.g., startsWith "ghcr.io" or equals the
default "ghcr.io/open-component-model") and explicitly exit with an error if it
is not GHCR to avoid running GHCR-specific auth/publish steps, and also replace
any hardcoded GitHub package URL usage with a conditional or template that uses
inputs.ocm_repository when building URLs (or skip that step when non-GHCR) so
the GHCR-only steps (the GHCR auth step and the publish/summary URL generation)
do not run for non-GHCR registries.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7e691571-367e-4bcd-be33-a1cd7d968a54

📥 Commits

Reviewing files that changed from the base of the PR and between e7f4bce and ca4af3f.

📒 Files selected for processing (1)
  • .github/workflows/publish-ocm-component-version.yml

Comment thread .github/workflows/publish-ocm-component-version.yml
Comment thread .github/workflows/publish-ocm-component-version.yml
Comment thread .github/workflows/publish-ocm-component-version.yml Outdated
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
@morri-son morri-son force-pushed the add-cv-creation-workflow branch from ae5e3ce to 3c3e840 Compare March 5, 2026 21:22

@frewilhelm frewilhelm left a comment

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.

As this is a reusable workflow we might make it a bit more generic regarding constructor/artifact-paths. There could be other users who want to use this as well.

But I would be fine using this in the first iteration.

Comment thread .github/workflows/publish-ocm-component-version.yml
Comment thread .github/workflows/publish-ocm-component-version.yml
Comment thread .github/workflows/publish-ocm-component-version.yml Outdated
Comment thread .github/workflows/publish-ocm-component-version.yml Outdated
Comment thread .github/workflows/publish-ocm-component-version.yml
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/publish-ocm-component-version.yml (2)

140-141: Add a brief comment explaining the URL encoding.

The shell parameter expansion ${COMPONENT_NAME//\//%2F} URL-encodes forward slashes. A brief comment would help readers unfamiliar with this syntax.

📝 Proposed comment
+          # URL-encode slashes in component name: ${var//pattern/replacement} replaces all '/' with '%2F'
           PKG_PATH="component-descriptors%2F${COMPONENT_NAME//\//%2F}"
           PACKAGE_URL="https://github.com/${GITHUB_REPOSITORY}/pkgs/container/${PKG_PATH}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-ocm-component-version.yml around lines 140 - 141,
Add a brief inline comment above the PKG_PATH/PACKAGE_URL assignments explaining
that the shell parameter expansion ${COMPONENT_NAME//\//%2F} replaces all
forward slashes with "%2F" to URL-encode the component name for the GitHub
Packages path; reference the PKG_PATH and PACKAGE_URL variables and place the
comment directly next to the PKG_PATH line so readers understand why the
expansion is used.

129-130: Clarify expected constructor format or adjust parsing.

The sed patterns ^name: and ^version: assume these fields appear at the start of lines, but typical component constructors nest these under a components: list:

components:
- name: github.com/acme.org/myapp
  version: 1.0.0

If the workflow expects a different single-component format (e.g., flat YAML without the components: wrapper), please add a comment documenting the expected structure to aid future maintainers.

♻️ Option A: Add a comment documenting expected format
+          # Expected constructor format (single component, flat structure):
+          #   name: <component-name>
+          #   version: <component-version>
+          #   ...
           COMPONENT_NAME=$(sed -n 's/^name:[[:space:]]*//p' "${CONSTRUCTOR_FILE}" | head -n 1)
           COMPONENT_VERSION=$(sed -n 's/^version:[[:space:]]*//p' "${CONSTRUCTOR_FILE}" | head -n 1)
♻️ Option B: Adjust regex to handle nested YAML format
-          COMPONENT_NAME=$(sed -n 's/^name:[[:space:]]*//p' "${CONSTRUCTOR_FILE}" | head -n 1)
-          COMPONENT_VERSION=$(sed -n 's/^version:[[:space:]]*//p' "${CONSTRUCTOR_FILE}" | head -n 1)
+          # Handle both flat and nested component constructor formats
+          COMPONENT_NAME=$(sed -n 's/^-\{0,1\}[[:space:]]*name:[[:space:]]*//p' "${CONSTRUCTOR_FILE}" | head -n 1)
+          COMPONENT_VERSION=$(sed -n 's/^[[:space:]]*version:[[:space:]]*//p' "${CONSTRUCTOR_FILE}" | head -n 1)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-ocm-component-version.yml around lines 129 - 130,
The sed extraction for COMPONENT_NAME and COMPONENT_VERSION assumes fields start
at column 0; either document the expected flat constructor YAML format near the
COMPONENT_NAME/COMPONENT_VERSION assignment (mentioning CONSTRUCTOR_FILE must
contain top-level name: and version: keys) or change the sed patterns used to
strip leading whitespace and an optional list dash so they match nested entries
like "- name:" and "version:" indented under components; update the two sed
invocations that produce COMPONENT_NAME and COMPONENT_VERSION to use the more
permissive pattern that accepts leading spaces and an optional leading '-'
before the key.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/publish-ocm-component-version.yml:
- Around line 79-88: The heredoc being written to "${HOME}/.ocmconfig" is
indented, so those leading spaces will be written into the file and produce
invalid YAML; fix this by left-aligning the heredoc body (remove the leading
spaces before "type:", "configurations:", etc.) and use a quoted delimiter to
prevent expansion (change the opener to <<'EOF') so the content is written
exactly as intended without variable expansion; alternatively, if you prefer
indented source, switch to a <<-EOF style and ensure you use tabs (not spaces)
for indentation so the shell strips them.

---

Nitpick comments:
In @.github/workflows/publish-ocm-component-version.yml:
- Around line 140-141: Add a brief inline comment above the PKG_PATH/PACKAGE_URL
assignments explaining that the shell parameter expansion
${COMPONENT_NAME//\//%2F} replaces all forward slashes with "%2F" to URL-encode
the component name for the GitHub Packages path; reference the PKG_PATH and
PACKAGE_URL variables and place the comment directly next to the PKG_PATH line
so readers understand why the expansion is used.
- Around line 129-130: The sed extraction for COMPONENT_NAME and
COMPONENT_VERSION assumes fields start at column 0; either document the expected
flat constructor YAML format near the COMPONENT_NAME/COMPONENT_VERSION
assignment (mentioning CONSTRUCTOR_FILE must contain top-level name: and
version: keys) or change the sed patterns used to strip leading whitespace and
an optional list dash so they match nested entries like "- name:" and "version:"
indented under components; update the two sed invocations that produce
COMPONENT_NAME and COMPONENT_VERSION to use the more permissive pattern that
accepts leading spaces and an optional leading '-' before the key.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 06ad6512-1eda-46f1-ac4a-fd318ab7fc07

📥 Commits

Reviewing files that changed from the base of the PR and between e79aebf and c18b463.

📒 Files selected for processing (1)
  • .github/workflows/publish-ocm-component-version.yml

Comment thread .github/workflows/publish-ocm-component-version.yml Outdated
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
@github-actions github-actions Bot added the size/l Large label Mar 6, 2026
@jakobmoellerdev

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 6, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (3)
.github/workflows/publish-ocm-component-version.yml (1)

34-37: Add explicit contents: read permission for checkout.

The job uses actions/checkout on Line [121]. Declaring contents: read explicitly avoids permission brittleness when token defaults are restricted.

💡 Proposed fix
     permissions:
       actions: read
+      contents: read
       packages: write    # Required for pushing to GHCR via docker login + OCM CLI

Also applies to: 121-126

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-ocm-component-version.yml around lines 34 - 37,
The workflow's job permissions block currently sets actions: read and packages:
write but omits contents: read, which can break actions/checkout; update the
job-level permissions to include contents: read so the actions/checkout step can
access repository contents (modify the permissions block that contains actions:
read and packages: write to add contents: read) and mirror the same change for
the other similar permissions block used around the actions/checkout step.
.github/scripts/component-constructor.test.js (1)

172-186: Use try/finally around temp-file blocks to guarantee cleanup.

If an assertion fails before cleanup, temp artifacts remain behind.

💡 Proposed fix pattern
 {
     const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "ocm-test-"));
     const tmpFile = path.join(tmpDir, "component-constructor.yaml");
-
-    const testDoc = { name: "ocm.software/test", version: "0.1.0", provider: { name: "test" } };
-    fs.writeFileSync(tmpFile, yaml.dump(testDoc), "utf8");
-
-    const parsed = parseConstructorFile(tmpFile);
-    assert.strictEqual(parsed.name, "ocm.software/test", "Should parse name from YAML file");
-    assert.strictEqual(parsed.version, "0.1.0", "Should parse version from YAML file");
-
-    // Cleanup
-    fs.unlinkSync(tmpFile);
-    fs.rmdirSync(tmpDir);
+    try {
+        const testDoc = { name: "ocm.software/test", version: "0.1.0", provider: { name: "test" } };
+        fs.writeFileSync(tmpFile, yaml.dump(testDoc), "utf8");
+
+        const parsed = parseConstructorFile(tmpFile);
+        assert.strictEqual(parsed.name, "ocm.software/test", "Should parse name from YAML file");
+        assert.strictEqual(parsed.version, "0.1.0", "Should parse version from YAML file");
+    } finally {
+        if (fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile);
+        if (fs.existsSync(tmpDir)) fs.rmdirSync(tmpDir);
+    }
 }

Apply the same pattern to the empty-file block.

Also applies to: 196-209

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/scripts/component-constructor.test.js around lines 172 - 186, The
test creates temp dirs/files and cleans them up manually but can leak artifacts
if assertions fail; wrap the temp-file test blocks that call
parseConstructorFile (the block creating tmpDir/tmpFile and the similar
"empty-file" block) in a try/finally where the finally always calls
fs.unlinkSync(tmpFile) and fs.rmdirSync(tmpDir) (guarding existence checks as
needed) so cleanup runs even on assertion failures; update both the block using
parseConstructorFile and the other empty-file test to use this try/finally
pattern.
.github/scripts/component-constructor.js (1)

154-156: Harden failure reporting for non-Error throws.

error.message can be empty/undefined if a non-Error value is thrown.

💡 Proposed fix
     } catch (error) {
-        core.setFailed(error.message);
+        const message = error instanceof Error ? error.message : String(error);
+        core.setFailed(message);
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/scripts/component-constructor.js around lines 154 - 156, The catch
block currently calls core.setFailed(error.message) which can be empty for
non-Error throws; update the catch handling in the catch (error) block to
normalize the thrown value before passing to core.setFailed (e.g., if error is
an Error use error.message or error.stack, otherwise convert to a string/JSON
via String(error) or JSON.stringify(error) and include it in the message) so
core.setFailed always receives a meaningful string; ensure you reference the
existing catch (error) and core.setFailed invocation when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/scripts/component-constructor.js:
- Around line 75-82: The CLI-path branch currently assumes resource.input.path
is a valid string and calls .split("/"), which throws if missing; in the
resource-name === "cli" && resource.input?.type === "file" block validate that
resource.input.path exists and is a non-empty string before splitting (e.g., if
(!resource.input?.path || typeof resource.input.path !== "string") throw a
constructor/validation error), then compute parts/filename and set
resource.input.path = `resources/bin/${filename}`; ensure the thrown error is a
clear constructor validation error mentioning the resource id/name and
missing/invalid input.path so callers can handle it.

---

Nitpick comments:
In @.github/scripts/component-constructor.js:
- Around line 154-156: The catch block currently calls
core.setFailed(error.message) which can be empty for non-Error throws; update
the catch handling in the catch (error) block to normalize the thrown value
before passing to core.setFailed (e.g., if error is an Error use error.message
or error.stack, otherwise convert to a string/JSON via String(error) or
JSON.stringify(error) and include it in the message) so core.setFailed always
receives a meaningful string; ensure you reference the existing catch (error)
and core.setFailed invocation when making the change.

In @.github/scripts/component-constructor.test.js:
- Around line 172-186: The test creates temp dirs/files and cleans them up
manually but can leak artifacts if assertions fail; wrap the temp-file test
blocks that call parseConstructorFile (the block creating tmpDir/tmpFile and the
similar "empty-file" block) in a try/finally where the finally always calls
fs.unlinkSync(tmpFile) and fs.rmdirSync(tmpDir) (guarding existence checks as
needed) so cleanup runs even on assertion failures; update both the block using
parseConstructorFile and the other empty-file test to use this try/finally
pattern.

In @.github/workflows/publish-ocm-component-version.yml:
- Around line 34-37: The workflow's job permissions block currently sets
actions: read and packages: write but omits contents: read, which can break
actions/checkout; update the job-level permissions to include contents: read so
the actions/checkout step can access repository contents (modify the permissions
block that contains actions: read and packages: write to add contents: read) and
mirror the same change for the other similar permissions block used around the
actions/checkout step.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0ca10dfb-2a88-4174-808d-fecae3146f9c

📥 Commits

Reviewing files that changed from the base of the PR and between c18b463 and c40a502.

📒 Files selected for processing (3)
  • .github/scripts/component-constructor.js
  • .github/scripts/component-constructor.test.js
  • .github/workflows/publish-ocm-component-version.yml

Comment thread .github/scripts/component-constructor.js
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Comment thread .github/workflows/publish-ocm-component-version.yml Outdated
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
piotrjanik
piotrjanik previously approved these changes Mar 6, 2026
On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
…component-model into add-cv-creation-workflow

On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
@morri-son morri-son merged commit 0d09fa3 into open-component-model:main Mar 6, 2026
16 checks passed
@morri-son morri-son deleted the add-cv-creation-workflow branch March 6, 2026 16:20
frewilhelm pushed a commit to frewilhelm/open-component-model that referenced this pull request Mar 12, 2026
…pen-component-model#1901)

On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>

<!-- markdownlint-disable MD041 -->
#### What this PR does / why we need it
Create a reusable workflow that can build component versions based on a
component constructor that can be used in cli/controller build and
cli/controller promotion step.
  

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Added a CI workflow to publish OCM component versions: verifies
artifacts, handles GHCR auth, supports configurable repository/CLI image
and optional conflict policy, runs the publish step, and appends a
Markdown summary with a link to the published package.
* **Tests**
* Added unit tests covering constructor parsing, name/version
extraction, URL construction, and constructor patching logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Co-authored-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Co-authored-by: Piotr Janik <piotr.janik@sap.com>
morri-son added a commit to morri-son/open-component-model that referenced this pull request Mar 18, 2026
…pen-component-model#1901)

On-behalf-of: Gerald Morrison (SAP) <gerald.morrison@sap.com>

<!-- markdownlint-disable MD041 -->
#### What this PR does / why we need it
Create a reusable workflow that can build component versions based on a
component constructor that can be used in cli/controller build and
cli/controller promotion step.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Added a CI workflow to publish OCM component versions: verifies
artifacts, handles GHCR auth, supports configurable repository/CLI image
and optional conflict policy, runs the publish step, and appends a
Markdown summary with a link to the published package.
* **Tests**
* Added unit tests covering constructor parsing, name/version
extraction, URL construction, and constructor patching logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Co-authored-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Co-authored-by: Piotr Janik <piotr.janik@sap.com>
Signed-off-by: Gerald Morrison (SAP) <gerald.morrison@sap.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/github-actions Changes on GitHub Actions or within `.github/` directory kind/chore chore, maintenance, etc. size/l Large size/m Medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create ocm components of controllers and make it part of a release

6 participants