Skip to content

Redesign check-coco-release workflow to create PR#20

Merged
bpradipt merged 1 commit into
confidential-devhub:mainfrom
bpradipt:coco-0.19
Apr 7, 2026
Merged

Redesign check-coco-release workflow to create PR#20
bpradipt merged 1 commit into
confidential-devhub:mainfrom
bpradipt:coco-0.19

Conversation

@bpradipt

@bpradipt bpradipt commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

instead of building and pushing images directly

Assisted-by: AI

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR redesigns the check-coco-release GitHub Actions workflow so it no longer builds/pushes release images directly; instead it detects a new CoCo release and opens a PR updating Containerfile and versions.yaml to the corresponding component versions.

Changes:

  • Replace “check GHCR tag + build/push image + create release” flow with “check existing PR + create update PR” flow.
  • Parse component versions from upstream CoCo release notes and apply them to Containerfile args.
  • Update versions.yaml based on the CoCo tag and open a PR with a generated body describing the update.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/check-coco-release.yml Outdated
Comment thread .github/workflows/check-coco-release.yml Outdated
Comment thread .github/workflows/check-coco-release.yml
Comment thread .github/workflows/check-coco-release.yml Outdated
Comment thread .github/workflows/check-coco-release.yml Outdated
Comment thread .github/workflows/check-coco-release.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/check-coco-release.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +48 to +53
PR_EXISTS=$(gh pr list \
--repo ${{ github.repository }} \
--head "${BRANCH}" \
--state open \
--json number \
--jq 'length > 0' 2>/dev/null || echo "false")

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

gh pr list errors are being swallowed (2>/dev/null || echo "false"), which can cause the workflow to incorrectly assume no PR exists (e.g., on auth/rate-limit/network failures) and then attempt to push/create a duplicate PR. Prefer failing fast on gh errors (or explicitly checking exit status and exiting with a clear message) rather than defaulting to "false".

Suggested change
PR_EXISTS=$(gh pr list \
--repo ${{ github.repository }} \
--head "${BRANCH}" \
--state open \
--json number \
--jq 'length > 0' 2>/dev/null || echo "false")
if ! PR_EXISTS=$(gh pr list \
--repo ${{ github.repository }} \
--head "${BRANCH}" \
--state open \
--json number \
--jq 'length > 0'); then
echo "ERROR: Failed to check for an existing PR for ${COCO_TAG}." >&2
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment on lines +78 to +81
NOTES=$(gh api \
"repos/confidential-containers/confidential-containers/contents/releases/${COCO_TAG}.md" \
--jq '.content' | base64 -d)

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

The release-notes fetch uses a pipeline (gh api ... | base64 -d) without pipefail, so failures in gh api can be masked and lead to confusing downstream parsing errors. Consider enabling set -o pipefail (and adjusting the grep pipelines accordingly) or rewriting this to capture/validate the gh api exit status explicitly before decoding.

Suggested change
NOTES=$(gh api \
"repos/confidential-containers/confidential-containers/contents/releases/${COCO_TAG}.md" \
--jq '.content' | base64 -d)
if ! ENCODED_NOTES=$(gh api \
"repos/confidential-containers/confidential-containers/contents/releases/${COCO_TAG}.md" \
--jq '.content'); then
echo "ERROR: Failed to fetch release notes for ${COCO_TAG}" >&2
exit 1
fi
if ! NOTES=$(base64 -d <<< "$ENCODED_NOTES"); then
echo "ERROR: Failed to decode release notes for ${COCO_TAG}" >&2
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment on lines +184 to +208
cat > "${PR_BODY}" << EOF
Automated update for CoCo release [${COCO_TAG}](${COCO_URL}).

## Component versions (parsed from [release notes](${NOTES_URL}))

| Argument | New value |
|---|---|
| \`GUEST_COMPONENTS_REF\` | \`${GC_REF}\` |
| \`TRUSTEE_REF\` | \`${GC_REF}\` |
| \`KATA_REF\` | \`${KATA_REF}\` |
| \`COCO_RUST_VERSION\` | ${COCO_RUST_ROW} |
| \`KATA_RUST_VERSION\` | ${KATA_RUST_ROW} |

## Manual review required

- [ ] Check \`SNPGUEST_REF\` — verify the current ref is compatible with CoCo ${COCO_TAG}
- [ ] Check \`SNPHOST_REF\` — verify the current ref is compatible with CoCo ${COCO_TAG}
- [ ] Check \`TDX_MEASURE_REF\` and \`VERITAS_REF\` if those projects have relevant updates

## After merge

- Push to \`main\` triggers \`push-image-to-ghcr.yml\` → publishes \`:latest\`
- Publish a GitHub release tagged \`${COCO_TAG}\` to trigger \`release.yml\` → publishes \`:${VERSION}\`
EOF

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

The PR body heredoc is indented in the workflow, so the generated Markdown will include leading spaces on every line; with 4+ leading spaces, GitHub renders it as a code block and headings/lists won't format as intended. Generate the body without leading indentation (e.g., via a small python3 dedent writer, or by stripping leading whitespace before writing the temp file).

Suggested change
cat > "${PR_BODY}" << EOF
Automated update for CoCo release [${COCO_TAG}](${COCO_URL}).
## Component versions (parsed from [release notes](${NOTES_URL}))
| Argument | New value |
|---|---|
| \`GUEST_COMPONENTS_REF\` | \`${GC_REF}\` |
| \`TRUSTEE_REF\` | \`${GC_REF}\` |
| \`KATA_REF\` | \`${KATA_REF}\` |
| \`COCO_RUST_VERSION\` | ${COCO_RUST_ROW} |
| \`KATA_RUST_VERSION\` | ${KATA_RUST_ROW} |
## Manual review required
- [ ] Check \`SNPGUEST_REF\` — verify the current ref is compatible with CoCo ${COCO_TAG}
- [ ] Check \`SNPHOST_REF\` — verify the current ref is compatible with CoCo ${COCO_TAG}
- [ ] Check \`TDX_MEASURE_REF\` and \`VERITAS_REF\` if those projects have relevant updates
## After merge
- Push to \`main\` triggers \`push-image-to-ghcr.yml\` → publishes \`:latest\`
- Publish a GitHub release tagged \`${COCO_TAG}\` to trigger \`release.yml\` → publishes \`:${VERSION}\`
EOF
python3 - <<'PY' "${PR_BODY}"
import pathlib
import sys
import textwrap
pathlib.Path(sys.argv[1]).write_text(
textwrap.dedent("""
Automated update for CoCo release [${COCO_TAG}](${COCO_URL}).
## Component versions (parsed from [release notes](${NOTES_URL}))
| Argument | New value |
|---|---|
| `GUEST_COMPONENTS_REF` | `${GC_REF}` |
| `TRUSTEE_REF` | `${GC_REF}` |
| `KATA_REF` | `${KATA_REF}` |
| `COCO_RUST_VERSION` | ${COCO_RUST_ROW} |
| `KATA_RUST_VERSION` | ${KATA_RUST_ROW} |
## Manual review required
- [ ] Check `SNPGUEST_REF` — verify the current ref is compatible with CoCo ${COCO_TAG}
- [ ] Check `SNPHOST_REF` — verify the current ref is compatible with CoCo ${COCO_TAG}
- [ ] Check `TDX_MEASURE_REF` and `VERITAS_REF` if those projects have relevant updates
## After merge
- Push to `main` triggers `push-image-to-ghcr.yml` → publishes `:latest`
- Publish a GitHub release tagged `${COCO_TAG}` to trigger `release.yml` → publishes `:${VERSION}`
""").lstrip("\n"),
encoding="utf-8",
)
PY

Copilot uses AI. Check for mistakes.
contents: write
packages: write
pull-requests: write

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

This workflow can run on a schedule and via manual dispatch; without a concurrency group, overlapping runs can race (both see no PR, both push/update the same branch) and intermittently fail git push/gh pr create. Consider adding a workflow-level concurrency block (similar to other workflows in this repo) to ensure only one check-coco-release run is active at a time.

Suggested change
concurrency:
group: check-coco-release
cancel-in-progress: false

Copilot uses AI. Check for mistakes.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +142 to +157
- name: Update Containerfile
env:
KATA_REF: ${{ steps.versions.outputs.kata_ref }}
GC_REF: ${{ steps.versions.outputs.gc_ref }}
COCO_RUST: ${{ steps.versions.outputs.coco_rust }}
KATA_RUST: ${{ steps.versions.outputs.kata_rust }}
run: |
sed -i "s|^ARG GUEST_COMPONENTS_REF=.*|ARG GUEST_COMPONENTS_REF=${GC_REF}|" Containerfile
sed -i "s|^ARG TRUSTEE_REF=.*|ARG TRUSTEE_REF=${GC_REF}|" Containerfile
sed -i "s|^ARG KATA_REF=.*|ARG KATA_REF=${KATA_REF}|" Containerfile
if [ -n "${COCO_RUST}" ]; then
sed -i "s|^ARG COCO_RUST_VERSION=.*|ARG COCO_RUST_VERSION=${COCO_RUST}|" Containerfile
fi
if [ -n "${KATA_RUST}" ]; then
sed -i "s|^ARG KATA_RUST_VERSION=.*|ARG KATA_RUST_VERSION=${KATA_RUST}|" Containerfile
fi

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

The update step only modifies Containerfile, but push-image-to-ghcr.yml also builds Containerfile.ubi (UBI image). As a result, Fedora and UBI images can end up using different component refs / Rust toolchains after this workflow runs. Update both containerfiles here (or explicitly justify why UBI should diverge).

Suggested change
- name: Update Containerfile
env:
KATA_REF: ${{ steps.versions.outputs.kata_ref }}
GC_REF: ${{ steps.versions.outputs.gc_ref }}
COCO_RUST: ${{ steps.versions.outputs.coco_rust }}
KATA_RUST: ${{ steps.versions.outputs.kata_rust }}
run: |
sed -i "s|^ARG GUEST_COMPONENTS_REF=.*|ARG GUEST_COMPONENTS_REF=${GC_REF}|" Containerfile
sed -i "s|^ARG TRUSTEE_REF=.*|ARG TRUSTEE_REF=${GC_REF}|" Containerfile
sed -i "s|^ARG KATA_REF=.*|ARG KATA_REF=${KATA_REF}|" Containerfile
if [ -n "${COCO_RUST}" ]; then
sed -i "s|^ARG COCO_RUST_VERSION=.*|ARG COCO_RUST_VERSION=${COCO_RUST}|" Containerfile
fi
if [ -n "${KATA_RUST}" ]; then
sed -i "s|^ARG KATA_RUST_VERSION=.*|ARG KATA_RUST_VERSION=${KATA_RUST}|" Containerfile
fi
- name: Update Containerfiles
env:
KATA_REF: ${{ steps.versions.outputs.kata_ref }}
GC_REF: ${{ steps.versions.outputs.gc_ref }}
COCO_RUST: ${{ steps.versions.outputs.coco_rust }}
KATA_RUST: ${{ steps.versions.outputs.kata_rust }}
run: |
for f in Containerfile Containerfile.ubi; do
sed -i "s|^ARG GUEST_COMPONENTS_REF=.*|ARG GUEST_COMPONENTS_REF=${GC_REF}|" "$f"
sed -i "s|^ARG TRUSTEE_REF=.*|ARG TRUSTEE_REF=${GC_REF}|" "$f"
sed -i "s|^ARG KATA_REF=.*|ARG KATA_REF=${KATA_REF}|" "$f"
if [ -n "${COCO_RUST}" ]; then
sed -i "s|^ARG COCO_RUST_VERSION=.*|ARG COCO_RUST_VERSION=${COCO_RUST}|" "$f"
fi
if [ -n "${KATA_RUST}" ]; then
sed -i "s|^ARG KATA_RUST_VERSION=.*|ARG KATA_RUST_VERSION=${KATA_RUST}|" "$f"
fi
done

Copilot uses AI. Check for mistakes.
fi

git commit -m "Update component refs for CoCo ${COCO_TAG}"
# --force-with-lease handles stale remote branches left by previous runs

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

git push --force-with-lease origin "${BRANCH}" is likely to fail when the remote branch already exists, because a fresh actions/checkout typically doesn't fetch that remote branch so there is no local remote-tracking ref for the lease check. If you want safe updates to an existing bot branch, fetch the remote branch first (and then use --force-with-lease), or use a deterministic strategy like deleting/recreating the branch, or --force with a dedicated bot branch.

Suggested change
# --force-with-lease handles stale remote branches left by previous runs
# Fetch the remote branch first so --force-with-lease has a local
# remote-tracking ref when a previous run already created it.
git fetch --no-tags origin "+refs/heads/${BRANCH}:refs/remotes/origin/${BRANCH}" || true

Copilot uses AI. Check for mistakes.
Comment on lines +206 to +210
echo "| \`GUEST_COMPONENTS_REF\` | \`${GC_REF}\` |"
echo "| \`TRUSTEE_REF\` | \`${GC_REF}\` |"
echo "| \`KATA_REF\` | \`${KATA_REF}\` |"
echo "| \`COCO_RUST_VERSION\` | ${COCO_RUST_ROW} |"
echo "| \`KATA_RUST_VERSION\` | ${KATA_RUST_ROW} |"

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

In the generated PR body table, GC_REF / KATA_REF values are wrapped in backticks but COCO_RUST_VERSION / KATA_RUST_VERSION values are not when present. Consider formatting actual version values consistently as inline code and reserving italic placeholders only for the “unchanged” cases.

Copilot uses AI. Check for mistakes.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +122 to +123
# CoCo Rust version (optional line) — "Trustee and guest components use Rust v1.90.0"
COCO_RUST=$(echo "$NOTES" | grep -oP '(?i)use Rust \Kv[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

The COCO_RUST parsing regex only matches the substring "use Rust vX.Y.Z". If the release notes use the more typical phrasing "uses Rust vX.Y.Z" (as indicated in the comment above), this will fail to parse and COCO_RUST_VERSION won’t be updated even when present. Consider adjusting the regex to accept both "use" and "uses" (or generally match "use(s)? Rust").

Suggested change
# CoCo Rust version (optional line) — "Trustee and guest components use Rust v1.90.0"
COCO_RUST=$(echo "$NOTES" | grep -oP '(?i)use Rust \Kv[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
# CoCo Rust version (optional line) — "Trustee and guest components use/uses Rust v1.90.0"
COCO_RUST=$(echo "$NOTES" | grep -oP '(?i)uses? Rust \Kv[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)

Copilot uses AI. Check for mistakes.
Comment on lines +194 to +196
# Fetch remote branch so --force-with-lease has a tracking ref to compare against
git fetch --no-tags origin "+refs/heads/${BRANCH}:refs/remotes/origin/${BRANCH}" || true
git push --force-with-lease origin "${BRANCH}"

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

The remote-branch fetch is allowed to fail ("|| true"), but the subsequent push still uses --force-with-lease. If the fetch fails due to a transient error, the push may either fail unexpectedly or lose the safety guarantee of the lease (depending on whether the remote-tracking ref exists). It’d be safer to handle the "branch doesn’t exist" case explicitly and fail the job on other fetch errors so the lease protection is reliable.

Suggested change
# Fetch remote branch so --force-with-lease has a tracking ref to compare against
git fetch --no-tags origin "+refs/heads/${BRANCH}:refs/remotes/origin/${BRANCH}" || true
git push --force-with-lease origin "${BRANCH}"
# Only ignore the specific "branch does not exist" case; fail on other remote errors
if git ls-remote --exit-code --heads origin "${BRANCH}" > /dev/null 2>&1; then
# Remote branch exists, so fetch it and use the remote-tracking ref for the lease check
git fetch --no-tags origin "+refs/heads/${BRANCH}:refs/remotes/origin/${BRANCH}"
git push --force-with-lease origin "${BRANCH}"
else
ls_remote_status=$?
if [ "${ls_remote_status}" -eq 2 ]; then
# Remote branch does not exist; require it to remain absent when pushing
git push --force-with-lease="refs/heads/${BRANCH}:" origin "${BRANCH}"
else
echo "Failed to determine whether remote branch ${BRANCH} exists." >&2
exit "${ls_remote_status}"
fi
fi

Copilot uses AI. Check for mistakes.
instead of building and pushing images directly

Assisted-by: AI
Signed-off-by: Pradipta Banerjee <pradipta.banerjee@gmail.com>
@bpradipt bpradipt closed this Apr 6, 2026
@bpradipt bpradipt reopened this Apr 6, 2026
@bpradipt bpradipt merged commit 798d725 into confidential-devhub:main Apr 7, 2026
2 checks passed
@bpradipt bpradipt deleted the coco-0.19 branch April 7, 2026 03:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants