Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to charmcraft 3 & charmcraft test #210

Open
wants to merge 34 commits into
base: main
Choose a base branch
from

Conversation

carlcsaposs-canonical
Copy link
Contributor

@carlcsaposs-canonical carlcsaposs-canonical commented Feb 3, 2025

Copy link
Contributor

@taurus-forever taurus-forever left a comment

Choose a reason for hiding this comment

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

OMG. This is going to be more complex as initially planned.
LGTM, @carlcsaposs-canonical please share TODO list we need to address to simplify CI. E.g. I see tons of pendinds TODO for charmcraft, let's sync with Sergio&Co there.

It will be harded to simplify this once we scale it to all repos. LGTM.

run: |
sudo snap install charmcraft --classic
pipx install tox poetry
- name: Collect spread jobs
Copy link
Contributor

Choose a reason for hiding this comment

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

Should it be a new DPW action ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so since the contents of this workflow are quite coupled to the spread configuration & the creation of a reusable workflow would limit the ways in which spread can be used

canonical/mysql-router-k8s-operator#379 (comment)

with:
channel: dpe/edge
artifact-prefix: ${{ needs.build.outputs.artifact-prefix }}
artifact-prefix: ${{ needs.ci-tests.outputs.artifact-prefix }}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we now releasing artifacts built outside of our trusted machines.
This opens us to https://en.wikipedia.org/wiki/XZ_Utils_backdoor

Copy link
Contributor Author

Choose a reason for hiding this comment

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

huh? we're building on github runners, same as before

this change is to use same build for test + release (canonical/mysql-router-k8s-operator#366)

Comment on lines +90 to +93
# Workaround to add unique identifier (git hash) to charm version while specification
# DA053 - Charm versioning
# (https://docs.google.com/document/d/1Jv1jhWLl8ejK3iJn7Q3VbCIM9GIhp8926bgXpdtx-Sg/edit?pli=1)
# is pending review.
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's complete this officially to move from here. Based on the last conversation I think we have synced all topics.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

multi track on single git branch could affect this, but yes I think we're synced. still needs approval from Mykola/Mohamed, but think we should wait until we get back to refresh v3

this is the same as before this PR; no change in behavior in this pr

@carlcsaposs-canonical
Copy link
Contributor Author

This is going to be more complex as initially planned

Worth noting that this PR includes the charmcraft 3 migration as well

TODO list we need to address to simplify CI. E.g. I see tons of pendinds TODO for charmcraft

don't see any easy paths forward here; happy to discuss

also the linked charmcraft issues only account for these extra lines (

# TODO: remove when https://github.com/canonical/charmcraft/issues/2105 and
# https://github.com/canonical/charmcraft/issues/2130 fixed
- run: |
sudo snap install go --classic
go install github.com/snapcore/spread/cmd/spread@latest
,
run: ~/go/bin/spread -vv -artifacts=artifacts '${{ matrix.job.spread_job }}'
), no other complexity will be removed

type: adhoc
# Only run on CI
manual: true
# HACK: spread requires runners to be accessible via SSH
Copy link
Contributor

Choose a reason for hiding this comment

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

oh dear

Copy link
Contributor

@sinclert-canonical sinclert-canonical left a comment

Choose a reason for hiding this comment

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

I think some logic re-shuffling is needed, to ease the maintainability of the integration-test workflow going forward.

Comment on lines +28 to +62
import json
import os
import subprocess

spread_jobs = (
subprocess.run(
["charmcraft", "test", "--list", "github-ci"], capture_output=True, check=True, text=True
)
.stdout.strip()
.split("\n")
)
jobs = []
for job in spread_jobs:
# Example `job`: "github-ci:ubuntu-24.04:tests/spread/test_charm.py:juju36"
_, runner, task, variant = job.split(":")
# Example: "test_charm.py"
task = task.removeprefix("tests/spread/")
if runner.endswith("-arm"):
architecture = "arm64"
else:
architecture = "amd64"
# Example: "test_charm.py:juju36 | amd64"
name = f"{task}:{variant} | {architecture}"
# ":" character not valid in GitHub Actions artifact
name_in_artifact = f"{task}-{variant}-{architecture}"
jobs.append({
"spread_job": job,
"name": name,
"name_in_artifact": name_in_artifact,
"runner": runner,
})
output = f"jobs={json.dumps(jobs)}"
print(output)
with open(os.environ["GITHUB_OUTPUT"], "a") as file:
file.write(output)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think moving this whole block to a Python script within .github/scripts would reduce the cognitive load of understanding what this job / set of steps does, in addition to having syntax highlighting.

AFAIK, the only thing that depends on GHA is the final population of a JSON string into the GITHUB_OUTPUT env var, which could be the output of such script.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

would reduce the cognitive load of understanding

I think it would increase the cognitive load, since you need to look at 2 files at once to understand what's happening, especially with respect to the value of items in the matrix

I see the benefits for syntax highlighting/linting—if you want to open a separate PR for this, feel free; imo it shouldn't block this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, this isn't something I expect to be edited often

And there are some benefits to a single file for copy-paste across repos & avoiding issues with some files getting copy-pasted while others not, and sync issues

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would increase the cognitive load, since you need to look at 2 files at once to understand what's happening

Splitting code into multiple files is the principle in which complex logic can be understood and scoped. That is why there are multiple files within the src directory of this repo, instead of a single and massive charm.py...

there are some benefits to a single file for copy-paste across repos

I agree with this statement, but that does not necessarily make it good. Designing code so that it is easy to copy+paste may be a code smell, as if we need to copy+paste it multiple times, maybe it is a sign that we should make it distributable (i.e. A reusable GHA workflow + scripts).


I would have expressed these concerns earlier, probably in this PR, but I stayed away as you told me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we should make it distributable (i.e. A reusable GHA workflow + scripts)

would you like to volunteer to create & maintain that distributable component?

Comment on lines +229 to +263
import dataclasses
import json
import pathlib


@dataclasses.dataclass(frozen=True)
class Result:
test_case_id: str
path: pathlib.Path

def __eq__(self, other):
if not isinstance(other, type(self)):
return False
return self.test_case_id == other.test_case_id


actual_results = pathlib.Path("allure-results")
default_results = pathlib.Path("allure-default-results")

results: dict[pathlib.Path, set[Result]] = {
actual_results: set(),
default_results: set(),
}
for directory, results_ in results.items():
for path in directory.glob("*-result.json"):
with path.open("r") as file:
id_ = json.load(file)["testCaseId"]
results_.add(Result(id_, path))

actual_results.mkdir(exist_ok=True)

missing_results = results[default_results] - results[actual_results]
for default_result in missing_results:
# Move to `actual_results` directory
default_result.path.rename(actual_results / default_result.path.name)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think moving this whole block to a Python script within .github/scripts would reduce the cognitive load of understanding what this job / set of steps does, in addition to having syntax highlighting.

Comment on lines +274 to +286
# Reverse engineered from https://github.com/simple-elf/allure-report-action/blob/eca283b643d577c69b8e4f048dd6cd8eb8457cfd/entrypoint.sh
import json

DATA = {
"name": "GitHub Actions",
"type": "github",
"buildOrder": ${{ github.run_number }}, # TODO future improvement: use run ID
"buildName": "Run ${{ github.run_id }}",
"buildUrl": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"reportUrl": "../${{ github.run_number }}/",
}
with open("allure-results/executor.json", "w") as file:
json.dump(DATA, file)
Copy link
Contributor

Choose a reason for hiding this comment

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

This block is relatively small, and highly dependent on GHA populated env variables. Here my suggestion would be to leverage existing GHA JSON utilities (see toJSON), instead of spawning a Python shell just to do a JSON dump.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think python is slightly more forgiving than raw json syntax, and has equivalent readability

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.

4 participants