Skip to content

Commit 677bbbf

Browse files
committed
feat: enhance Makefile with improved artifact extraction and cleanup processes
1 parent b4424ff commit 677bbbf

File tree

1 file changed

+103
-74
lines changed

1 file changed

+103
-74
lines changed

Makefile

Lines changed: 103 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,135 @@
1-
PYTHON_VERSION ?= 3.13.3
1+
# ==============================================================================
2+
# Project: Python Build System (Containerized)
3+
# Description: Builds Python artifacts via a multi-stage container process.
4+
# ==============================================================================
5+
6+
# --- Configuration & Defaults -------------------------------------------------
7+
8+
# Shell safety flags: fail on error, fail on pipe error, fail on unset variables
9+
SHELL := /bin/bash
10+
.SHELLFLAGS := -eu -o pipefail -c
11+
12+
# Verbosity control: use 'make V=1' to see full commands
13+
ifeq ($(origin V), undefined)
14+
Q := @
15+
else
16+
Q :=
17+
endif
18+
19+
# Versioning
20+
PYTHON_VERSION ?= 3.13.3
221
ACTIONS_PYTHON_VERSIONS ?= 3.13.3-14344076652
3-
POWERSHELL_VERSION ?= v7.5.2
22+
POWERSHELL_VERSION ?= v7.5.2
423
POWERSHELL_NATIVE_VERSION ?= v7.4.0
5-
ARCH ?= $(shell uname -m)
6-
UBUNTU_VERSION ?= 24.04
7-
BASE_IMAGE ?= powershell:ubuntu-$(UBUNTU_VERSION)
24+
UBUNTU_VERSION ?= 24.04
25+
26+
# System Architecture (Computed Once)
27+
ARCH := $(shell uname -m)
28+
29+
# Container Engine Detection
830
CONTAINER_ENGINE := $(shell command -v podman 2>/dev/null || command -v docker)
931

1032
# Fail fast if no container runtime is available
1133
ifeq ($(strip $(CONTAINER_ENGINE)),)
12-
$(error No container runtime found (install `docker` or `podman` and ensure it's on PATH))
34+
$(error No container runtime found. Please install `docker` or `podman`)
1335
endif
1436

15-
# Deterministic temporary container name used to `create` a stopped
16-
# container so artifacts can be `cp`'d out. We build this name at Make
17-
# expansion time to avoid shell-variable quoting/escaping issues inside
18-
# multiline recipe lines.
19-
TEMP_CONTAINER_NAME := python-build-$(PYTHON_VERSION)-$(ARCH)-tmp
37+
# --- Internal Variables -------------------------------------------------------
2038

21-
# Output and artifact naming
39+
BASE_IMAGE := powershell:ubuntu-$(UBUNTU_VERSION)
40+
41+
# Naming conventions
2242
OUTPUT_DIR := python-versions/output
2343
IMAGE_NAME := python:$(PYTHON_VERSION)-ubuntu-$(UBUNTU_VERSION)-$(ARCH)
2444
ARTIFACT_NAME := python-$(PYTHON_VERSION)-linux-$(ARCH).tar.gz
25-
CONTAINER_NAME_PREFIX := python-build
2645

27-
.PHONY: all powershell clean help
46+
# Deterministic temporary container name for artifact extraction
47+
TEMP_CONTAINER_NAME := python-build-$(PYTHON_VERSION)-$(ARCH)-tmp
2848

29-
ifeq ($(findstring podman,$(CONTAINER_ENGINE)),podman)
30-
ifeq ($(shell uname),Linux)
31-
VOLUME_FLAG := -v $(abspath ./python-versions/output):/tmp/artifact:z
32-
else
33-
VOLUME_FLAG := -v ./python-versions/output:/tmp/artifact:z
34-
endif
35-
else
36-
VOLUME_FLAG := -v ./python-versions/output:/tmp/artifact
37-
endif
49+
# Prerequisite Files for PowerShell Build
50+
PS_DIR := PowerShell
51+
PS_PREREQS := \
52+
$(PS_DIR)/Dockerfile \
53+
$(PS_DIR)/patch/powershell-native-$(POWERSHELL_NATIVE_VERSION).patch \
54+
$(PS_DIR)/patch/powershell-$(ARCH)-$(POWERSHELL_VERSION).patch \
55+
$(PS_DIR)/patch/powershell-gen-$(POWERSHELL_VERSION).tar.gz
3856

39-
all: python-versions/output/python-$(PYTHON_VERSION)-linux-$(ARCH).tar.gz
57+
# --- Targets ------------------------------------------------------------------
58+
59+
.PHONY: all powershell clean help
4060

41-
.PHONY: powershell
61+
all: $(OUTPUT_DIR)/$(ARTIFACT_NAME)
4262

43-
python-versions/output/python-$(PYTHON_VERSION)-linux-$(ARCH).tar.gz: powershell
44-
cd python-versions; \
45-
mkdir -p $(abspath ../$(OUTPUT_DIR)); \
46-
$(CONTAINER_ENGINE) build \
63+
# 1. Build the Python Artifact
64+
# Depends on the PowerShell base image being ready.
65+
$(OUTPUT_DIR)/$(ARTIFACT_NAME): powershell | $(OUTPUT_DIR)
66+
@echo "--- Building Python $(PYTHON_VERSION) Image ---"
67+
$(Q)cd python-versions && $(CONTAINER_ENGINE) build \
4768
--network=host \
4869
--build-arg PYTHON_VERSION=$(PYTHON_VERSION) \
4970
--build-arg ACTIONS_PYTHON_VERSIONS=$(ACTIONS_PYTHON_VERSIONS) \
5071
--build-arg UBUNTU_VERSION=$(UBUNTU_VERSION) \
5172
--build-arg TARGETARCH=$(ARCH) \
5273
--build-arg BASE_IMAGE=$(BASE_IMAGE) \
53-
-t $(IMAGE_NAME) . || exit 1; \
54-
#
55-
# Use a deterministic temporary container name so we can reliably copy
56-
# artifacts out of the image even if the runtime prints nothing (some
57-
# container engines/modes may not return an id to backticks reliably).
58-
# note: TEMP_CONTAINER_NAME is defined above at Makefile parse time.
59-
# Ensure no stale container exists with the same name
60-
$(CONTAINER_ENGINE) rm -f $(TEMP_CONTAINER_NAME) 2>/dev/null || true; \
61-
$(CONTAINER_ENGINE) create --name $(TEMP_CONTAINER_NAME) $(IMAGE_NAME) >/dev/null || (echo "ERROR: failed to create container $(TEMP_CONTAINER_NAME)" && exit 1); \
62-
$(CONTAINER_ENGINE) cp $(TEMP_CONTAINER_NAME):/tmp/artifact/$(ARTIFACT_NAME) $(abspath ../$(OUTPUT_DIR))/$(ARTIFACT_NAME) || (echo "ERROR: failed to copy artifact from $(TEMP_CONTAINER_NAME)" && $(CONTAINER_ENGINE) rm -f $(TEMP_CONTAINER_NAME) >/dev/null 2>&1 || true; exit 1); \
63-
$(CONTAINER_ENGINE) cp $(TEMP_CONTAINER_NAME):/tmp/artifact/python-$(PYTHON_VERSION)-$(ARCH).sbom.json $(abspath ../$(OUTPUT_DIR))/python-$(PYTHON_VERSION)-linux-$(UBUNTU_VERSION)-$(ARCH).sbom.json || true; \
64-
$(CONTAINER_ENGINE) cp $(TEMP_CONTAINER_NAME):/tmp/artifact/trivy-$(PYTHON_VERSION)-$(ARCH)-vuln.json $(abspath ../$(OUTPUT_DIR))/trivy-python-$(PYTHON_VERSION)-linux-$(UBUNTU_VERSION)-$(ARCH)-vuln.json || true; \
65-
$(CONTAINER_ENGINE) cp $(TEMP_CONTAINER_NAME):/tmp/artifact/trivy-$(PYTHON_VERSION)-$(ARCH)-secret.json $(abspath ../$(OUTPUT_DIR))/trivy-python-$(PYTHON_VERSION)-linux-$(UBUNTU_VERSION)-$(ARCH)-secret.json || true; \
66-
$(CONTAINER_ENGINE) rm -f $(TEMP_CONTAINER_NAME) >/dev/null 2>&1 || true
67-
68-
powershell: PowerShell/Dockerfile \
69-
PowerShell/patch/powershell-native-$(POWERSHELL_NATIVE_VERSION).patch \
70-
PowerShell/patch/powershell-$(ARCH)-$(POWERSHELL_VERSION).patch \
71-
PowerShell/patch/powershell-gen-$(POWERSHELL_VERSION).tar.gz
72-
cd PowerShell; \
73-
$(CONTAINER_ENGINE) build \
74+
-t $(IMAGE_NAME) .
75+
76+
@echo "--- Extracting Artifacts ---"
77+
@# Ensure no stale container exists
78+
$(Q)$(CONTAINER_ENGINE) rm -f $(TEMP_CONTAINER_NAME) 2>/dev/null || true
79+
80+
@# Create stopped container for copying
81+
$(Q)$(CONTAINER_ENGINE) create --name $(TEMP_CONTAINER_NAME) $(IMAGE_NAME) >/dev/null
82+
83+
@# Copy artifacts using strict paths
84+
$(Q)$(CONTAINER_ENGINE) cp $(TEMP_CONTAINER_NAME):/tmp/artifact/$(ARTIFACT_NAME) $(abspath $(OUTPUT_DIR))/$(ARTIFACT_NAME)
85+
$(Q)$(CONTAINER_ENGINE) cp $(TEMP_CONTAINER_NAME):/tmp/artifact/python-$(PYTHON_VERSION)-$(ARCH).sbom.json \
86+
$(abspath $(OUTPUT_DIR))/python-$(PYTHON_VERSION)-linux-$(UBUNTU_VERSION)-$(ARCH).sbom.json || echo "Warning: SBOM missing"
87+
$(Q)$(CONTAINER_ENGINE) cp $(TEMP_CONTAINER_NAME):/tmp/artifact/trivy-$(PYTHON_VERSION)-$(ARCH)-vuln.json \
88+
$(abspath $(OUTPUT_DIR))/trivy-python-$(PYTHON_VERSION)-linux-$(UBUNTU_VERSION)-$(ARCH)-vuln.json || echo "Warning: Trivy Vuln report missing"
89+
$(Q)$(CONTAINER_ENGINE) cp $(TEMP_CONTAINER_NAME):/tmp/artifact/trivy-$(PYTHON_VERSION)-$(ARCH)-secret.json \
90+
$(abspath $(OUTPUT_DIR))/trivy-python-$(PYTHON_VERSION)-linux-$(UBUNTU_VERSION)-$(ARCH)-secret.json || echo "Warning: Trivy Secret report missing"
91+
92+
@# Cleanup
93+
$(Q)$(CONTAINER_ENGINE) rm -f $(TEMP_CONTAINER_NAME) >/dev/null
94+
@echo "Build complete: $(OUTPUT_DIR)/$(ARTIFACT_NAME)"
95+
96+
# 2. Build the Base PowerShell Image
97+
powershell: $(PS_PREREQS)
98+
@echo "--- Building PowerShell Base Image ---"
99+
$(Q)cd $(PS_DIR) && $(CONTAINER_ENGINE) build \
74100
--network=host \
75101
--build-arg POWERSHELL_VERSION=$(POWERSHELL_VERSION) \
76102
--build-arg POWERSHELL_NATIVE_VERSION=$(POWERSHELL_NATIVE_VERSION) \
77103
--build-arg UBUNTU_VERSION=$(UBUNTU_VERSION) \
78104
--build-arg TARGETARCH=$(ARCH) \
79105
--tag powershell:ubuntu-$(UBUNTU_VERSION) .
80106

81-
# Pattern rule to help diagnose missing patch files
82-
PowerShell/patch/%.tar.gz:
83-
@if [ ! -f "$@" ]; then \
84-
echo "Error: Required patch file $@ is missing."; \
85-
exit 1; \
86-
fi
107+
# Order-only prerequisite: Create output directory if it doesn't exist
108+
$(OUTPUT_DIR):
109+
$(Q)mkdir -p $@
87110

88-
# Show a short help message describing common targets
89-
help:
90-
echo "Usage: make [target]"
91-
echo "Common targets:"
92-
echo " all (default) - build the Python artifact and export to $(OUTPUT_DIR)"
93-
echo " powershell - build the PowerShell base image used as builder base"
94-
echo " clean - remove generated artifacts and temporary container"
95-
echo " help - show this message"
96-
97-
# Remove artifacts and any temporary container created by this Makefile.
98-
# This is conservative: it removes files under $(OUTPUT_DIR) and attempts
99-
# to remove the temporary container name used by the recipe. It does NOT
100-
# remove images by default to avoid surprising the user.
111+
# Diagnostic pattern rule for missing patches
112+
$(PS_DIR)/patch/%.tar.gz:
113+
$(error Required patch file $@ is missing)
114+
115+
# Cleanup
101116
clean:
102-
echo "Removing artifacts in $(OUTPUT_DIR)..."
103-
rm -rf $(OUTPUT_DIR) || true
104-
echo "Attempting to remove temporary container $(TEMP_CONTAINER_NAME) if present..."
105-
$(CONTAINER_ENGINE) rm -f $(TEMP_CONTAINER_NAME) >/dev/null 2>&1 || true
106-
echo "Clean complete."
117+
@echo "Cleaning up artifacts and temporary containers..."
118+
$(Q)rm -rf $(OUTPUT_DIR)
119+
$(Q)$(CONTAINER_ENGINE) rm -f $(TEMP_CONTAINER_NAME) 2>/dev/null || true
120+
@echo "Clean complete."
121+
122+
# Help
123+
help:
124+
@echo "Usage: make [target] [V=1]"
125+
@echo ""
126+
@echo "Targets:"
127+
@echo " all (default) Build Python artifact and export to $(OUTPUT_DIR)"
128+
@echo " powershell Build the PowerShell base image (builder dependency)"
129+
@echo " clean Remove artifacts and temporary containers"
130+
@echo " help Show this help message"
131+
@echo ""
132+
@echo "Variables:"
133+
@echo " PYTHON_VERSION = $(PYTHON_VERSION)"
134+
@echo " ARCH = $(ARCH)"
135+
@echo " ENGINE = $(CONTAINER_ENGINE)"

0 commit comments

Comments
 (0)