Artifacts Storage
π¦ Artifacts Repository Overview
The igaawi-artifacts repository is a dedicated storage for large static build artifacts used by the frontend application at runtime β such as ML model weights (*.bin), 3D models (*.glb, *.GLB), and other precomputed assets that should not live in the application source tree.
Because these files are large binary blobs, the repository uses Git LFS to keep the Git history light. Tracked patterns are defined in .gitattributes:
# glb files
*.glb filter=lfs diff=lfs merge=lfs-text
*.GLB filter=lfs diff=lfs merge=lfs-text
# tfjs model weight shards
*.bin filter=lfs diff=lfs merge=lfs-text
π Repository Layout
igaawi-artifacts/
βββ .github/
β βββ actions/sync_bucket/action.yaml # composite action: gzip + upload + invalidate
β βββ workflows/sync_bucket.yaml # manual workflow_dispatch entrypoint
βββ artifacts/ # source of truth for all delivered assets
βββ public/
βββ web/
Everything under artifacts/ is what ends up in the target S3 bucket β the directory structure is preserved as S3 keys.
π Delivery Flow
graph LR;
A[git push / LFS] --> B[igaawi-artifacts repo]
B --> C[GHA: Sync Bucket]
C --> D[gzip + aws s3 cp]
D --> E[(S3 bucket)]
E --> F[CloudFront]
F --> G[Frontend]
- A developer commits new/updated assets into
artifacts/(large files go through Git LFS). - A maintainer triggers the Sync Bucket workflow manually via
workflow_dispatch, choosing the target environment (development,staging,production). - The workflow assumes an AWS IAM role via GitHub OIDC, gzips every file in place, uploads the tree to S3 with
Content-Encoding: gzip, and β for production β creates a CloudFront invalidation. - The frontend and CloudFront read from the same bucket (see CloudFront).
π IAM Permissions
The IAM role used by GitHub Actions is provisioned by Terraform in
envs/prod/platforms/github/actions/prod.tfvars.
Only the igaawi-artifacts repository is allowed to assume this role via OIDC, and it is scoped to a single bucket plus one CloudFront distribution:
gha_roles = {
"github-actions-oidc" = {
identifier = "artifacts-s3",
description_policy = "Allows syncing build artifacts into the API backend S3 bucket"
description_role = "Role used by GHA to sync build artifacts into the API backend S3 bucket"
github_oidc_repositories = [
"igaawi-artifacts"
],
extra_oidc_iam_role_policies = [
{
actions = [
"s3:DeleteObject",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
]
resources = [
"arn:aws:s3:::igaawi-prod-api-backend-bucket",
"arn:aws:s3:::igaawi-prod-api-backend-bucket/*"
]
},
{
actions = [
"cloudfront:CreateInvalidation",
"cloudfront:GetInvalidation",
"cloudfront:ListInvalidations"
]
resources = [
"arn:aws:cloudfront::187528943262:distribution/E3V0XRM5MEK3WZ"
]
}
]
}
}
Key points:
- No long-lived AWS credentials β auth is done via GitHub OIDC, tokens are short-lived and scoped to the workflow run.
- The role can
Get/Put/Delete/Listonly onigaawi-prod-api-backend-bucket. - The role can create and read CloudFront invalidations only for distribution
E3V0XRM5MEK3WZβ the frontend distribution. - Trust policy accepts OIDC subjects only from
saritasa-nest/igaawi-artifacts, so no other repo in the org can borrow this role.
βοΈ Sync Workflow
The workflow is defined in .github/workflows/sync_bucket.yaml and delegates the heavy lifting to a composite action .github/actions/sync_bucket/action.yaml.
on:
workflow_dispatch:
inputs:
environment:
description: "Target environment"
type: choice
required: true
options:
- development
- staging
- production
The environment selector controls which set of GitHub Environment variables is used
(AWS_ROLE_ARN, AWS_DEFAULT_REGION, AWS_S3_BUCKET, CLOUDFRONT_DISTRIBUTION_ID).
CloudFront invalidation runs only for production, other environments just refresh the bucket.
What the composite action does
-
Install
aws-cliif the runner image doesn’t already have it. -
Configure AWS credentials via OIDC using
aws-actions/configure-aws-credentials@v4and the role ARN above. -
Gzip every file under
artifacts/in place withgzip -n -9, then strip the.gzsuffix so that S3 keys stay clean (artifacts/web/foo.bin, notartifacts/web/foo.bin.gz). -
Recursive upload via
aws s3 cp --recursivewith:--content-type application/octet-stream--content-encoding gzip
This lets browsers and CloudFront transparently decompress the payload, while we store and transfer it compressed.
-
Invalidate CloudFront (
/*) so the new artifacts are visible immediately β see CloudFront for details on how caching works.
π§ Related Docs
- CloudFront β how the frontend serves these artifacts through the CDN.
- CI/CD β how application code (not artifacts) is built and deployed.