Skip to content

Commit 7393162

Browse files
authored
ci: change s3 cache provider to optimize costs (#2344)
1 parent f72bbef commit 7393162

File tree

20 files changed

+464
-248
lines changed

20 files changed

+464
-248
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
name: "aws_credentials"
3+
description: |
4+
Configure .aws/credentials file with provided access key ID and secret access key.
5+
6+
This action creates a credentials file in ${HOME}/.aws/credentials with the provided access key ID and secret access key.
7+
It also sets AWS_PROFILE and AWS_SHARED_CREDENTIALS_FILE environment variables to use this profile.
8+
9+
It can conflict with other actions that define AWS credentials or set AWS_PROFILE env variable.
10+
Explicitly set AWS_PROFILE=sccache and unset AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in case
11+
of conflicting settings.
12+
inputs:
13+
access_key_id:
14+
description: Access key ID
15+
required: true
16+
secret_access_key:
17+
description: Secret access key
18+
required: true
19+
profile:
20+
description: AWS profile to use; set AWS_PROFILE env variable to use this profile
21+
default: "default"
22+
23+
runs:
24+
using: composite
25+
steps:
26+
- name: Configure AWS credentials
27+
shell: bash
28+
run: |
29+
mkdir -p "${HOME}/.aws"
30+
cat >> ${HOME}/.aws/credentials << EOF
31+
[${{ inputs.profile }}]
32+
aws_access_key_id=${{ inputs.access_key_id }}
33+
aws_secret_access_key=${{ inputs.secret_access_key }}
34+
EOF
35+
chmod -R go-rwx ${HOME}/.aws
36+
37+
- name: Set env variables
38+
shell: bash
39+
run: |
40+
# Exit on any error
41+
set -euo pipefail
42+
# Validate AWS_PROFILE is not empty
43+
if [ -z "${{ inputs.profile }}" ]; then
44+
echo "Error: AWS_PROFILE cannot be empty"
45+
exit 1
46+
fi
47+
# Export variables
48+
echo "AWS_PROFILE=${{ inputs.profile }}" >> $GITHUB_ENV
49+
echo "AWS_SHARED_CREDENTIALS_FILE=${HOME}/.aws/credentials" >> $GITHUB_ENV
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
# Login to AWS ECR
3+
name: "aws_ecr_login"
4+
description: "Login to AWS ECR to store Docker containers"
5+
inputs:
6+
aws_account_id:
7+
description: AWS account ID (AWS_ACCOUNT_ID)
8+
required: true
9+
aws_access_key_id:
10+
description: Access key ID (AWS_ACCESS_KEY_ID)
11+
required: true
12+
aws_secret_access_key:
13+
description: Secret access key (AWS_SECRET_ACCESS_KEY)
14+
required: true
15+
aws_region:
16+
description: AWS region to use (AWS_REGION)
17+
required: true
18+
19+
runs:
20+
using: composite
21+
steps:
22+
- name: Configure AWS credentials and bucket region
23+
uses: aws-actions/configure-aws-credentials@v4
24+
with:
25+
aws-access-key-id: ${{ inputs.aws_access_key_id }}
26+
aws-secret-access-key: ${{ inputs.aws_secret_access_key }}
27+
aws-region: ${{ inputs.aws_region }}
28+
29+
- name: Login to ECR
30+
run: |
31+
aws ecr get-login-password \
32+
--region ${{ inputs.aws_region }} | docker login --username AWS --password-stdin ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com
33+
shell: bash
34+
35+
# Unset AWS credentials to avoid conflicts, as we prefer credentials from ~/.aws/credentials to authenticate
36+
- name: Unset AWS credentials to avoid conflicts
37+
shell: bash
38+
run: |
39+
echo AWS_DEFAULT_REGION='' >> $GITHUB_ENV
40+
echo AWS_REGION='' >> $GITHUB_ENV
41+
echo AWS_ACCESS_KEY_ID='' >> $GITHUB_ENV
42+
echo AWS_SECRET_ACCESS_KEY='' >> $GITHUB_ENV

.github/actions/docker/action.yaml

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
---
22
name: "Build and push docker image"
3-
description: "Build and push docker image by digest with Rust caching"
3+
description: |
4+
Build and push docker image by digest with extensive caching.
5+
6+
This action builds and pushes a Docker image to Docker Hub.
7+
It uses caching for Rust dependencies and Docker layers.
8+
It also provides sccache settings to the docker builder for caching Rust compilation.
9+
10+
Layers cache and sccache will use the same credentials and S3 bucket, but different prefixes.
411
inputs:
512
image_name:
613
description: Name of image in Docker Hub, like `drive`
@@ -25,21 +32,24 @@ inputs:
2532
cargo_profile:
2633
description: Cargo build profile, i.e release or dev
2734
default: dev
28-
bucket:
29-
description: S3 bucket to use for caching, must match runner define in `runs-on`
30-
default: multi-runner-cache-x1xibo9c
31-
region:
35+
cache_bucket:
36+
description: S3 bucket to use for caching (both sccache and layer cache)
37+
required: true
38+
cache_region:
3239
description: S3 bucket region
3340
required: true
34-
aws_access_key_id:
35-
description: AWS access key ID
41+
cache_endpoint:
42+
description: S3 endpoint to use for caching
43+
required: true
44+
cache_access_key_id:
45+
description: Access key ID for s3 cache
3646
required: true
37-
aws_secret_access_key:
38-
description: AWS secret access key
47+
cache_secret_access_key:
48+
description: Secret access key for s3 cache
3949
required: true
4050
cache_to_name:
41-
description: 'Save cache to name manifest (should be used only on default branch)'
42-
default: 'false'
51+
description: "Save cache to name manifest (should be used only on default branch)"
52+
default: "false"
4353
outputs:
4454
digest:
4555
value: ${{ steps.docker_build.outputs.digest }}
@@ -80,9 +90,13 @@ runs:
8090
id: layer_cache_settings
8191
with:
8292
name: ${{ inputs.image_name }}
83-
region: ${{ inputs.region }}
84-
bucket: ${{ inputs.bucket }}
93+
region: ${{ inputs.cache_region }}
94+
bucket: ${{ inputs.cache_bucket }}
95+
endpoint: ${{ inputs.cache_endpoint }}
96+
prefix: "cache-layers/${{ inputs.platform }}/"
8597
cache_to_name: ${{ inputs.cache_to_name }}
98+
s3_access_key_id: ${{ inputs.cache_access_key_id }}
99+
s3_secret_access_key: ${{ inputs.cache_secret_access_key }}
86100

87101
- name: Set HOME variable to github context
88102
shell: bash
@@ -133,7 +147,7 @@ runs:
133147
id: arch
134148
uses: actions/github-script@v6
135149
with:
136-
result-encoding: 'string'
150+
result-encoding: "string"
137151
script: return '${{ inputs.platform }}'.replace('linux/', '');
138152

139153
- name: Inject cargo cache into docker
@@ -148,9 +162,24 @@ runs:
148162
}
149163
skip-extraction: ${{ steps.yarn-cache.outputs.cache-hit }}
150164

165+
- name: Configure sccache settings
166+
uses: ./.github/actions/sccache
167+
id: sccache
168+
with:
169+
bucket: ${{ inputs.cache_bucket }}
170+
region: ${{ inputs.cache_region }}
171+
endpoint: ${{ inputs.cache_endpoint }}
172+
access_key_id: ${{ inputs.cache_access_key_id }}
173+
secret_access_key: ${{ inputs.cache_secret_access_key }}
174+
platform: ${{ inputs.platform }}
175+
install: false
176+
151177
- name: Build and push Docker image ${{ inputs.image }}
152178
id: docker_build
153179
uses: docker/build-push-action@v6
180+
env:
181+
# AWS profile to be used by layer cache; sccache settings are passed via build-args
182+
AWS_PROFILE: ${{ steps.layer_cache_settings.outputs.aws_profile }}
154183
with:
155184
context: .
156185
builder: ${{ steps.buildx.outputs.name }}
@@ -159,14 +188,9 @@ runs:
159188
push: ${{ inputs.push_tags }}
160189
tags: ${{ inputs.push_tags == 'true' && steps.docker_meta.outputs.tags || '' }}
161190
platforms: ${{ inputs.platform }}
162-
build-args: |
163-
CARGO_BUILD_PROFILE=${{ inputs.cargo_profile }}
164-
RUSTC_WRAPPER=sccache
165-
SCCACHE_BUCKET=${{ inputs.bucket }}
166-
SCCACHE_REGION=${{ inputs.region }}
167-
SCCACHE_S3_KEY_PREFIX=${{ runner.os }}/sccache
168-
AWS_ACCESS_KEY_ID=${{ inputs.aws_access_key_id }}
169-
AWS_SECRET_ACCESS_KEY=${{ inputs.aws_secret_access_key }}
191+
secret-files: |
192+
AWS=${{ env.HOME }}/.aws/credentials
193+
build-args: ${{ steps.sccache.outputs.env_vars }}
170194
cache-from: ${{ steps.layer_cache_settings.outputs.cache_from }}
171195
cache-to: ${{ steps.layer_cache_settings.outputs.cache_to }}
172196
outputs: type=image,name=${{ inputs.image_org }}/${{ inputs.image_name }},push-by-digest=${{ inputs.push_tags != 'true' }},name-canonical=true,push=true

.github/actions/librocksdb/action.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ inputs:
99
description: RocksDB version, eg. "8.10.2"
1010
required: false
1111
default: "8.10.2"
12-
bucket:
13-
description: S3 bucket to use for caching
14-
required: false
15-
default: multi-runner-cache-x1xibo9c
1612
force:
1713
description: Force rebuild
1814
required: false

.github/actions/rust/action.yaml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ runs:
3131
fi
3232
3333
echo "TOOLCHAIN_VERSION=$TOOLCHAIN_VERSION" >> $GITHUB_ENV
34-
echo "::set-output name=version::$TOOLCHAIN_VERSION"
34+
echo "version=$TOOLCHAIN_VERSION" >> $GITHUB_OUTPUT
3535
3636
- uses: dtolnay/rust-toolchain@master
3737
name: Install Rust toolchain
@@ -82,12 +82,6 @@ runs:
8282
echo "PROTOC=${HOME}/.local/bin/protoc" >> $GITHUB_ENV
8383
export PATH="${PATH}:${HOME}/.local/bin"
8484
85-
- name: Install sccache-cache
86-
uses: mozilla-actions/[email protected]
87-
with:
88-
version: "v0.8.2" # Must be the same as in Dockerfile
89-
if: inputs.cache == 'true'
90-
9185
- name: Set HOME variable to github context
9286
shell: bash
9387
run: echo "HOME=$HOME" >> $GITHUB_ENV

.github/actions/s3-layer-cache-settings/action.yaml

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,66 @@
1-
name: 'Get S3 Docker Layer Cache settings'
1+
name: "Get S3 Docker Layer Cache settings"
22
description: |
33
This action generates string with s3-based cache configuration for docker buildx.
44
It defines three manifests:
55
- name and current commit to hit all builds for this commit (restart) with this name
66
- name and head ref to hit all builds for this branch with this name
77
- just name to hit all builds for this name
88
9+
To correcly use caching, ensure buildx has AWS_PROFILE environment set to value of `aws_profile` output.
10+
911
inputs:
1012
name:
11-
description: 'Cache key name will be used as a prefix for all docker image manifests'
13+
description: "Cache key name will be used as a prefix for all docker image manifests"
1214
required: true
1315
head_ref:
14-
description: 'Head ref for an additional manifest to hit all builds for this head'
16+
description: "Head ref for an additional manifest to hit all builds for this head"
1517
default: ${{ github.ref }}
1618
region:
1719
description: S3 region
1820
required: true
1921
bucket:
2022
description: S3 bucket name
2123
required: true
24+
endpoint:
25+
description: S3 endpoint to use for caching
26+
required: false
2227
prefix:
2328
description: S3 key prefix
24-
default: 'cache-layers/'
29+
default: "cache-layers/"
30+
s3_access_key_id:
31+
description: Access key ID for S3 cache
32+
required: true
33+
s3_secret_access_key:
34+
description: Secret access key for S3 cache
35+
required: true
2536
mode:
2637
description: Cache mode
2738
default: max
2839
cache_to_name:
29-
description: 'Save cache to name manifest (should be used only on default branch)'
30-
default: 'false'
40+
description: "Save cache to name manifest (should be used only on default branch)"
41+
default: "false"
3142

3243
outputs:
3344
cache_to:
34-
description: 'String with s3-based cache configuration for docker buildx cache-to option'
45+
description: "String with s3-based cache configuration for docker buildx cache-to option"
3546
value: ${{ steps.script.outputs.cache_to }}
3647
cache_from:
37-
description: 'String with s3-based cache configuration for docker buildx cache-from option'
48+
description: "String with s3-based cache configuration for docker buildx cache-from option"
3849
value: ${{ steps.script.outputs.cache_from }}
50+
aws_profile:
51+
description: "AWS profile to use for s3 cache, to set inside AWS_PROFILE env var"
52+
value: layers
3953

4054
runs:
4155
using: composite
4256
steps:
57+
- name: Configure AWS credentials for s3 layers
58+
uses: ./.github/actions/aws_credentials
59+
with:
60+
access_key_id: ${{ inputs.s3_access_key_id }}
61+
secret_access_key: ${{ inputs.s3_secret_access_key }}
62+
profile: "layers"
63+
4364
- uses: actions/github-script@v6
4465
id: script
4566
with:
@@ -49,6 +70,7 @@ runs:
4970
region: '${{ inputs.region }}',
5071
bucket: '${{ inputs.bucket }}',
5172
prefix: '${{ inputs.prefix }}',
73+
endpoint_url: '${{ inputs.endpoint }}',
5274
};
5375
5476
const settingsString = Object.entries(settings)
@@ -59,7 +81,7 @@ runs:
5981
const sanitizedHeadRef = '${{ inputs.head_ref }}'.replace(/[^a-zA-Z0-9]/g, '-');
6082
6183
const shaManifestName = '${{ inputs.name }}_sha_${{ github.sha }}';
62-
const headRefManifestName = '${{ inputs.name }}_tag_${ sanitizedHeadRef }';
84+
const headRefManifestName = '${{ inputs.name }}_tag_' + sanitizedHeadRef;
6385
6486
const cacheFromManifestNames = [
6587
shaManifestName,

0 commit comments

Comments
 (0)