Skip to content

Commit f0dd629

Browse files
Revert "Revert "feat: update build to bundle from qchat pipeline (#308)" (#423)" (#502)
This reverts commit 3f8676b.
1 parent cd9c1b6 commit f0dd629

File tree

5 files changed

+96
-12
lines changed

5 files changed

+96
-12
lines changed

build-config/buildspec-linux-minimal.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ phases:
3636
# Disable tests that need fish/shellcheck
3737
- export AMAZON_Q_BUILD_SKIP_FISH_TESTS=1
3838
- export AMAZON_Q_BUILD_SKIP_SHELLCHECK_TESTS=1
39-
- python3.11 build-scripts/main.py build
39+
- python3.11 build-scripts/main.py build --chat-build-bucket-name "$CHAT_BUILD_BUCKET_NAME" --chat-download-role-arn "$CHAT_DOWNLOAD_ROLE_ARN"
4040

4141
artifacts:
4242
discard-paths: "yes"

build-config/buildspec-linux-ubuntu.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ phases:
4141
- export AMAZON_Q_BUILD_SKIP_FISH_TESTS=1
4242
- export AMAZON_Q_BUILD_SKIP_SHELLCHECK_TESTS=1
4343
- export GNOME_SHELL_BUILD_RELEASE=1
44-
- python3.11 build-scripts/main.py build --variant=full
44+
- python3.11 build-scripts/main.py build --variant=full --chat-build-bucket-name "$CHAT_BUILD_BUCKET_NAME" --chat-download-role-arn "$CHAT_DOWNLOAD_ROLE_ARN"
4545

4646
artifacts:
4747
discard-paths: "yes"

build-scripts/build-macos.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ while [[ $# -gt 0 ]]; do
3535
shift
3636
stage_name="$1"
3737
;;
38+
--chat-build-bucket-name)
39+
shift
40+
chat_build_bucket_name="$1"
41+
;;
42+
--chat-download-role-arn)
43+
shift
44+
chat_download_role_arn="$1"
45+
;;
3846
esac
3947
shift
4048
done
@@ -71,4 +79,6 @@ python3.11 build-scripts/main.py build \
7179
--aws-account-id "${aws_account_id:-}" \
7280
--signing-role-name "${signing_role_name:-}" \
7381
--stage-name "${stage_name:-}" \
82+
--chat-build-bucket-name "${chat_build_bucket_name:-}" \
83+
--chat-download-role-arn "${chat_download_role_arn:-}" \
7484
2>&1

build-scripts/build.py

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import boto3
2+
13
from dataclasses import dataclass
24
from functools import cache
35
import os
@@ -16,6 +18,7 @@
1618
run_cmd,
1719
run_cmd_output,
1820
info,
21+
warn,
1922
set_executable,
2023
version,
2124
tauri_product_name,
@@ -160,6 +163,66 @@ def build_cargo_bin(
160163
return out_path
161164

162165

166+
def fetch_chat_bin(chat_build_bucket_name: str | None, chat_download_role_arn: str | None) -> pathlib.Path:
167+
"""
168+
Downloads the chat binary from the provided bucket (using the IAM role to authenticate as).
169+
If the build bucket or role is not provided, then a dummy script is created and returned instead.
170+
171+
The returned path follows the convention: `{binary_name}-{target_triple}`
172+
"""
173+
info(f"Chat build bucket name: {chat_build_bucket_name}")
174+
info(f"IAM Role to assume: {chat_download_role_arn}")
175+
176+
# To prevent requiring a network request and S3 bucket for downloading the chat
177+
# binary (e.g. for local dev testing), we create a dummy script to bundle instead.
178+
if not chat_build_bucket_name or not chat_download_role_arn:
179+
warn("missing required chat arguments, creating dummy binary")
180+
dummy_dir = BUILD_DIR / "dummy_chat"
181+
dummy_dir.mkdir(exist_ok=True)
182+
dummy_path = dummy_dir / f"qchat-{get_target_triple()}"
183+
dummy_path.write_text("#!/usr/bin/env sh\n\necho dummy chat binary\n")
184+
set_executable(dummy_path)
185+
return dummy_path
186+
187+
"""Get S3 client with cross-account role credentials"""
188+
if profile_name := os.getenv("CHAT_BUILD_BUCKET_ACCESS_AWS_PROFILE"):
189+
info(f"Using AWS_PROFILE override {profile_name} for accessing the chat build bucket")
190+
session = boto3.Session(profile_name=profile_name)
191+
sts = session.client("sts")
192+
else:
193+
sts = boto3.client("sts")
194+
195+
# Assume the cross-account role
196+
response = sts.assume_role(RoleArn=chat_download_role_arn, RoleSessionName="QChatBuildBucketS3Access")
197+
creds = response["Credentials"]
198+
199+
# Return S3 client with assumed role credentials
200+
s3 = boto3.client(
201+
"s3",
202+
aws_access_key_id=creds["AccessKeyId"],
203+
aws_secret_access_key=creds["SecretAccessKey"],
204+
aws_session_token=creds["SessionToken"],
205+
)
206+
207+
# The path to the download should be:
208+
# BUILD_BUCKET/prod/latest/{target}/qchat.zip
209+
target = get_target_triple()
210+
chat_bucket_path = f"prod/latest/{target}/qchat.zip"
211+
chat_dl_dir = BUILD_DIR / "chat_download"
212+
chat_dl_dir.mkdir(exist_ok=True)
213+
chat_dl_path = chat_dl_dir / "qchat.zip"
214+
info(f"Downloading qchat zip from bucket: {chat_bucket_path} and path: {chat_bucket_path}")
215+
s3.download_file(chat_build_bucket_name, chat_bucket_path, chat_dl_path)
216+
217+
# unzip and return the path to the contained binary
218+
run_cmd(["unzip", "-o", chat_dl_path, "-d", chat_dl_dir])
219+
220+
# Append target triple, as expected by tauri cli.
221+
chat_path = chat_dl_dir / f"qchat-{target}"
222+
(chat_dl_dir / "qchat").rename(chat_path)
223+
return chat_path
224+
225+
163226
@cache
164227
def gen_manifest() -> str:
165228
return json.dumps(
@@ -215,6 +278,8 @@ def macos_tauri_config(cli_path: pathlib.Path, chat_path: pathlib.Path, pty_path
215278
"tauri": {
216279
"bundle": {
217280
"externalBin": [
281+
# Note that tauri bundling expects the target triple to be appended to each binary,
282+
# but in the config it must be strippled.
218283
str(cli_path).removesuffix(f"-{target}"),
219284
str(chat_path).removesuffix(f"-{target}"),
220285
str(pty_path).removesuffix(f"-{target}"),
@@ -794,6 +859,8 @@ def build(
794859
output_bucket: str | None = None,
795860
signing_bucket: str | None = None,
796861
aws_account_id: str | None = None,
862+
chat_build_bucket_name: str | None = None,
863+
chat_download_role_arn: str | None = None,
797864
apple_id_secret: str | None = None,
798865
signing_role_name: str | None = None,
799866
stage_name: str | None = None,
@@ -851,6 +918,11 @@ def build(
851918
for variant in variants:
852919
info(f"Building variant: {variant.name}")
853920

921+
info("Fetching", CHAT_PACKAGE_NAME)
922+
chat_path = fetch_chat_bin(
923+
chat_build_bucket_name=chat_build_bucket_name, chat_download_role_arn=chat_download_role_arn
924+
)
925+
854926
info("Building", CLI_PACKAGE_NAME)
855927
cli_path = build_cargo_bin(
856928
variant=variant,
@@ -861,16 +933,6 @@ def build(
861933
targets=targets,
862934
)
863935

864-
info("Building", CHAT_PACKAGE_NAME)
865-
chat_path = build_cargo_bin(
866-
variant=variant,
867-
release=release,
868-
package=CHAT_PACKAGE_NAME,
869-
output_name=CHAT_BINARY_NAME,
870-
features=cargo_features,
871-
targets=targets,
872-
)
873-
874936
info("Building", PTY_PACKAGE_NAME)
875937
pty_path = build_cargo_bin(
876938
variant=variant,

build-scripts/main.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ def __call__(self, parser, namespace, values, option_string=None):
3939
action=StoreIfNotEmptyAction,
4040
help="The AWS account ID",
4141
)
42+
build_subparser.add_argument(
43+
"--chat-build-bucket-name",
44+
action=StoreIfNotEmptyAction,
45+
help="The name of the bucket containing the chat binary",
46+
)
47+
build_subparser.add_argument(
48+
"--chat-download-role-arn",
49+
action=StoreIfNotEmptyAction,
50+
help="The IAM Role to assume when downloading from the chat build bucket",
51+
)
4252
build_subparser.add_argument(
4353
"--apple-id-secret",
4454
action=StoreIfNotEmptyAction,
@@ -116,6 +126,8 @@ def __call__(self, parser, namespace, values, option_string=None):
116126
output_bucket=args.output_bucket,
117127
signing_bucket=args.signing_bucket,
118128
aws_account_id=args.aws_account_id,
129+
chat_build_bucket_name=args.chat_build_bucket_name,
130+
chat_download_role_arn=args.chat_download_role_arn,
119131
apple_id_secret=args.apple_id_secret,
120132
signing_role_name=args.signing_role_name,
121133
stage_name=args.stage_name,

0 commit comments

Comments
 (0)