-
Notifications
You must be signed in to change notification settings - Fork 5
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
base: main
Are you sure you want to change the base?
Conversation
b2c9acc
to
0fea833
Compare
There was a problem hiding this 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 |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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
with: | ||
channel: dpe/edge | ||
artifact-prefix: ${{ needs.build.outputs.artifact-prefix }} | ||
artifact-prefix: ${{ needs.ci-tests.outputs.artifact-prefix }} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)
# 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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
Worth noting that this PR includes the charmcraft 3 migration as well
don't see any easy paths forward here; happy to discuss also the linked charmcraft issues only account for these extra lines ( mysql-router-operator/.github/workflows/integration_test.yaml Lines 104 to 108 in ab1aa0a
|
type: adhoc | ||
# Only run on CI | ||
manual: true | ||
# HACK: spread requires runners to be accessible via SSH |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh dear
There was a problem hiding this 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.
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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
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) |
There was a problem hiding this comment.
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.
# 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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
no arm charm built on 20
b1657d4
to
b69e73d
Compare
Ported from canonical/mysql-router-k8s-operator#379