From bc1be0de56ed89a618e8f534b91e9e303ba5b6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Leinha=CC=88upl?= Date: Sun, 8 May 2022 18:13:50 +0200 Subject: [PATCH 1/5] =?UTF-8?q?=E2=9C=A8=20Load=20secrets=20from=20environ?= =?UTF-8?q?ment=20variables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++++++++-- Sources/ACKLocalizationCore/ACKLocalization.swift | 12 +++++++++++- Sources/ACKLocalizationCore/Constants.swift | 6 ++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 443123a..0bca7d0 100644 --- a/README.md +++ b/README.md @@ -84,12 +84,22 @@ Attributes documentation: | `apiKey` | ❌ | API key that will be used to communicate with Google Sheets API, `apiKey` or `serviceAccount` has to be provided | | `serviceAccount` | ❌ | Path to service account file that will be used to access spreadsheet, `apiKey` or `serviceAccount` has to be provided | | `spreadsheetID` | ✅ | Identifier of spreadsheet that should be downloaded | -| `spreadsheetTabName` | ❌ | Name of spreadsheet tab to be fetched, ff nothing is specified, we will use the first tab in spreadsheet | +| `spreadsheetTabName` | ❌ | Name of spreadsheet tab to be fetched, if nothing is specified, we will use the first tab in spreadsheet | | `stringsFileName` | ❌ | Name of strings file that should be generated | The file has to be in the same directory where you call ACKLocalization. -To be able to communicate with Google Sheets API, you need to provide either `apiKey` or `serviceAccount` parameter. If both are provided, then `serviceAccount` will be used. +To be able to communicate with Google Sheets API, you need to provide either `apiKey` or `serviceAccount` parameter or [use environment variable](#environment-variables). If both are provided, then `serviceAccount` will be used. + +### Environment variables + +Do you want to share secrets across multiple projects, or do you not want to keep secrets in the project repository? We have the solution for you. Just set one of the environment variables below. + +`ACKLOCALIZATION_SERVICE_ACCOUNT_PATH` - Path to service account file that will be used to access spreadsheet +`ACKLOCALIZATION_API_KEY` - API key that will be used to communicate with Google Sheets API + +`apiKey` or `serviceAccount` defined in `Configuration.json` have higher priority than environment values. +If both are provided then `ACKLOCALIZATION_SERVICE_ACCOUNT_PATH` will be used. ### Calling ACKLocalization diff --git a/Sources/ACKLocalizationCore/ACKLocalization.swift b/Sources/ACKLocalizationCore/ACKLocalization.swift index 340b62b..18310d1 100644 --- a/Sources/ACKLocalizationCore/ACKLocalization.swift +++ b/Sources/ACKLocalizationCore/ACKLocalization.swift @@ -277,8 +277,18 @@ public final class ACKLocalization { return fetchSheetValues(config.spreadsheetTabName, spreadsheetId: config.spreadsheetID, serviceAccount: serviceAccount) } else if let apiKey = config.apiKey { return fetchSheetValues(config.spreadsheetTabName, spreadsheetId: config.spreadsheetID, apiKey: apiKey) + } else if let serviceAccountPath = ProcessInfo.processInfo.environment[Constants.serviceAccountPath] { + let serviceAccount = try loadServiceAccount(from: serviceAccountPath) + return fetchSheetValues( + config.spreadsheetTabName, + spreadsheetId: config.spreadsheetID, + serviceAccount: serviceAccount + ) + } else if let apiKey = ProcessInfo.processInfo.environment[Constants.apiKey] { + let apiKey = APIKey(value: apiKey) + return fetchSheetValues(config.spreadsheetTabName, spreadsheetId: config.spreadsheetID, apiKey: apiKey) } else { - throw LocalizationError(message: "Either `apiKey` or `serviceAccount` must be provided in `localization.json` file") + throw LocalizationError(message: "Either `apiKey` or `serviceAccount` in `localization.json` file or environment variable must be provided.") } } catch { switch error { diff --git a/Sources/ACKLocalizationCore/Constants.swift b/Sources/ACKLocalizationCore/Constants.swift index 20ffc04..bbbc01c 100644 --- a/Sources/ACKLocalizationCore/Constants.swift +++ b/Sources/ACKLocalizationCore/Constants.swift @@ -14,4 +14,10 @@ public enum Constants { /// Regex pattern for suffix of the plural translations public static let pluralPattern = #"^([\w.]+)?##\{([\w]+)?\}$"# + + /// Environment variable key for providing service account path + public static let serviceAccountPath = "ACKLOCALIZATION_SERVICE_ACCOUNT_PATH" + + /// Environment variable key for providing API key + public static let apiKey = "ACKLOCALIZATION_API_KEY" } From 970ba02370be2ad4df48ddff07933042c52028da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Leinha=CC=88upl?= Date: Sun, 8 May 2022 18:49:42 +0200 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=93=84=20Update=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0bca7d0..584377a 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ Do you want to share secrets across multiple projects, or do you not want to kee `ACKLOCALIZATION_SERVICE_ACCOUNT_PATH` - Path to service account file that will be used to access spreadsheet `ACKLOCALIZATION_API_KEY` - API key that will be used to communicate with Google Sheets API -`apiKey` or `serviceAccount` defined in `Configuration.json` have higher priority than environment values. +`apiKey` or `serviceAccount` defined in `localization.json` have higher priority than environment values. If both are provided then `ACKLOCALIZATION_SERVICE_ACCOUNT_PATH` will be used. ### Calling ACKLocalization From 9e467a49dcc0da6e9c9a2d4d7774fbb407eba073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Leinha=CC=88upl?= Date: Sun, 8 May 2022 18:53:07 +0200 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=93=84=20Update=20CHANGELOG.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e8b7bd..89006d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ ## master +- Add support for loading secrets from environment variables ([#29](https://github.com/AckeeCZ/ACKLocalization/pull/29), kudos to @leinhauplk) + ## 1.2.0 ### Added From 75c030e802dbdd550d6de455502d6af6b779b922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Leinha=CC=88upl?= Date: Sun, 8 May 2022 18:58:01 +0200 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=93=84=20Update=20CHANGELOG.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89006d4..cc6b8c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ## master +### Added - Add support for loading secrets from environment variables ([#29](https://github.com/AckeeCZ/ACKLocalization/pull/29), kudos to @leinhauplk) ## 1.2.0 From 814a6e05986a14f431b99e2948e459249be6d510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Leinha=CC=88upl?= Date: Sun, 8 May 2022 20:05:52 +0200 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=91=8C=20Update=20error=20message?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/ACKLocalizationCore/ACKLocalization.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sources/ACKLocalizationCore/ACKLocalization.swift b/Sources/ACKLocalizationCore/ACKLocalization.swift index 18310d1..e158d42 100644 --- a/Sources/ACKLocalizationCore/ACKLocalization.swift +++ b/Sources/ACKLocalizationCore/ACKLocalization.swift @@ -288,7 +288,15 @@ public final class ACKLocalization { let apiKey = APIKey(value: apiKey) return fetchSheetValues(config.spreadsheetTabName, spreadsheetId: config.spreadsheetID, apiKey: apiKey) } else { - throw LocalizationError(message: "Either `apiKey` or `serviceAccount` in `localization.json` file or environment variable must be provided.") + let errorMessage = """ + Unable to load API key or service account path. Please check if: + + - `apiKey` or `serviceAccount` attribute is provided in `localization.json` file + or + - `\(Constants.apiKey)` or `\(Constants.serviceAccountPath)` environment variable is set + """ + + throw LocalizationError(message: errorMessage) } } catch { switch error {