Merge pull request #64 from DeterminateSystems/determine-env

Determine running environment
This commit is contained in:
Luc Perkins 2024-05-16 17:07:48 -04:00 committed by GitHub
commit 8f6369dd2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 118 additions and 99 deletions

View file

@ -5,18 +5,30 @@ on:
workflow_call:
jobs:
build-artifacts-ARM64-macOS:
runs-on: macos-latest-xlarge
build-artifacts:
runs-on: ${{ matrix.systems.runner }}
strategy:
matrix:
systems:
- nix-system: x86_64-linux
system: X64-Linux
runner: ubuntu-22.04
- nix-system: aarch64-linux
system: ARM64-Linux
runner: namespace-profile-default-arm64
- nix-system: x86_64-darwin
system: X64-macOS
runner: macos-12
- nix-system: aarch64-darwin
system: ARM64-macOS
runner: macos-latest-xlarge
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v3
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Build package
run: "nix build .# -L --fallback && nix-store --export $(nix-store -qR ./result) | xz -9 > magic-nix-cache.closure.xz"
@ -24,81 +36,6 @@ jobs:
uses: actions/upload-artifact@v3.1.2
with:
# Artifact name
name: magic-nix-cache-ARM64-macOS
path: magic-nix-cache.closure.xz
retention-days: 1
build-artifacts-X64-macOS:
runs-on: macos-12
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v3
- uses: DeterminateSystems/flake-checker-action@main
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Build package
run: "nix build .# -L --fallback && nix-store --export $(nix-store -qR ./result) | xz -9 > magic-nix-cache.closure.xz"
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.2
with:
# Artifact name
name: magic-nix-cache-X64-macOS
path: magic-nix-cache.closure.xz
retention-days: 1
build-artifacts-X64-Linux:
runs-on: ubuntu-22.04
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v3
- uses: DeterminateSystems/flake-checker-action@main
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Build package
run: "nix build .# -L --fallback && nix-store --export $(nix-store -qR ./result) | xz -9 > magic-nix-cache.closure.xz"
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.2
with:
# Artifact name
name: magic-nix-cache-X64-Linux
path: magic-nix-cache.closure.xz
retention-days: 1
build-artifacts-ARM64-Linux:
runs-on: namespace-profile-default-arm64
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v3
- uses: DeterminateSystems/flake-checker-action@main
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Build package
run: "nix build .# -L --fallback && nix-store --export $(nix-store -qR ./result) | xz -9 > magic-nix-cache.closure.xz"
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3.1.2
with:
# Artifact name
name: magic-nix-cache-ARM64-Linux
name: magic-nix-cache-${{ matrix.systems.system }}
path: magic-nix-cache.closure.xz
retention-days: 1

View file

@ -55,7 +55,7 @@
cargo-bloat
cargo-edit
cargo-udeps
cargo-watch
bacon
age
];

View file

@ -0,0 +1,50 @@
use std::fmt::{self, Display};
#[derive(Clone, Copy)]
pub enum Environment {
GitHubActions,
GitLabCI,
Other,
}
impl Environment {
pub fn determine() -> Self {
if env_var_is_true("GITHUB_ACTIONS") {
return Environment::GitHubActions;
}
if env_var_is_true("GITLAB_CI") {
return Environment::GitLabCI;
}
Environment::Other
}
pub fn is_github_actions(&self) -> bool {
matches!(self, Self::GitHubActions)
}
pub fn is_gitlab_ci(&self) -> bool {
matches!(self, Self::GitLabCI)
}
}
impl Display for Environment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Environment::*;
write!(
f,
"{}",
match self {
GitHubActions => "GitHub Actions",
GitLabCI => "GitLab CI",
Other => "an unspecified environment",
}
)
}
}
fn env_var_is_true(e: &str) -> bool {
std::env::var(e).is_ok_and(|v| v == "true")
}

View file

@ -1,3 +1,4 @@
use crate::env::Environment;
use crate::error::{Error, Result};
use attic::cache::CacheName;
use attic::nix_store::{NixStore, StorePath};
@ -27,6 +28,7 @@ pub struct State {
}
pub async fn init_cache(
environment: Environment,
flakehub_api_server: &Url,
flakehub_api_server_netrc: &Path,
flakehub_cache_server: &Url,
@ -102,22 +104,26 @@ pub async fn init_cache(
let api_inner = ApiClient::from_server_config(server_config)?;
let api = Arc::new(RwLock::new(api_inner));
// NOTE(cole-h): This is a workaround -- at the time of writing, GitHub Actions JWTs are only
// valid for 5 minutes after being issued. FlakeHub uses these JWTs for authentication, which
// means that after those 5 minutes have passed and the token is expired, FlakeHub (and by
// extension FlakeHub Cache) will no longer allow requests using this token. However, GitHub
// gives us a way to repeatedly request new tokens, so we utilize that and refresh the token
// every 2 minutes (less than half of the lifetime of the token).
let netrc_path_clone = flakehub_api_server_netrc.to_path_buf();
let initial_github_jwt_clone = flakehub_password.clone();
let flakehub_cache_server_clone = flakehub_cache_server.to_string();
let api_clone = api.clone();
tokio::task::spawn(refresh_github_actions_jwt_worker(
netrc_path_clone,
initial_github_jwt_clone,
flakehub_cache_server_clone,
api_clone,
));
// Periodically refresh JWT in GitHub Actions environment
if environment.is_github_actions() {
// NOTE(cole-h): This is a workaround -- at the time of writing, GitHub Actions JWTs are only
// valid for 5 minutes after being issued. FlakeHub uses these JWTs for authentication, which
// means that after those 5 minutes have passed and the token is expired, FlakeHub (and by
// extension FlakeHub Cache) will no longer allow requests using this token. However, GitHub
// gives us a way to repeatedly request new tokens, so we utilize that and refresh the token
// every 2 minutes (less than half of the lifetime of the token).
let netrc_path_clone = flakehub_api_server_netrc.to_path_buf();
let initial_github_jwt_clone = flakehub_password.clone();
let flakehub_cache_server_clone = flakehub_cache_server.to_string();
let api_clone = api.clone();
tokio::task::spawn(refresh_github_actions_jwt_worker(
netrc_path_clone,
initial_github_jwt_clone,
flakehub_cache_server_clone,
api_clone,
));
}
// Get the cache UUID for this project.
let cache_name = {

View file

@ -14,6 +14,7 @@
mod api;
mod binary_cache;
mod env;
mod error;
mod flakehub;
mod gha;
@ -112,6 +113,24 @@ struct Args {
startup_notification_url: Option<reqwest::Url>,
}
impl Args {
fn validate(&self, environment: env::Environment) -> Result<(), error::Error> {
if environment.is_gitlab_ci() && self.use_gha_cache {
return Err(error::Error::Config(String::from(
"the --use-gha-cache flag should not be applied in GitLab CI",
)));
}
if environment.is_gitlab_ci() && !self.use_flakehub {
return Err(error::Error::Config(String::from(
"you must set --use-flakehub in GitLab CI",
)));
}
Ok(())
}
}
/// The global server state.
struct StateInner {
/// State for uploading to the GHA cache.
@ -140,6 +159,9 @@ async fn main_cli() -> Result<()> {
init_logging();
let args = Args::parse();
let environment = env::Environment::determine();
tracing::debug!("Running in {}", environment.to_string());
args.validate(environment)?;
let metrics = Arc::new(telemetry::TelemetryReport::new());
@ -167,6 +189,7 @@ async fn main_cli() -> Result<()> {
let flakehub_flake_name = args.flakehub_flake_name;
match flakehub::init_cache(
environment,
&args
.flakehub_api_server
.ok_or_else(|| anyhow!("--flakehub-api-server is required"))?,
@ -240,7 +263,10 @@ async fn main_cli() -> Result<()> {
tracing::info!("Native GitHub Action cache is enabled.");
Some(gha_cache)
} else {
tracing::info!("Native GitHub Action cache is disabled.");
if environment.is_github_actions() {
tracing::info!("Native GitHub Action cache is disabled.");
}
None
};