diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml
index 830a7908b..5cbae4162 100644
--- a/.github/workflows/integration-tests.yml
+++ b/.github/workflows/integration-tests.yml
@@ -189,3 +189,52 @@ jobs:
${SCCACHE_PATH} --show-stats
${SCCACHE_PATH} --show-stats | grep -e "Cache hits\s*[1-9]"
+
+ gha:
+ runs-on: ubuntu-latest
+ needs: build
+
+ env:
+ SCCACHE_GHA_VERSION: "sccache_integration_tests"
+ RUSTC_WRAPPER: /home/runner/.cargo/bin/sccache
+
+ steps:
+ - name: Clone repository
+ uses: actions/checkout@v3
+
+ - name: Configure Cache Env
+ uses: actions/github-script@v6
+ with:
+ script: |
+ core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
+ core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
+
+ - name: Install rust
+ uses: ./.github/actions/rust-toolchain
+ with:
+ toolchain: "stable"
+
+ - uses: actions/download-artifact@v3
+ with:
+ name: integration-tests
+ path: /home/runner/.cargo/bin/
+ - name: Chmod for binary
+ run: chmod +x ${SCCACHE_PATH}
+
+ - name: Test
+ run: cargo clean && cargo build
+
+ - name: Output
+ run: |
+ ${SCCACHE_PATH} --show-stats
+
+ ${SCCACHE_PATH} --show-stats | grep gha
+
+ - name: Test Twice for Cache Read
+ run: cargo clean && cargo build
+
+ - name: Output
+ run: |
+ ${SCCACHE_PATH} --show-stats
+
+ ${SCCACHE_PATH} --show-stats | grep -e "Cache hits\s*[1-9]"
diff --git a/Cargo.lock b/Cargo.lock
index 2b1749a9e..ae3dd90df 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -127,16 +127,6 @@ dependencies = [
"tokio",
]
-[[package]]
-name = "async-lock"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685"
-dependencies = [
- "event-listener",
- "futures-lite",
-]
-
[[package]]
name = "async-trait"
version = "0.1.60"
@@ -908,34 +898,6 @@ dependencies = [
"wasm-bindgen",
]
-[[package]]
-name = "gha-toolkit"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56168956d9bb259029ae3187c78d618b4d001037898c50ec069d747690bdc5f3"
-dependencies = [
- "async-lock",
- "bytes",
- "futures",
- "hex",
- "http",
- "hyperx",
- "md-5",
- "reqwest",
- "reqwest-middleware",
- "reqwest-retry",
- "reqwest-retry-after",
- "reqwest-tracing",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sha2",
- "shell-escape",
- "thiserror",
- "tracing",
- "url",
-]
-
[[package]]
name = "gzp"
version = "0.11.1"
@@ -1588,9 +1550,9 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]]
name = "opendal"
-version = "0.22.6"
+version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c32203b1d5644a1cbd7b918a36269f59a055ff8c6c29f021a34b612a68234f07"
+checksum = "97541724cf371973b28f5a873404f2a2a4f7bb1efe7ca36a27836c13958781c2"
dependencies = [
"anyhow",
"async-compat",
@@ -1854,9 +1816,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quick-xml"
-version = "0.26.0"
+version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd"
+checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41"
dependencies = [
"memchr",
"serde",
@@ -2018,9 +1980,9 @@ dependencies = [
[[package]]
name = "reqsign"
-version = "0.7.3"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70bdb7e4031af194baaf4422662b753ae625400ed8d562b3b3530935e1a52a83"
+checksum = "1c97ac0f771c78ddf4bcb73c8454c76565a7249780e7296767f7e89661b0e045"
dependencies = [
"anyhow",
"backon",
@@ -2089,69 +2051,6 @@ dependencies = [
"winreg",
]
-[[package]]
-name = "reqwest-middleware"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69539cea4148dce683bec9dc95be3f0397a9bb2c248a49c8296a9d21659a8cdd"
-dependencies = [
- "anyhow",
- "async-trait",
- "futures",
- "http",
- "reqwest",
- "serde",
- "task-local-extensions",
- "thiserror",
-]
-
-[[package]]
-name = "reqwest-retry"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce246a729eaa6aff5e215aee42845bf5fed9893cc6cd51aeeb712f34e04dd9f3"
-dependencies = [
- "anyhow",
- "async-trait",
- "chrono",
- "futures",
- "http",
- "hyper",
- "reqwest",
- "reqwest-middleware",
- "retry-policies",
- "task-local-extensions",
- "tokio",
- "tracing",
-]
-
-[[package]]
-name = "reqwest-retry-after"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d80dd628f731727ef10bd58e09e5a6970ea130a9615c12da0d16579326482148"
-dependencies = [
- "async-trait",
- "reqwest",
- "reqwest-middleware",
- "task-local-extensions",
- "tokio",
-]
-
-[[package]]
-name = "reqwest-tracing"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64977f9a47fa7768cc88751e29026e569730ac1667c2eaeaac04b32624849fbe"
-dependencies = [
- "async-trait",
- "reqwest",
- "reqwest-middleware",
- "task-local-extensions",
- "tokio",
- "tracing",
-]
-
[[package]]
name = "retain_mut"
version = "0.1.9"
@@ -2167,17 +2066,6 @@ dependencies = [
"rand 0.8.5",
]
-[[package]]
-name = "retry-policies"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e09bbcb5003282bcb688f0bae741b278e9c7e8f378f561522c9806c58e075d9b"
-dependencies = [
- "anyhow",
- "chrono",
- "rand 0.8.5",
-]
-
[[package]]
name = "ring"
version = "0.16.20"
@@ -2333,7 +2221,6 @@ dependencies = [
"flate2",
"futures",
"futures-locks",
- "gha-toolkit",
"gzp",
"http",
"hyper",
@@ -2579,12 +2466,6 @@ dependencies = [
"digest",
]
-[[package]]
-name = "shell-escape"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
-
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
@@ -2717,15 +2598,6 @@ dependencies = [
"xattr",
]
-[[package]]
-name = "task-local-extensions"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4167afbec18ae012de40f8cf1b9bf48420abb390678c34821caa07d924941cc4"
-dependencies = [
- "tokio",
-]
-
[[package]]
name = "tempfile"
version = "3.3.0"
@@ -3018,21 +2890,9 @@ dependencies = [
"cfg-if 1.0.0",
"log",
"pin-project-lite",
- "tracing-attributes",
"tracing-core",
]
-[[package]]
-name = "tracing-attributes"
-version = "0.1.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "tracing-core"
version = "0.1.30"
diff --git a/Cargo.toml b/Cargo.toml
index 596d0ade7..8d257c652 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,7 +28,7 @@ bincode = "1"
blake3 = "1"
byteorder = "1.0"
bytes = "1"
-opendal = { version= "0.22.6", optional=true }
+opendal = { version= "0.24", optional=true }
reqsign = {version="0.7.3", optional=true}
chrono = { version = "0.4.23", optional = true }
clap = { version = "4.0.29", features = ["derive", "env", "wrap_help"] }
@@ -38,7 +38,6 @@ filetime = "0.2"
flate2 = { version = "1.0", optional = true, default-features = false, features = ["rust_backend"] }
futures = "0.3"
futures-locks = "0.7"
-gha-toolkit = { version = "0.3.1", optional = true }
gzp = { version = "0.11.1", default-features = false, features = ["deflate_rust"] }
http = "0.2"
hyper = { version = "0.14.10", optional = true, features = ["server"] }
@@ -123,7 +122,7 @@ all = ["dist-client", "redis", "s3", "memcached", "gcs", "azure", "gha"]
azure = ["opendal","reqsign"]
s3 = ["opendal","reqsign"]
gcs = ["opendal","reqsign", "url", "reqwest/blocking"]
-gha = ["gha-toolkit"]
+gha = ["opendal"]
memcached = ["memcached-rs"]
native-zlib = []
redis = ["url", "opendal/services-redis"]
diff --git a/docs/GHA.md b/docs/GHA.md
index 86249ac83..e5b222ac5 100644
--- a/docs/GHA.md
+++ b/docs/GHA.md
@@ -1,8 +1,8 @@
# GitHub Actions
-To use the [GitHub Actions cache](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows), you need to set the `SCCACHE_GHA_CACHE_URL`/`ACTIONS_CACHE_URL` and `SCCACHE_GHA_RUNTIME_TOKEN`/`ACTIONS_RUNTIME_TOKEN` environmental variables. The `SCCACHE_` prefixed environmental variables override the variables without the prefix.
+To use the [GitHub Actions cache](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows), you need to set the `SCCACHE_GHA_VERSION` which is a namespace for the whole cache set.
-In a GitHub Actions workflow, you can set these environmental variables using the following step.
+This cache type will needs token like `ACTIONS_CACHE_URL` and `ACTIONS_RUNTIME_TOKEN` to work. You can set these environmental variables using the following step in a GitHub Actions workflow.
```yaml
- name: Configure sccache
@@ -12,17 +12,3 @@ In a GitHub Actions workflow, you can set these environmental variables using th
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
```
-
-To write to the cache, set `SCCACHE_GHA_CACHE_TO` to a cache key, for example
-`sccache-latest`. To read from cache key prefixes, set `SCCACHE_GHA_CACHE_FROM`
-to a comma-separated list of cache key prefixes, for example `sccache-`.
-
-In contrast to the [`@actions/cache`](https://github.com/actions/cache) action, which saves a single large archive per cache key, `sccache` with GHA cache storage saves each cache entry separately.
-
-GHA cache storage will create many small caches with the same cache key, e.g. `SCCACHE_GHA_CACHE_TO` and `SCCACHE_GHA_CACHE_FROM`. These GHA caches are differentiated by their [_version_](https://github.com/actions/cache#cache-version). The GHA cache implementation in `sccache` calculates the cache version from the [`sccache` entry key](docs/Caching.md), e.g. the source file path.
-
-For example, if a cache entry has the version `main.rs` and has GHA cache entries for the `sccache-1` and `sccache-2` keys, then `SCCACHE_GHA_CACHE_FROM=sccache-` will match both and [return the most recent entry](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key).
-
-This behavior is useful for scoping caches from different versions of Rust or for cross-platform builds (`rust-sdk-{RUST_TOOLKIT}-{TARGET_TRIPLE}-`), and to allow newer commits to override older caches by adding the Git SHA as a suffix (`-{GITHUB_SHA}`), as in the following screenshot.
-
-
diff --git a/src/cache/cache.rs b/src/cache/cache.rs
index 8fb3d3ba1..46c6d4a45 100644
--- a/src/cache/cache.rs
+++ b/src/cache/cache.rs
@@ -394,6 +394,7 @@ impl Storage for opendal::Operator {
let can_write = match self.object(path).write("Hello, World!").await {
Ok(_) => true,
+ Err(err) if err.kind() == ErrorKind::ObjectAlreadyExists => true,
Err(err) if err.kind() == ErrorKind::ObjectPermissionDenied => false,
Err(err) => bail!("cache storage failed to write: {:?}", err),
};
@@ -485,15 +486,10 @@ pub fn storage_from_config(
return Ok(Arc::new(storage));
}
#[cfg(feature = "gha")]
- CacheType::GHA(config::GHACacheConfig {
- ref url,
- ref token,
- ref cache_to,
- ref cache_from,
- }) => {
- debug!("Init gha cache with url {url}");
+ CacheType::GHA(config::GHACacheConfig { ref version }) => {
+ debug!("Init gha cache with version {version}");
- let storage = GHACache::new(url, token, cache_to.clone(), cache_from.clone())
+ let storage = GHACache::build(version)
.map_err(|err| anyhow!("create gha cache failed: {err:?}"))?;
return Ok(Arc::new(storage));
}
diff --git a/src/cache/gha.rs b/src/cache/gha.rs
index 06ed18edf..29189ff67 100644
--- a/src/cache/gha.rs
+++ b/src/cache/gha.rs
@@ -12,82 +12,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-use std::io;
-use std::time::{Duration, Instant};
+use opendal::layers::LoggingLayer;
+use opendal::services::ghac;
+use opendal::Operator;
-use gha_toolkit::cache::*;
-
-use crate::cache::{Cache, CacheRead, CacheWrite, Storage};
use crate::errors::*;
-/// A cache that stores entries in Amazon S3.
-pub struct GHACache {
- client: CacheClient,
-}
+/// A cache that stores entries in GHA Cache Services.
+pub struct GHACache;
impl GHACache {
- /// Create a new `GHACache` storing data in `bucket`.
- pub fn new(
- url: &str,
- token: &str,
- cache_to: Option,
- cache_from: Option,
- ) -> Result {
- let mut builder = CacheClient::builder(url, token);
- if let Some(key) = cache_to {
- builder = builder.cache_to(key);
- }
- if let Some(cache_from) = cache_from {
- builder = builder.cache_from(
- cache_from
- .split(',')
- .map(str::trim)
- .filter(|s| !s.is_empty()),
- );
- }
- let client = builder.build()?;
- Ok(GHACache { client })
- }
-}
-
-#[async_trait]
-impl Storage for GHACache {
- async fn get(&self, key: &str) -> Result {
- let entry = self.client.entry(key).await?;
- if let Some(ArtifactCacheEntry {
- archive_location: Some(url),
- ..
- }) = entry
- {
- let data = self.client.get(&url).await?;
- let hit = CacheRead::from(io::Cursor::new(data))?;
- Ok(Cache::Hit(hit))
- } else {
- Ok(Cache::Miss)
- }
- }
-
- async fn put(&self, key: &str, entry: CacheWrite) -> Result {
- let start = Instant::now();
- let data = entry.finish()?;
- self.client.put(key, io::Cursor::new(data)).await?;
- Ok(start.elapsed())
- }
-
- fn location(&self) -> String {
- format!(
- "GHA, url: {}, cache_to: {:?}, cache_from: {:?}",
- self.client.base_url(),
- self.client.cache_to(),
- self.client.cache_from()
- )
- }
-
- async fn current_size(&self) -> Result