From 45f2aca73b8c48f0c456030d884c7d4c0c4deda0 Mon Sep 17 00:00:00 2001
From: Tim Jaacks <tim.jaacks@seco.com>
Date: Thu, 14 Sep 2023 11:57:46 +0200
Subject: [PATCH] Refactoring: remove parsing of testdata.json in package stage

Extract and save these variables in the build stage instead and
explicitly pass them as arguments to the package script.
---
 build-pipeline.yml         | 33 +++++++++++++++++++---
 scripts/package_release.py | 57 ++++++++++++++++----------------------
 2 files changed, 53 insertions(+), 37 deletions(-)

diff --git a/build-pipeline.yml b/build-pipeline.yml
index 89df3345..f4c09c78 100644
--- a/build-pipeline.yml
+++ b/build-pipeline.yml
@@ -111,12 +111,21 @@ workflow:
   - bitbake "${YOCTO_IMAGE}" -c "${BITBAKE_TASK}"
   - echo -e "section_end:`date +%s`:bitbake_run\r\e[0K"
 
+.source_bitbake_env: &source_bitbake_env
+  # Extract all variable assignments from the BitBake environment and source them.
+  # The rather complicated regex also regards values containing escaped quotes.
+  - source <( ${BITBAKE_ENV_COMMAND} | egrep '^[A-Z]\w*="([^\\"]+|\\.)*"$' )
+
 .save_build_env: &save_build_env
   - cd ${CI_PROJECT_DIR}
   # Artifact paths are needed for packaging
   - echo "IMAGE_PATH=${IMAGE_PATH}" > build.env
   - echo "SDK_PATH=${SDK_PATH}" >> build.env
   - echo "LICENSES_PATH=${LICENSES_PATH}" >> build.env
+  # SDK name, artifacts and images from the BitBake environment are needed for packaging
+  - echo "TOOLCHAIN_OUTPUTNAME=${TOOLCHAIN_OUTPUTNAME}" >> build.env
+  - echo "DISTRO_IMAGES='${DISTRO_IMAGES}'" >> build.env
+  - echo "DISTRO_RELEASE_ARTEFACTS='${DISTRO_RELEASE_ARTEFACTS}'" >> build.env
   # Install script location is needed in test job
   - echo "FNG_INSTALL_URL=${FNG_INSTALL_URL}" >> build.env
 
@@ -151,16 +160,13 @@ workflow:
   rules:
     - when: always
   variables:
-    BITBAKE_ENV_COMMAND: bitbake ${YOCTO_IMAGE} -e
     # RELEASE_VERSION_EXPRESSION and RELEASE_NAME_EXPRESSION are eval'ed and then saved
     # as RELEASE_VERSION and RELEASE_NAME to version.env, so we can use deferred
     # variable expansion or even command execution to construct their values.
     RELEASE_VERSION_EXPRESSION: $${DISTRO_VERSION}
     RELEASE_NAME_EXPRESSION: Yocto-$${RELEASE_VERSION}
   script:
-    # Extract all variable assignments from the BitBake environment and source them.
-    # The rather complicated regex also regards values containing escaped quotes.
-    - source <( ${BITBAKE_ENV_COMMAND} | egrep '^[A-Z]\w*="([^\\"]+|\\.)*"$' )
+    - *source_bitbake_env
     - echo ${RELEASE_VERSION_EXPRESSION}
     - echo ${RELEASE_NAME_EXPRESSION}
     - RELEASE_VERSION=$(eval echo "${RELEASE_VERSION_EXPRESSION}")
@@ -229,6 +235,7 @@ workflow:
     IMAGE_PATH: "${BUILD_PATH}/tmp/deploy/images/${MACHINE}"
     LICENSES_PATH: "${BUILD_PATH}/tmp/deploy/licenses"
     SDK_PATH: "${BUILD_PATH}/tmp/deploy/sdk"
+    BITBAKE_ENV_COMMAND: bitbake ${YOCTO_IMAGE} -e
     JOB_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/jobs/${CI_JOB_ID}"
     FNG_INSTALL_URL: "${JOB_URL}/artifacts/${IMAGE_PATH}/${INSTALL_SCRIPT}"
   before_script:
@@ -239,6 +246,7 @@ workflow:
   script:
     - *run_build
     - *collect_srcrevs
+    - *source_bitbake_env
     - *save_build_env
     - *dump_install_command
 
@@ -258,6 +266,15 @@ workflow:
     - wget -O artifacts.zip ${BUILD_ARTIFACTS}
     - unzip artifacts.zip
   after_script:
+    # FIXME: This is necessary because we're using an old build for the build simulation
+    # which does not export these variables, yet. Can be removed as soon as we switch to
+    # a newer release already containing these variables, then they can be read from the
+    # existing build.env from the cache.
+    # yamllint disable-line rule:line-length
+    - export TOOLCHAIN_OUTPUTNAME="seconorth-wayland-glibc-x86_64-seconorth-image-cortexa9t2hf-neon-$MACHINE-toolchain-kirkstone-7.0"
+    - export DISTRO_IMAGES="seconorth-image-$MACHINE.tar.gz"
+    # yamllint disable-line rule:line-length
+    - export DISTRO_RELEASE_ARTEFACTS="seconorth-image-$MACHINE.tar.gz fng-install.sh pkg.py"
     - *save_build_env
   cache:
     - *cache
@@ -341,6 +358,10 @@ workflow:
   script:
     # IMAGE_PATH, SDK_PATH and LICENSES_PATH are available via build.env from build job
     # RELEASE_NAME is available via version.env from build-version job
+    # FIXME: The "--sdk-name" argument shouldn't be necessary for the image package
+    # type. It is used only for the generation of "metainfo.json", which is used for the
+    # overview page on our FTP server, which is going to be replaced by Confluence. As
+    # soon as this is done, remove the "--sdk-name" argument from the image packaging.
     - if [[ "${PACKAGE_TYPE}" == "image" ]]; then
     - .gitlab-ci/scripts/package_release.py
         --images-dir="${IMAGE_PATH}"
@@ -349,12 +370,16 @@ workflow:
         --output-dir=${RELEASE_NAME}
         --release-version=${RELEASE_VERSION}
         --machine=${MACHINE}
+        --sdk-name="${TOOLCHAIN_OUTPUTNAME}"
+        --image-artifacts="${DISTRO_IMAGES}"
+        --artifacts="${DISTRO_RELEASE_ARTEFACTS}"
     - elif [[ "${PACKAGE_TYPE}" == "sdk" ]]; then
     - .gitlab-ci/scripts/package_release.py
         --sdk-dir="${SDK_PATH}"
         --output-dir=${RELEASE_NAME}
         --release-version=${RELEASE_VERSION}
         --machine=${MACHINE}
+        --sdk-name="${TOOLCHAIN_OUTPUTNAME}"
     - fi
   cache:
     - key: ${CI_PIPELINE_ID}-${ASSOCIATED_BUILD_JOB}
diff --git a/scripts/package_release.py b/scripts/package_release.py
index a131d904..0be68004 100755
--- a/scripts/package_release.py
+++ b/scripts/package_release.py
@@ -2,10 +2,8 @@
 import argparse
 import glob
 import hashlib
-import json
 import os
 import shutil
-import sys
 
 from convert_md2html import convertmd2html
 from generate_release_metadata import generate_metadata
@@ -98,37 +96,23 @@ def main():
         dest="machine",
         required=True,
     )
+    parser.add_argument(
+        "--sdk-name",
+        help="""Name of the SDK file""",
+        dest="sdk_name",
+    )
+    parser.add_argument(
+        "--image-artifacts",
+        help="""Space separated list of image artifacts""",
+        dest="image_artifacts",
+    )
+    parser.add_argument(
+        "--artifacts",
+        help="""Space separated list of artifacts""",
+        dest="artifacts",
+    )
     args, _ = parser.parse_known_args()
 
-    # Get bitbake variables from testdata.json file
-    testdata_files = []
-    if args.images_dir is not None:
-        testdata_files += glob.glob(os.path.join(args.images_dir, "*.testdata.json"))
-    if args.sdk_dir is not None:
-        testdata_files += glob.glob(os.path.join(args.sdk_dir, "*.testdata.json"))
-
-    # Debug output if no testdata file found
-    if not testdata_files:
-        if args.images_dir is not None:
-            print(args.images_dir)
-            for f in glob.glob(f"{args.images_dir}/*"):
-                print("-- ", f)
-        if args.sdk_dir is not None:
-            print(args.sdk_dir)
-            for f in glob.glob(f"{args.sdk_dir}/*"):
-                print("-- ", f)
-        sys.exit("ERROR: no *.testdata.json file found in image or sdk dir.")
-
-    # The required build variables from testdata have the same values for image and SDK
-    # builds, so we just read one of them.
-    with open(testdata_files[0], "r", encoding="utf-8") as f:
-        buildvars = json.load(f)
-
-    sdkname = buildvars["TOOLCHAIN_OUTPUTNAME"]
-    image_artifacts = buildvars["DISTRO_IMAGES"].split()
-    artifacts = buildvars["DISTRO_RELEASE_ARTEFACTS"].split()
-    artifacts.append("BUILD_SRCREVS.log")
-
     # Create output directory
     os.makedirs(args.output_dir, exist_ok=True)
 
@@ -154,6 +138,10 @@ def main():
 
     # Package image files
     if args.images_dir is not None:
+        image_artifacts = args.image_artifacts.split() if args.image_artifacts else []
+        artifacts = args.artifacts.split() if args.artifacts else []
+        artifacts.append("BUILD_SRCREVS.log")
+
         # Add some additional files to the artifacts
         for artifact in image_artifacts:
             artifacts.append(f"{artifact.split('.')[0]}.manifest")
@@ -180,11 +168,14 @@ def main():
         artifacts.append(image_md5sums_file)
 
         # Generate metadata file
+        # FIXME: This is used for the overview page on our FTP server, which is going to
+        # be replaced by Confluence. As soon as this is done, remove this and the
+        # "--sdk-name" argument from the image packaging call in build-pipeline.yml.
         generate_metadata(
             args.machine,
             args.release_version,
             artifacts,
-            sdkname,
+            args.sdk_name,
             os.path.join(args.images_dir, "metainfo.json"),
         )
         artifacts.append(os.path.join(args.images_dir, "metainfo.json"))
@@ -194,7 +185,7 @@ def main():
 
     # Package SDK
     if args.sdk_dir is not None:
-        sdkfiles = glob.glob(os.path.join(args.sdk_dir, f"{sdkname}*"))
+        sdkfiles = glob.glob(os.path.join(args.sdk_dir, f"{args.sdk_name}*"))
 
         # Generate MD5 sums file
         sdk_md5sums_file = os.path.join(args.machine, "sdk", "md5sums.txt")
-- 
GitLab