Skip to content

Commit 51fac7e

Browse files
committed
Separate hostapp artifacts from leviathan artifacts
Change-type: minor Signed-off-by: Kyle Harding <kyle@balena.io>
1 parent 47097d7 commit 51fac7e

File tree

1 file changed

+123
-94
lines changed

1 file changed

+123
-94
lines changed

.github/workflows/yocto-build-deploy.yml

Lines changed: 123 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -848,59 +848,107 @@ jobs:
848848
aws s3 sync --sse="${S3_SSE}" "${SHARED_DOWNLOADS_DIR}/" "${S3_URL}/" \
849849
--exclude "*/*" --exclude "*.tmp" --size-only --follow-symlinks --no-progress
850850
851+
# login required to pull private balena/balena-img image
852+
# https://github.com/docker/login-action
853+
- name: Login to Docker Hub
854+
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
855+
with:
856+
registry: docker.io
857+
username: ${{ secrets.DOCKERHUB_USER }}
858+
password: ${{ secrets.DOCKERHUB_TOKEN }}
859+
851860
# TODO: Unroll balena_deploy_artifacts into the workflow shell directly
852861
# and only package up what is needed for s3 deploy, hostapp deploy, and leviathan tests.
853-
# Note that the option to remove compressed files is set to true, as we want to avoid duplicate image files in the upload,
854-
# and they can be uncompressed in the s3 deploy step.
855-
- name: Prepare artifacts
862+
# https://github.com/balena-os/balena-yocto-scripts/blob/fe5debadae75e2b9cda9bd40aa2d0aced777860a/automation/include/balena-deploy.inc#L23
863+
- name: Prepare hostapp artifacts
856864
env:
857865
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
866+
# Note that this is the DEPLOY_PATH + the device slug and os version
867+
DEPLOY_PATH: ${{ github.workspace }}/deploy/${{ needs.balena-lib.outputs.device_slug }}/${{ needs.balena-lib.outputs.os_version }}
858868
run: |
859869
if ! command -v zip; then
860870
sudo apt-get update
861871
sudo apt-get install -y zip
862872
fi
863873
864874
source "${automation_dir}/include/balena-deploy.inc"
865-
# https://github.com/balena-os/balena-yocto-scripts/blob/fe5debadae75e2b9cda9bd40aa2d0aced777860a/automation/include/balena-deploy.inc#L23
866-
balena_deploy_artifacts "${SLUG}" "${DEPLOY_PATH}" true
875+
balena_deploy_artifacts "${SLUG}" "${DEPLOY_PATH}" false
867876
868877
cp -v "${WORKSPACE}/balena.yml" "${DEPLOY_PATH}/balena.yml"
869878
870879
du -cksh "${DEPLOY_PATH}"
871880
find "${DEPLOY_PATH}" -type f -exec du -h {} \;
872881
873-
tar -I zstd -cf "${ARTIFACTS_TAR}" -C "${DEPLOY_PATH}" .
874-
du -h "${ARTIFACTS_TAR}"
882+
- name: Prepare deflate files
883+
if: needs.balena-lib.outputs.deploy_artifact != 'docker-image'
884+
env:
885+
HELPER_IMAGE: balena/balena-img:6.20.26
886+
# This should be the root of DEPLOY_PATH from prepare hostapp artifacts
887+
DEPLOY_PATH: ${{ github.workspace }}/deploy
888+
run: |
889+
docker run --rm \
890+
-e BASE_DIR=/host/images \
891+
-v "${DEPLOY_PATH}:/host/images" \
892+
"${HELPER_IMAGE}" /usr/src/app/node_modules/.bin/ts-node /usr/src/app/scripts/prepare.ts
893+
894+
du -cksh "${DEPLOY_PATH}"
895+
find "${DEPLOY_PATH}" -exec ls -lh {} \;
875896
876-
# Encrypt artifacts and remove the original tarball so it doesn't get uploaded
877-
- name: Encrypt artifacts
897+
# Encrypt .img and .img.zip files and remove the originals
898+
- name: Encrypt signed/private artifacts
878899
if: inputs.sign-image || needs.balena-lib.outputs.is_private == 'true'
879900
env:
880-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
881-
ARTIFACTS_ENC: "${{ runner.temp }}/artifacts.tar.zst.enc"
901+
# This should be the root of DEPLOY_PATH from prepare hostapp artifacts
902+
DEPLOY_PATH: ${{ github.workspace }}/deploy
882903
PBDKF2_PASSPHRASE: ${{ secrets.PBDKF2_PASSPHRASE }}
883904
run: |
884-
openssl enc -v -e -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${ARTIFACTS_TAR}" -out "${ARTIFACTS_ENC}"
885-
rm "${ARTIFACTS_TAR}"
905+
set -x
906+
for file in "${DEPLOY_PATH}"/**/*.img "${DEPLOY_PATH}"/**/*.img.zip "${DEPLOY_PATH}"/**/*.docker "${DEPLOY_PATH}"/**/*.deflate; do
907+
openssl enc -v -e -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${file}" -out "${file}.enc"
908+
rm "${file}"
909+
done
886910
887-
# Upload either the encrypted or the unencrypted artifacts, whichever is present
888911
# https://github.com/actions/upload-artifact
889-
- name: Upload artifacts
912+
- name: Upload hostapp artifacts
890913
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
891914
env:
892-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
893-
ARTIFACTS_ENC: "${{ runner.temp }}/artifacts.tar.zst.enc"
915+
# Note that this is the DEPLOY_PATH + the device slug and os version
916+
DEPLOY_PATH: ${{ github.workspace }}/deploy/${{ needs.balena-lib.outputs.device_slug }}/${{ needs.balena-lib.outputs.os_version }}
894917
with:
895-
name: build-artifacts
918+
name: hostapp-artifacts
896919
if-no-files-found: error
897920
retention-days: 3
898-
# Change compression-level to 0 since we already compressed with zstd and
899-
# encrypted files cannot be compressed further.
921+
# Use 0 compression to avoid corrupting the encrypted files
900922
compression-level: 0
901923
path: |
902-
${{ env.ARTIFACTS_TAR }}
903-
${{ env.ARTIFACTS_ENC }}
924+
${{ env.DEPLOY_PATH }}/image/*.img.zip
925+
${{ env.DEPLOY_PATH }}/image/*.img.zip.enc
926+
${{ env.DEPLOY_PATH }}/compressed*/*.deflate
927+
${{ env.DEPLOY_PATH }}/compressed*/*.deflate.enc
928+
${{ env.DEPLOY_PATH }}/*.yml
929+
${{ env.DEPLOY_PATH }}/*.json
930+
${{ env.DEPLOY_PATH }}/*.md
931+
${{ env.DEPLOY_PATH }}/VERSION*
932+
${{ env.DEPLOY_PATH }}/*.manifest
933+
${{ env.DEPLOY_PATH }}/*.tar.gz
934+
935+
# https://github.com/actions/upload-artifact
936+
- name: Upload testing artifacts
937+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
938+
env:
939+
# Note that this is the DEPLOY_PATH + the device slug and os version
940+
DEPLOY_PATH: ${{ github.workspace }}/deploy/${{ needs.balena-lib.outputs.device_slug }}/${{ needs.balena-lib.outputs.os_version }}
941+
with:
942+
name: testing-artifacts
943+
if-no-files-found: error
944+
retention-days: 3
945+
# Use 0 compression to avoid corrupting the encrypted files
946+
compression-level: 0
947+
path: |
948+
${{ env.DEPLOY_PATH }}/image/*.img.zip
949+
${{ env.DEPLOY_PATH }}/image/*.img.zip.enc
950+
${{ env.DEPLOY_PATH }}/*.docker.enc
951+
${{ env.DEPLOY_PATH }}/*.tar.gz
904952
905953
##############################
906954
# hostapp Deploy
@@ -931,26 +979,26 @@ jobs:
931979
env:
932980
BALENARC_BALENA_URL: ${{ vars.BALENA_HOST || vars.BALENARC_BALENA_URL || 'balena-cloud.com' }}
933981
HOSTAPP_ORG: ${{ vars.HOSTAPP_ORG || 'balena_os' }}
934-
DEPLOY_PATH: ${{ github.workspace }}/deploy/${{ needs.balena-lib.outputs.device_slug }}/${{ needs.balena-lib.outputs.os_version }}
935-
# Same as DEPLOY_PATH but used by prepare.ts which expects the structure "/host/images/${device_slug}/${version}/..."
936-
PREPARE_DEPLOY_PATH: ${{ github.workspace }}/deploy
982+
DEPLOY_PATH: ${{ github.workspace }}/deploy
937983

938984
steps:
939985

940986
# Use gh to download the build artifacts from the build job
941987
# https://github.com/actions/download-artifact/issues/396#issuecomment-2796144940
942988
# https://cli.github.com/manual/gh_run_download
943989
# https://cli.github.com/manual/gh_help_environment
944-
- name: Download build artifacts
990+
- name: Download hostapp artifacts
945991
run: |
946-
gh run download "${GITHUB_RUN_ID}" --dir "${{ runner.temp }}" --name build-artifacts
992+
mkdir -p "${DEPLOY_PATH}"
993+
gh run download "${GITHUB_RUN_ID}" --dir "${DEPLOY_PATH}" --name hostapp-artifacts
947994
env:
948995
GH_TOKEN: ${{ github.token }}
949996
GH_REPO: ${{ github.repository }}
950997
GH_DEBUG: "true"
951998
GH_PAGER: "cat"
952999
GH_PROMPT_DISABLED: "true"
9531000
GH_SPINNER_DISABLED: "true"
1001+
DEPLOY_PATH: ${{ github.workspace }}/deploy
9541002

9551003
# # https://github.com/actions/download-artifact
9561004
# - name: Download build artifacts
@@ -962,24 +1010,20 @@ jobs:
9621010
- name: Decrypt artifacts
9631011
if: inputs.sign-image || needs.balena-lib.outputs.is_private == 'true'
9641012
env:
965-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
966-
ARTIFACTS_ENC: "${{ runner.temp }}/artifacts.tar.zst.enc"
9671013
PBDKF2_PASSPHRASE: ${{ secrets.PBDKF2_PASSPHRASE }}
1014+
DEPLOY_PATH: ${{ github.workspace }}/deploy
9681015
run: |
969-
openssl enc -v -d -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${ARTIFACTS_ENC}" -out "${ARTIFACTS_TAR}"
1016+
set -x
1017+
for enc in "${DEPLOY_PATH}"/**/*.enc; do
1018+
openssl enc -v -d -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${enc}" -out "${enc%.enc}"
1019+
done
9701020
971-
# Decompress the entire the entire tarball for the S3 upload.
972-
# Note that in this case DEPLOY_PATH includes <workspace>/deploy/${device_slug}/${version}/
973-
# List the contents of the tar file to make sure we're decompressing the right files.
9741021
# Unzip the raw image files that were zipped and removed before uploading.
9751022
- name: Decompress artifacts
9761023
env:
977-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
1024+
DEPLOY_PATH: ${{ github.workspace }}/deploy
9781025
run: |
9791026
set -x
980-
mkdir -p "${DEPLOY_PATH}"
981-
tar -tf "${ARTIFACTS_TAR}"
982-
tar -I zstd -xvf "${ARTIFACTS_TAR}" -C "${DEPLOY_PATH}"
9831027
9841028
if ! command -v unzip; then
9851029
sudo apt-get update
@@ -994,28 +1038,6 @@ jobs:
9941038
9951039
cp -v "${DEPLOY_PATH}/balena.yml" "${WORKSPACE}/balena.yml"
9961040
997-
# login required to pull private balena/balena-img image
998-
# https://github.com/docker/login-action
999-
- name: Login to Docker Hub
1000-
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
1001-
with:
1002-
registry: docker.io
1003-
username: ${{ secrets.DOCKERHUB_USER }}
1004-
password: ${{ secrets.DOCKERHUB_TOKEN }}
1005-
1006-
- name: Prepare deflate files
1007-
if: needs.balena-lib.outputs.deploy_artifact != 'docker-image'
1008-
env:
1009-
HELPER_IMAGE: balena/balena-img:6.20.26
1010-
PREPARE_DEPLOY_PATH: ${{ env.PREPARE_DEPLOY_PATH }}
1011-
run: |
1012-
docker run --rm \
1013-
-e BASE_DIR=/host/images \
1014-
-v "${PREPARE_DEPLOY_PATH}:/host/images" \
1015-
"${HELPER_IMAGE}" /usr/src/app/node_modules/.bin/ts-node /usr/src/app/scripts/prepare.ts
1016-
1017-
find "${PREPARE_DEPLOY_PATH}" -exec ls -lh {} \;
1018-
10191041
- name: Setup balena CLI
10201042
uses: balena-io-examples/setup-balena-action@41338eb4bb2b2e8b239d8ca5b8523d1a707333bf # v0.0.6
10211043
env:
@@ -1295,16 +1317,18 @@ jobs:
12951317
# https://github.com/actions/download-artifact/issues/396#issuecomment-2796144940
12961318
# https://cli.github.com/manual/gh_run_download
12971319
# https://cli.github.com/manual/gh_help_environment
1298-
- name: Download build artifacts
1320+
- name: Download hostapp artifacts
12991321
run: |
1300-
gh run download "${GITHUB_RUN_ID}" --dir "${{ runner.temp }}" --name build-artifacts
1322+
mkdir -p "${DEPLOY_PATH}"
1323+
gh run download "${GITHUB_RUN_ID}" --dir "${DEPLOY_PATH}" --name hostapp-artifacts
13011324
env:
13021325
GH_TOKEN: ${{ github.token }}
13031326
GH_REPO: ${{ github.repository }}
13041327
GH_DEBUG: "true"
13051328
GH_PAGER: "cat"
13061329
GH_PROMPT_DISABLED: "true"
13071330
GH_SPINNER_DISABLED: "true"
1331+
DEPLOY_PATH: ${{ github.workspace }}/deploy
13081332

13091333
# # https://github.com/actions/download-artifact
13101334
# - name: Download build artifacts
@@ -1316,24 +1340,20 @@ jobs:
13161340
- name: Decrypt artifacts
13171341
if: inputs.sign-image || needs.balena-lib.outputs.is_private == 'true'
13181342
env:
1319-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
1320-
ARTIFACTS_ENC: "${{ runner.temp }}/artifacts.tar.zst.enc"
13211343
PBDKF2_PASSPHRASE: ${{ secrets.PBDKF2_PASSPHRASE }}
1344+
DEPLOY_PATH: ${{ github.workspace }}/deploy
13221345
run: |
1323-
openssl enc -v -d -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${ARTIFACTS_ENC}" -out "${ARTIFACTS_TAR}"
1346+
set -x
1347+
for enc in "${DEPLOY_PATH}"/**/*.enc; do
1348+
openssl enc -v -d -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${enc}" -out "${enc%.enc}"
1349+
done
13241350
1325-
# Decompress the entire the entire tarball for the S3 upload.
1326-
# Note that in this case DEPLOY_PATH includes <workspace>/deploy/${device_slug}/${version}/
1327-
# List the contents of the tar file to make sure we're decompressing the right files.
13281351
# Unzip the raw image files that were zipped and removed before uploading.
13291352
- name: Decompress artifacts
13301353
env:
1331-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
1354+
DEPLOY_PATH: ${{ github.workspace }}/deploy
13321355
run: |
13331356
set -x
1334-
mkdir -p "${DEPLOY_PATH}"
1335-
tar -tf "${ARTIFACTS_TAR}"
1336-
tar -I zstd -xvf "${ARTIFACTS_TAR}" -C "${DEPLOY_PATH}"
13371357
13381358
if ! command -v unzip; then
13391359
sudo apt-get update
@@ -1478,16 +1498,18 @@ jobs:
14781498
# https://github.com/actions/download-artifact/issues/396#issuecomment-2796144940
14791499
# https://cli.github.com/manual/gh_run_download
14801500
# https://cli.github.com/manual/gh_help_environment
1481-
- name: Download build artifacts
1501+
- name: Download hostapp artifacts
14821502
run: |
1483-
gh run download "${GITHUB_RUN_ID}" --dir "${{ runner.temp }}" --name build-artifacts
1503+
mkdir -p "${DEPLOY_PATH}"
1504+
gh run download "${GITHUB_RUN_ID}" --dir "${DEPLOY_PATH}" --name hostapp-artifacts
14841505
env:
14851506
GH_TOKEN: ${{ github.token }}
14861507
GH_REPO: ${{ github.repository }}
14871508
GH_DEBUG: "true"
14881509
GH_PAGER: "cat"
14891510
GH_PROMPT_DISABLED: "true"
14901511
GH_SPINNER_DISABLED: "true"
1512+
DEPLOY_PATH: ${{ github.workspace }}/deploy
14911513

14921514
# # https://github.com/actions/download-artifact
14931515
# - name: Download build artifacts
@@ -1499,28 +1521,31 @@ jobs:
14991521
- name: Decrypt artifacts
15001522
if: inputs.sign-image || needs.balena-lib.outputs.is_private == 'true'
15011523
env:
1502-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
1503-
ARTIFACTS_ENC: "${{ runner.temp }}/artifacts.tar.zst.enc"
15041524
PBDKF2_PASSPHRASE: ${{ secrets.PBDKF2_PASSPHRASE }}
1525+
DEPLOY_PATH: ${{ github.workspace }}/deploy
15051526
run: |
1506-
openssl enc -v -d -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${ARTIFACTS_ENC}" -out "${ARTIFACTS_TAR}"
1527+
set -x
1528+
for enc in "${DEPLOY_PATH}"/**/*.enc; do
1529+
openssl enc -v -d -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${enc}" -out "${enc%.enc}"
1530+
done
15071531
1508-
# Only decompress the raw image file for the AMI creation
1509-
# List the contents of the tar file to make sure we're decompressing the right files
1532+
# Unzip the raw image files that were zipped and removed before uploading.
15101533
- name: Decompress artifacts
15111534
env:
1512-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
1535+
DEPLOY_PATH: ${{ github.workspace }}/deploy
15131536
run: |
1514-
mkdir -p "${DEPLOY_PATH}"
1515-
tar -tf "${ARTIFACTS_TAR}"
1516-
tar -I zstd -xvf "${ARTIFACTS_TAR}" -C "${DEPLOY_PATH}" ./image/balena.img.zip
1537+
set -x
15171538
15181539
if ! command -v unzip; then
15191540
sudo apt-get update
15201541
sudo apt-get install -y unzip
15211542
fi
15221543
1523-
unzip "${DEPLOY_PATH}/image/balena.img.zip" -d "${DEPLOY_PATH}/image/"
1544+
find "${DEPLOY_PATH}/image" -type f -name "*.img.zip"
1545+
1546+
for zip in "${DEPLOY_PATH}"/image/*.img.zip; do
1547+
unzip "${zip}" -d "$(dirname "${zip}")"
1548+
done
15241549
15251550
# https://github.com/unfor19/install-aws-cli-action
15261551
# https://github.com/aws/aws-cli/tags
@@ -2083,16 +2108,18 @@ jobs:
20832108
# https://github.com/actions/download-artifact/issues/396#issuecomment-2796144940
20842109
# https://cli.github.com/manual/gh_run_download
20852110
# https://cli.github.com/manual/gh_help_environment
2086-
- name: Download build artifacts
2111+
- name: Download testing artifacts
20872112
run: |
2088-
gh run download "${GITHUB_RUN_ID}" --dir "${{ runner.temp }}" --name build-artifacts
2113+
mkdir -p "${DEPLOY_PATH}"
2114+
gh run download "${GITHUB_RUN_ID}" --dir "${DEPLOY_PATH}" --name testing-artifacts
20892115
env:
20902116
GH_TOKEN: ${{ github.token }}
20912117
GH_REPO: ${{ github.repository }}
20922118
GH_DEBUG: "true"
20932119
GH_PAGER: "cat"
20942120
GH_PROMPT_DISABLED: "true"
20952121
GH_SPINNER_DISABLED: "true"
2122+
DEPLOY_PATH: ${{ github.workspace }}/deploy
20962123

20972124
# # https://github.com/actions/download-artifact
20982125
# - name: Download build artifacts
@@ -2104,26 +2131,28 @@ jobs:
21042131
- name: Decrypt artifacts
21052132
if: inputs.sign-image || needs.balena-lib.outputs.is_private == 'true'
21062133
env:
2107-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
2108-
ARTIFACTS_ENC: "${{ runner.temp }}/artifacts.tar.zst.enc"
21092134
PBDKF2_PASSPHRASE: ${{ secrets.PBDKF2_PASSPHRASE }}
2135+
DEPLOY_PATH: ${{ github.workspace }}/deploy
21102136
run: |
2111-
openssl enc -v -d -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${ARTIFACTS_ENC}" -out "${ARTIFACTS_TAR}"
2137+
set -x
2138+
for enc in "${DEPLOY_PATH}"/**/*.enc; do
2139+
openssl enc -v -d -aes-256-cbc -k "${PBDKF2_PASSPHRASE}" -pbkdf2 -iter 310000 -md sha256 -salt -in "${enc}" -out "${enc%.enc}"
2140+
done
21122141
2113-
# Only decompress the raw image file and the balena-image.docker file for the leviathan tests
2114-
# List the contents of the tar file to make sure we're decompressing the right files
2142+
# Unzip the raw image files that were zipped and removed before uploading.
21152143
- name: Decompress artifacts
21162144
env:
2117-
ARTIFACTS_TAR: "${{ runner.temp }}/artifacts.tar.zst"
2145+
DEPLOY_PATH: ${{ github.workspace }}/deploy
21182146
run: |
2119-
mkdir -p "${DEPLOY_PATH}"
2120-
tar -tf "${ARTIFACTS_TAR}"
2121-
tar -I zstd -xvf "${ARTIFACTS_TAR}" -C "${DEPLOY_PATH}" "./image/${BALENA_OS_IMAGE}.zip" ./balena-image.docker ./kernel_modules_headers.tar.gz
2147+
set -x
2148+
21222149
if ! command -v unzip; then
21232150
sudo apt-get update
21242151
sudo apt-get install -y unzip
21252152
fi
21262153
2154+
find "${DEPLOY_PATH}/image" -type f -name "*.img.zip"
2155+
21272156
unzip "${DEPLOY_PATH}/image/${BALENA_OS_IMAGE}.zip" -d "${DEPLOY_PATH}/image/"
21282157
21292158
# Check out private contracts if this is a private device type - as these are required for the tests

0 commit comments

Comments
 (0)