Skip to content

Commit c251e2f

Browse files
authored
fix: harden CLI safety, S3 transport, and release workflows (#253)
1 parent 5f94138 commit c251e2f

33 files changed

Lines changed: 2693 additions & 1586 deletions

.github/workflows/ci.yml

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,25 @@ env:
1010
CARGO_TERM_COLOR: always
1111
RUST_BACKTRACE: 1
1212

13+
permissions:
14+
contents: read
15+
1316
jobs:
17+
advisories:
18+
name: Dependency Advisories
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
22+
- uses: EmbarkStudios/cargo-deny-action@bb137d7af7e4fb67e5f82a49c4fce4fad40782fe # v2
23+
with:
24+
command: check advisories
25+
1426
fmt:
1527
name: Format Check
1628
runs-on: ubuntu-latest
1729
steps:
18-
- uses: actions/checkout@v6
19-
- uses: dtolnay/rust-toolchain@stable
30+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
31+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
2032
with:
2133
components: rustfmt
2234
- name: Check formatting
@@ -26,11 +38,11 @@ jobs:
2638
name: Clippy
2739
runs-on: ubuntu-latest
2840
steps:
29-
- uses: actions/checkout@v6
30-
- uses: dtolnay/rust-toolchain@stable
41+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
42+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
3143
with:
3244
components: clippy
33-
- uses: Swatinem/rust-cache@v2
45+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
3446
- name: Run Clippy
3547
run: cargo clippy --workspace --all-targets -- -D warnings
3648

@@ -42,9 +54,9 @@ jobs:
4254
matrix:
4355
os: [ ubuntu-latest, macos-latest, windows-latest ]
4456
steps:
45-
- uses: actions/checkout@v6
46-
- uses: dtolnay/rust-toolchain@stable
47-
- uses: Swatinem/rust-cache@v2
57+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
58+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
59+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
4860
- name: Run tests
4961
# Don't use --all-features as integration/golden require external services
5062
# See integration.yml for those tests
@@ -58,19 +70,19 @@ jobs:
5870
matrix:
5971
os: [ ubuntu-latest, macos-latest, windows-latest ]
6072
steps:
61-
- uses: actions/checkout@v6
62-
- uses: dtolnay/rust-toolchain@stable
63-
- uses: Swatinem/rust-cache@v2
73+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
74+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
75+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
6476
- name: Build
6577
run: cargo build --workspace --release
6678

6779
doc:
6880
name: Documentation
6981
runs-on: ubuntu-latest
7082
steps:
71-
- uses: actions/checkout@v6
72-
- uses: dtolnay/rust-toolchain@stable
73-
- uses: Swatinem/rust-cache@v2
83+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
84+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
85+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
7486
- name: Build documentation
7587
run: cargo doc --workspace --no-deps
7688
env:
@@ -82,10 +94,12 @@ jobs:
8294
runs-on: ubuntu-latest
8395
if: github.event_name == 'pull_request'
8496
steps:
85-
- uses: actions/checkout@v6
97+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
8698
with:
8799
fetch-depth: 0
88100
- name: Check protected files
101+
env:
102+
PR_BODY: ${{ github.event.pull_request.body }}
89103
run: |
90104
PROTECTED_FILES=(
91105
"docs/reference/rc/"
@@ -103,7 +117,7 @@ jobs:
103117
echo "This change requires the Breaking Change process. See AGENTS.md."
104118
105119
# Check if PR body contains BREAKING marker
106-
if ! echo "${{ github.event.pull_request.body }}" | grep -q "BREAKING"; then
120+
if ! grep -q "BREAKING" <<< "$PR_BODY"; then
107121
echo "::error::Protected file $file modified without BREAKING marker in PR description"
108122
exit 1
109123
fi
@@ -115,10 +129,10 @@ jobs:
115129
name: Minimum Supported Rust Version
116130
runs-on: ubuntu-latest
117131
steps:
118-
- uses: actions/checkout@v6
119-
- uses: dtolnay/rust-toolchain@master
132+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
133+
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master
120134
with:
121135
toolchain: "1.92"
122-
- uses: Swatinem/rust-cache@v2
136+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
123137
- name: Build with MSRV
124138
run: cargo build --workspace

.github/workflows/docker.yml

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,62 @@ on:
1414
permissions:
1515
contents: read
1616

17-
env:
18-
image_tag: ${{ github.event.inputs.tag || github.event.workflow_run.head_branch || 'latest' }}
19-
2017
jobs:
2118
build-and-push:
19+
if: github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push')
2220
runs-on: ubuntu-latest
2321

2422
steps:
2523
- name: Checkout code
26-
uses: actions/checkout@v6
24+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
25+
with:
26+
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
27+
28+
- name: Resolve image tags
29+
id: image
30+
env:
31+
EVENT_NAME: ${{ github.event_name }}
32+
MANUAL_TAG: ${{ github.event.inputs.tag }}
33+
shell: bash
34+
run: |
35+
set -euo pipefail
36+
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
37+
image_tag="$MANUAL_TAG"
38+
else
39+
workspace_version=$(awk -F'"' '/^version = "/ { print $2; exit }' Cargo.toml)
40+
image_tag="v${workspace_version}"
41+
fi
42+
43+
if [[ ! "$image_tag" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$ ]]; then
44+
echo "Invalid Docker image tag: $image_tag"
45+
exit 1
46+
fi
47+
48+
{
49+
echo 'tags<<EOF'
50+
echo "rustfs/rc:${image_tag}"
51+
if [[ "$EVENT_NAME" == "workflow_run" && "$image_tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
52+
echo 'rustfs/rc:latest'
53+
fi
54+
echo 'EOF'
55+
} >> "$GITHUB_OUTPUT"
2756
2857
- name: Set up QEMU
29-
uses: docker/setup-qemu-action@v3
58+
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
3059

3160
- name: Set up Docker Buildx
32-
uses: docker/setup-buildx-action@v3
61+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
3362

3463
- name: Log in to Docker Hub
35-
uses: docker/login-action@v3
64+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
3665
with:
3766
username: ${{ secrets.DOCKERHUB_USERNAME }}
3867
password: ${{ secrets.DOCKERHUB_TOKEN }}
3968

4069
- name: Build and push image
41-
uses: docker/build-push-action@v6
70+
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
4271
with:
4372
context: .
4473
platforms: linux/amd64,linux/arm64
4574
push: true
46-
tags: |
47-
rustfs/rc:${{ env.image_tag }}
48-
rustfs/rc:latest
75+
tags: ${{ steps.image.outputs.tags }}

.github/workflows/integration.yml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@ env:
1616
TEST_S3_ACCESS_KEY: accesskey
1717
TEST_S3_SECRET_KEY: secretkey
1818

19+
permissions:
20+
contents: read
21+
1922
jobs:
2023
cli-contract:
2124
name: CLI Contract (Commands and Options)
2225
runs-on: ubuntu-latest
2326
timeout-minutes: 20
2427
steps:
25-
- uses: actions/checkout@v6
26-
- uses: dtolnay/rust-toolchain@stable
27-
- uses: Swatinem/rust-cache@v2
28+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
29+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
30+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
2831

2932
- name: Run CLI help contract tests
3033
run: cargo test --package rustfs-cli --test help_contract
@@ -34,9 +37,9 @@ jobs:
3437
runs-on: ubuntu-latest
3538
timeout-minutes: 30
3639
steps:
37-
- uses: actions/checkout@v6
38-
- uses: dtolnay/rust-toolchain@stable
39-
- uses: Swatinem/rust-cache@v2
40+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
41+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
42+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
4043

4144
- name: Start RustFS latest
4245
run: |
@@ -103,9 +106,9 @@ jobs:
103106
timeout-minutes: 90
104107
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
105108
steps:
106-
- uses: actions/checkout@v6
107-
- uses: dtolnay/rust-toolchain@stable
108-
- uses: Swatinem/rust-cache@v2
109+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
110+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
111+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
109112

110113
- name: Start RustFS latest
111114
run: |
@@ -139,6 +142,9 @@ jobs:
139142
- name: Run full integration suite
140143
run: cargo test --package rustfs-cli --test integration --features integration -- --test-threads=1
141144

145+
- name: Run S3 golden tests
146+
run: cargo test --package rustfs-cli --test golden --features golden,integration -- --test-threads=1
147+
142148
- name: Show RustFS logs on failure
143149
if: failure()
144150
run: docker logs rustfs 2>&1 | tail -200
@@ -148,9 +154,9 @@ jobs:
148154
runs-on: ubuntu-latest
149155
timeout-minutes: 20
150156
steps:
151-
- uses: actions/checkout@v6
152-
- uses: dtolnay/rust-toolchain@stable
153-
- uses: Swatinem/rust-cache@v2
157+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
158+
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 # stable
159+
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
154160

155161
- name: Run golden tests
156162
run: cargo test --package rustfs-cli --test golden --features golden

0 commit comments

Comments
 (0)