Skip to content

Commit 80aa64d

Browse files
authored
Move artifact and size JSONs to temp directory (DataDog#21496)
* temp dir * changelog * add && to command * echos * test * test * Revert testing changes * test * Revert testing changes * change changelog to fixed * test * Revert testing for suggested changes * test * test getting previous artifact * Revert testing changes * Add version to file_path
1 parent 84cb954 commit 80aa64d

5 files changed

Lines changed: 89 additions & 97 deletions

File tree

.github/workflows/measure-disk-usage.yml

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,32 @@ jobs:
3434
run: |
3535
ddev config override
3636
37-
- name: Measure disk usage
38-
env:
39-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37+
- name: Define command
38+
id: cmd
4039
run: |
4140
cmd="ddev size status \
4241
--commit ${{ github.event.workflow_run.head_sha }} \
4342
--format json"
4443
45-
# Send metrics to Datadog only on push to master
4644
if [ "${{ github.event.workflow_run.event }}" = "push" ] && [ "${{ github.ref_name }}" = "master" ]; then
4745
cmd="$cmd --to-dd-key ${{ secrets.DD_API_KEY }}"
4846
fi
49-
50-
$cmd
5147
52-
$cmd --compressed
48+
echo "cmd=$cmd" >> $GITHUB_OUTPUT
49+
50+
- name: Measure disk usage (Uncompressed)
51+
env:
52+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53+
run: |
54+
echo "Running for uncompressed sizes"
55+
${{ steps.cmd.outputs.cmd }}
56+
57+
- name: Measure disk usage (Compressed)
58+
env:
59+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60+
run: |
61+
echo "Running for compressed sizes"
62+
${{ steps.cmd.outputs.cmd }} --compressed
5363
5464
- name: Upload JSON uncompressed sizes artifact
5565
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2

ddev/changelog.d/21496.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The `ddev size status` now stores temporary files in a temporary directory that is removed when the commands finishes. This prevents littering the local disk with unnecessary files.

ddev/src/ddev/cli/size/status.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ def status(
7878
if commit:
7979
from ddev.cli.size.utils.common_funcs import get_last_dependency_sizes_artifact
8080

81-
dependency_sizes = get_last_dependency_sizes_artifact(app, commit, plat)
81+
dependency_sizes = get_last_dependency_sizes_artifact(app, commit, plat, ver, compressed)
82+
8283
parameters: CLIParameters = {
8384
"app": app,
8485
"platform": plat,

ddev/src/ddev/cli/size/utils/common_funcs.py

Lines changed: 63 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -954,34 +954,31 @@ def get_last_commit_data() -> tuple[str, list[str], list[str]]:
954954

955955

956956
@cache
957-
def get_last_dependency_sizes_artifact(app: Application, commit: str, platform: str) -> Path | None:
957+
def get_last_dependency_sizes_artifact(
958+
app: Application, commit: str, platform: str, py_version: str, compressed: bool
959+
) -> Path | None:
958960
'''
959961
Lockfiles of dependencies are not updated in the same commit as the dependencies are updated.
960962
So in each commit, there is an artifact with the sizes of the wheels that were built to get the actual
961963
size of that commit.
962964
'''
963-
dep_sizes_json = get_dep_sizes_json(commit, platform)
965+
dep_sizes_json = get_dep_sizes_json(commit, platform, py_version)
964966
if not dep_sizes_json:
965-
previous_sizes = get_previous_dep_sizes_json(app.repo.git.merge_base(commit, "origin/master"))
966-
if previous_sizes:
967-
compressed_json, uncompressed_json = previous_sizes["compressed"], previous_sizes["uncompressed"]
968-
sizes = parse_sizes_json(compressed_json, uncompressed_json, platform)
969-
with open(f"{platform}.json", "w") as f:
970-
json.dump(sizes, f, indent=2)
971-
dep_sizes_json = Path(f"{platform}.json")
972-
return dep_sizes_json if dep_sizes_json else None
967+
dep_sizes_json = get_previous_dep_sizes(
968+
app.repo.git.merge_base(commit, "origin/master"), platform, py_version, compressed
969+
)
970+
return Path(dep_sizes_json) if dep_sizes_json else None
973971

974972

975973
@cache
976-
def get_dep_sizes_json(current_commit: str, platform: str) -> Path | None:
974+
def get_dep_sizes_json(current_commit: str, platform: str, py_version: str) -> Path | None:
977975
'''
978976
Gets the dependency sizes json for a given commit and platform when dependencies were resolved.
979977
'''
980978
print(f"Getting dependency sizes json for commit: {current_commit}, platform: {platform}")
981979
run_id = get_run_id(current_commit, RESOLVE_BUILD_DEPS_WORKFLOW)
982980
if run_id:
983-
dep_sizes_json = get_current_sizes_json(run_id, platform)
984-
print(f"Dependency sizes json path: {dep_sizes_json}")
981+
dep_sizes_json = get_current_sizes_json(run_id, platform, py_version)
985982
return dep_sizes_json
986983
else:
987984
return None
@@ -1019,7 +1016,7 @@ def get_run_id(commit: str, workflow: str) -> str | None:
10191016

10201017

10211018
@cache
1022-
def get_current_sizes_json(run_id: str, platform: str) -> Path | None:
1019+
def get_current_sizes_json(run_id: str, platform: str, py_version: str) -> Path | None:
10231020
'''
10241021
Downloads the dependency sizes json for a given run id and platform when dependencies were resolved.
10251022
'''
@@ -1059,79 +1056,85 @@ def get_current_sizes_json(run_id: str, platform: str) -> Path | None:
10591056
return None
10601057

10611058
print(f"Found sizes artifact at {sizes_file}")
1062-
dest_path = sizes_file.rename(f"{platform}.json")
1059+
dest_path = sizes_file.rename(f"{platform}_{py_version}.json")
10631060
return dest_path
10641061

10651062

10661063
@cache
1067-
def get_artifact(run_id: str, artifact_name: str) -> Path | None:
1064+
def get_artifact(run_id: str, artifact_name: str, target_dir: str | None = None) -> Path | None:
10681065
print(f"Downloading artifact: {artifact_name} from run_id={run_id}")
10691066
try:
1070-
subprocess.run(
1071-
[
1072-
'gh',
1073-
'run',
1074-
'download',
1075-
run_id,
1076-
'--name',
1077-
artifact_name,
1078-
],
1079-
check=True,
1080-
text=True,
1081-
)
1067+
cmd = [
1068+
'gh',
1069+
'run',
1070+
'download',
1071+
run_id,
1072+
'--name',
1073+
artifact_name,
1074+
]
1075+
if target_dir:
1076+
cmd.extend(['--dir', target_dir])
1077+
1078+
subprocess.run(cmd, check=True, text=True)
10821079
except subprocess.CalledProcessError as e:
10831080
print(f"Failed to download artifact: {artifact_name} from run_id={run_id}: {e}")
10841081
return None
10851082

1086-
print(f"Artifact downloaded to: {artifact_name}")
1087-
return Path(artifact_name)
1083+
artifact_path = Path(target_dir) / artifact_name if target_dir else Path(artifact_name)
1084+
print(f"Artifact downloaded to: {artifact_path}")
1085+
return artifact_path
10881086

10891087

10901088
@cache
1091-
def get_previous_dep_sizes_json(base_commit: str) -> dict[str, Path] | None:
1089+
def get_previous_dep_sizes(base_commit: str, platform: str, py_version: str, compressed: bool) -> Path | None:
10921090
'''
10931091
Gets the dependency sizes for a given commit when dependencies were not resolved.
10941092
'''
1095-
print(f"Getting previous dependency sizes json for {base_commit=}")
1096-
run_id = get_run_id(base_commit, MEASURE_DISK_USAGE_WORKFLOW)
1097-
print(f"Previous run_id: {run_id}")
1098-
compressed_json = None
1099-
uncompressed_json = None
1100-
if run_id:
1101-
compressed_json = get_artifact(run_id, 'status_compressed.json')
1102-
if run_id:
1103-
uncompressed_json = get_artifact(run_id, 'status_uncompressed.json')
1104-
print(f"Compressed json: {compressed_json}")
1105-
print(f"Uncompressed json: {uncompressed_json}")
1106-
if not compressed_json or not uncompressed_json:
1107-
return None
1108-
return {
1109-
"compressed": compressed_json,
1110-
"uncompressed": uncompressed_json,
1111-
}
1093+
with tempfile.TemporaryDirectory() as tmpdir:
1094+
print(f"Getting previous dependency sizes json for {base_commit=}")
1095+
1096+
if (run_id := get_run_id(base_commit, MEASURE_DISK_USAGE_WORKFLOW)) is None:
1097+
return None
1098+
1099+
print(f"Previous run_id: {run_id}")
1100+
1101+
artifact_name = 'status_compressed.json' if compressed else 'status_uncompressed.json'
1102+
sizes_json = get_artifact(run_id, artifact_name, tmpdir)
1103+
1104+
if not sizes_json:
1105+
return None
1106+
1107+
print(f"Sizes json: {sizes_json}")
1108+
1109+
sizes = parse_sizes_json(sizes_json, platform, py_version, compressed)
1110+
1111+
sizes_path = Path(tmpdir) / f"{platform}_{py_version}.json"
1112+
with open(sizes_path, "w") as f:
1113+
json.dump(sizes, f, indent=2)
1114+
1115+
target_path = f"{platform}_{py_version}.json"
1116+
shutil.copy(sizes_path, target_path)
1117+
return Path(target_path)
11121118

11131119

11141120
@cache
11151121
def parse_sizes_json(
1116-
compressed_json_path: Path, uncompressed_json_path: Path, platform: str
1122+
sizes_json_path: Path, platform: str, py_version: str, compressed: bool
11171123
) -> dict[str, dict[str, int]]:
1118-
compressed_list = list(json.loads(compressed_json_path.read_text()))
1119-
uncompressed_list = list(json.loads(uncompressed_json_path.read_text()))
1124+
sizes_list = list(json.loads(sizes_json_path.read_text()))
1125+
size_key = "compressed" if compressed else "uncompressed"
11201126
sizes = {
11211127
dep["Name"]: {
1122-
"compressed": int(dep["Size_Bytes"]),
1128+
size_key: int(dep["Size_Bytes"]),
11231129
"version": dep.get("Version"),
1130+
"compression": compressed,
11241131
}
1125-
for dep in compressed_list
1126-
if dep.get("Type") == "Dependency" and dep.get("Platform") == platform
1132+
for dep in sizes_list
1133+
if dep.get("Type") == "Dependency"
1134+
and dep.get("Platform") == platform
1135+
and dep.get("Python_Version") == py_version
11271136
}
11281137

1129-
for dep in uncompressed_list:
1130-
if dep.get("Type") == "Dependency" and dep.get("Platform") == platform:
1131-
name = dep["Name"]
1132-
entry = sizes.setdefault(name, {"version": dep.get("Version")})
1133-
entry["uncompressed"] = int(dep["Size_Bytes"])
1134-
11351138
return sizes
11361139

11371140

ddev/tests/size/test_common.py

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -384,61 +384,38 @@ def test_parse_sizes_json(tmp_path):
384384
"Size": "2 B",
385385
"Type": "Dependency",
386386
"Platform": "linux-x86_64",
387+
"Python_Version": "3.12",
387388
},
388389
{
389390
"Name": "dep2",
390391
"Size_Bytes": 123,
391392
"Size": "2 B",
392393
"Type": "Dependency",
393394
"Platform": "macos-x86_64",
395+
"Python_Version": "3.12",
394396
},
395397
{
396398
"Name": "module1",
397399
"Size_Bytes": 123,
398400
"Size": "2 B",
399401
"Type": "Integration",
400402
"Platform": "linux-x86_64",
401-
},
402-
]
403-
)
404-
uncompressed_data = json.dumps(
405-
[
406-
{
407-
"Name": "dep1",
408-
"Size_Bytes": 456,
409-
"Size": "4 B",
410-
"Type": "Dependency",
411-
"Platform": "linux-x86_64",
412-
},
413-
{
414-
"Name": "dep2",
415-
"Size_Bytes": 456,
416-
"Size": "4 B",
417-
"Type": "Dependency",
418-
"Platform": "macos-x86_64",
419-
},
420-
{
421-
"Name": "module1",
422-
"Size_Bytes": 456,
423-
"Size": "4 B",
424-
"Type": "Integration",
425-
"Platform": "linux-x86_64",
403+
"Python_Version": "3.12",
426404
},
427405
]
428406
)
429407

430408
expected_output = {
431409
"dep1": {
432410
"compressed": 123,
433-
"uncompressed": 456,
411+
"compression": True,
434412
"version": None,
435413
}
436414
}
437415
compressed_json_path = tmp_path / "compressed.json"
438416
compressed_json_path.write_text(compressed_data)
439-
uncompressed_json_path = tmp_path / "uncompressed.json"
440-
uncompressed_json_path.write_text(uncompressed_data)
441-
result = parse_sizes_json(compressed_json_path, uncompressed_json_path, "linux-x86_64")
417+
418+
result = parse_sizes_json(compressed_json_path, "linux-x86_64", "3.12", True)
442419

443420
assert result == expected_output
444421

0 commit comments

Comments
 (0)