Skip to content

Commit

Permalink
Merge pull request #199 from polac24/add-graceful-missing-common-sha
Browse files Browse the repository at this point in the history
Add support for graceful handling missing common sha
  • Loading branch information
polac24 authored Apr 20, 2023
2 parents dfb4039 + 1c67b79 commit 352e72f
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ Note: This step is not required if at least one of these is true:
| `disable_vfs_overlay` | A feature flag to disable virtual file system overlay support (temporary) | `false` | ⬜️ |
| `custom_rewrite_envs` | A list of extra ENVs that should be used as placeholders in the dependency list. ENV rewrite process is optimistic - does nothing if an ENV is not defined in the pre/postbuild process. | `[]` | ⬜️ |
| `irrelevant_dependencies_paths` | Regexes of files that should not be included in a list of dependencies. Warning! Add entries here with caution - excluding dependencies that are relevant might lead to a target overcaching. The regex can match either partially or fully the filepath, e.g. `\\.modulemap$` will exclude all `.modulemap` files. | `[]` | ⬜️ |
| `gracefully_handle_missing_common_sha` | If true, do not fail `prepare` if cannot find the most recent common commits with the primary branch. That might be useful on CI, where a shallow clone is used and cloning depth is not big enough to fetch a commit from a primary branch | `false` | ⬜️ |

## Backend cache server

Expand Down
13 changes: 12 additions & 1 deletion Sources/XCRemoteCache/Commands/Prepare/Prepare.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,18 @@ class Prepare: PrepareLogic {
guard fileAccessor.fileExists(atPath: PhaseCacheModeController.xcodeSelectLink.path) else {
throw PrepareError.missingXcodeSelectDirectory
}
let commonSha = try gitClient.getCommonPrimarySha()

let commonSha: String
do {
commonSha = try gitClient.getCommonPrimarySha()
} catch let GitClientError.noCommonShaWithPrimaryRepo(remoteName, error) {
guard context.gracefullyHandleMissingCommonSha else {
throw GitClientError.noCommonShaWithPrimaryRepo(remoteName: remoteName, error: error)
}
infoLog("Cannot find a common sha with the primary branch: \(error). Gracefully disabling remote cache")
try disable()
return .failed
}

if context.offline {
// Optimistically take first common sha
Expand Down
3 changes: 3 additions & 0 deletions Sources/XCRemoteCache/Commands/Prepare/PrepareContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public struct PrepareContext {
let cacheHealthPathProbeCount: Int
/// clang wrapper output file
let xcccCommand: URL
/// gracefully disable remote cache for missing common sha with the primary branch
let gracefullyHandleMissingCommonSha: Bool
}

extension PrepareContext {
Expand All @@ -77,5 +79,6 @@ extension PrepareContext {
cacheAddresses = try config.cacheAddresses.map(URL.build)
cacheHealthPath = config.cacheHealthPath
cacheHealthPathProbeCount = config.cacheHealthPathProbeCount
gracefullyHandleMissingCommonSha = config.gracefullyHandleMissingCommonSha
}
}
7 changes: 7 additions & 0 deletions Sources/XCRemoteCache/Config/XCRemoteCacheConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ public struct XCRemoteCacheConfig: Encodable {
/// Note: The regex can match either partially or fully the filepath, e.g. `\\.modulemap$` will exclude
/// all `.modulemap` files
var irrelevantDependenciesPaths: [String] = []
/// If true, do not fail `prepare` if cannot find the most recent common commits with the primary branch
/// That might useful on CI, where a shallow clone is used
var gracefullyHandleMissingCommonSha: Bool = false
}

extension XCRemoteCacheConfig {
Expand Down Expand Up @@ -206,6 +209,8 @@ extension XCRemoteCacheConfig {
merge.disableVFSOverlay = scheme.disableVFSOverlay ?? disableVFSOverlay
merge.customRewriteEnvs = scheme.customRewriteEnvs ?? customRewriteEnvs
merge.irrelevantDependenciesPaths = scheme.irrelevantDependenciesPaths ?? irrelevantDependenciesPaths
merge.gracefullyHandleMissingCommonSha =
scheme.gracefullyHandleMissingCommonSha ?? gracefullyHandleMissingCommonSha
return merge
}

Expand Down Expand Up @@ -273,6 +278,7 @@ struct ConfigFileScheme: Decodable {
let disableVFSOverlay: Bool?
let customRewriteEnvs: [String]?
let irrelevantDependenciesPaths: [String]?
let gracefullyHandleMissingCommonSha: Bool?

// Yams library doesn't support encoding strategy, see https://github.com/jpsim/Yams/issues/84
enum CodingKeys: String, CodingKey {
Expand Down Expand Up @@ -323,6 +329,7 @@ struct ConfigFileScheme: Decodable {
case disableVFSOverlay = "disable_vfs_overlay"
case customRewriteEnvs = "custom_rewrite_envs"
case irrelevantDependenciesPaths = "irrelevant_dependencies_paths"
case gracefullyHandleMissingCommonSha = "gracefully_handle_missing_common_sha"
}
}

Expand Down
62 changes: 62 additions & 0 deletions Tests/XCRemoteCacheTests/Commands/PrepareTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,66 @@ class PrepareTests: XCTestCase {

XCTAssertEqual(result, .preparedFor(sha: .init(sha: "2", age: 0), recommendedCacheAddress: remoteURL))
}

func testFailsForMissingCommonShaWhenConfiguredToGrefullyDisable() throws {
git = GitClientFake(shaHistory: [], primaryBranchIndex: 0)
config.gracefullyHandleMissingCommonSha = true

let prepare = Prepare(
context: try PrepareContext(config, offline: false),
gitClient: git,
networkClients: [],
ccBuilder: CCWrapperBuilderFake(),
fileAccessor: FileManager.default,
globalCacheSwitcher: globalCacheSwitcher,
cacheInvalidator: CacheInvalidatorFake()
)

let result = try prepare.prepare()

XCTAssertEqual(result, .failed)
}

func testDisablesGlobalCacheForMissingCommonShaWhenConfiguredToGrefullyDisable() throws {
git = GitClientFake(shaHistory: [], primaryBranchIndex: 0)
config.gracefullyHandleMissingCommonSha = true
try globalCacheSwitcher.enable(sha: "starting_state")

let prepare = Prepare(
context: try PrepareContext(config, offline: false),
gitClient: git,
networkClients: [],
ccBuilder: CCWrapperBuilderFake(),
fileAccessor: FileManager.default,
globalCacheSwitcher: globalCacheSwitcher,
cacheInvalidator: CacheInvalidatorFake()
)

_ = try prepare.prepare()

XCTAssertEqual(globalCacheSwitcher.state, .disabled)
}

func testThrowsForMissingCommonSha() throws {
git = GitClientFake(shaHistory: [], primaryBranchIndex: 0)
config.gracefullyHandleMissingCommonSha = false

let prepare = Prepare(
context: try PrepareContext(config, offline: false),
gitClient: git,
networkClients: [],
ccBuilder: CCWrapperBuilderFake(),
fileAccessor: FileManager.default,
globalCacheSwitcher: globalCacheSwitcher,
cacheInvalidator: CacheInvalidatorFake()
)

XCTAssertThrowsError(try prepare.prepare()) { error in
switch error {
case GitClientError.noCommonShaWithPrimaryRepo: break
default:
XCTFail("Not expected error")
}
}
}
}
5 changes: 4 additions & 1 deletion Tests/XCRemoteCacheTests/TestDoubles/GitClientFake.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class GitClientFake: GitClient {
}

func getCommonPrimarySha() throws -> String {
shaHistory[primaryBranchIndex].sha
guard shaHistory.count > primaryBranchIndex else {
throw GitClientError.noCommonShaWithPrimaryRepo(remoteName: "testing", error: "SampleError")
}
return shaHistory[primaryBranchIndex].sha
}

func getShaDate(sha: String) throws -> Date {
Expand Down

0 comments on commit 352e72f

Please sign in to comment.