mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-12 17:01:05 +00:00
Sonar: shell, workflow, Rust, HTML and analysis-scope findings
See the pull request for each change.
This commit is contained in:
1 parent
71adfd4701
commit
4982e6e3aa
22 files changed
+53
-58
No files matched your search
@@ -46,7 +46,7 @@ jobs:
|
||||
node-version: lts/*
|
||||
|
||||
- name: install Rust stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable
|
||||
with:
|
||||
targets: ${{ matrix.platform == 'macos-latest-xlarge' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
|
||||
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
npm cache clean --force
|
||||
|
||||
echo "Installing all workspace dependencies..."
|
||||
npm ci
|
||||
npm ci --ignore-scripts
|
||||
|
||||
echo "=== Version Information ==="
|
||||
echo "Node version:"
|
||||
@@ -205,9 +205,8 @@ jobs:
|
||||
# Increase Node.js memory limit for the build
|
||||
export NODE_OPTIONS="--max-old-space-size=8192"
|
||||
|
||||
# Use npx to ensure we use the local nx version
|
||||
echo "Building with npx nx..."
|
||||
npx nx run artcraft:build
|
||||
echo "Building with nx..."
|
||||
./node_modules/.bin/nx run artcraft:build
|
||||
|
||||
echo "Checking build output..."
|
||||
# shellcheck disable=SC2012
|
||||
@@ -226,7 +225,7 @@ jobs:
|
||||
|
||||
|
||||
- name: build and publish
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
uses: tauri-apps/tauri-action@fce9c6108b31ea247710505d3aaaa893ee6768d4 # v0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: install Rust stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable
|
||||
|
||||
- name: install wreq dependencies
|
||||
run: |
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
npm cache clean --force
|
||||
|
||||
echo "Installing all workspace dependencies..."
|
||||
npm ci
|
||||
npm ci --ignore-scripts
|
||||
|
||||
echo "=== Version Information ==="
|
||||
echo "Node version:"
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
$config | ConvertTo-Json -Depth 10 | Set-Content tauri.conf.json
|
||||
|
||||
- name: build and publish
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
uses: tauri-apps/tauri-action@fce9c6108b31ea247710505d3aaaa893ee6768d4 # v0
|
||||
env:
|
||||
# NB(bt): This is needed by wreq. Hopefully it doesn't kill Tauri
|
||||
RUSTFLAGS: "-C target-feature=+crt-static"
|
||||
|
||||
Generated
+1
@@ -8075,6 +8075,7 @@ dependencies = [
|
||||
"sqlx",
|
||||
"tempfile",
|
||||
"tokens",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -21,10 +21,6 @@ impl TaskId {
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
self.0.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for TaskId {
|
||||
|
||||
+2
-2
@@ -141,8 +141,8 @@ mod tests {
|
||||
async fn test_requests() -> AnyhowResult<()> {
|
||||
setup_test_logging(LevelFilter::Debug);
|
||||
|
||||
let refresh_token = "AMf-vByUgA0J9S93vULECe-sD50cbR85AFVYF60gKAmLFF1MBYwXlKRJCsv7z3oSpLtP0ApyOU5fAl52qHWM2U0yKgEu5gQ5UCUDt5SEG4UBRHWvHEmLLcu-Zl04Fq4ljocSEO3qJzuX1wyshmptZxlDPRkjdLYgyn-Kp03woI2yRPKLuQF5hQtABHabsNUh9Zhs129sgxuUlOuw4zsFI4L8UdE3bEuF3k6Mic7KlE3440YwyQ8Qtmk9zHtXIx2ob56N-1WTGSqwMUuQ1mX4OOvLve9bw2zDW3UzchomTWkh732886RPrP-DNRkPbO3FejUEMxuYQFWYX3EEeIEdfNGXFNGPL1dNniSXlSaKadpX699Ishjviv-x9o-pPQa3zoAj3NzWLyd8mn5rDBh9qAO_iDETaeo01Sjhb4mGYfAWZ-g4S6nW778";
|
||||
let refresh_token = WorldLabsRefreshToken::new(refresh_token.to_string());
|
||||
let refresh_token = std::env::var("WORLDLABS_REFRESH_TOKEN")?;
|
||||
let refresh_token = WorldLabsRefreshToken::new(refresh_token);
|
||||
|
||||
let result = google_refresh_token(GoogleRefreshTokenArgs {
|
||||
refresh_token: &refresh_token,
|
||||
|
||||
+1
-4
@@ -31,8 +31,6 @@ use sqlite_tasks::queries::task::Task;
|
||||
use sqlite_tasks::queries::update_successful_task_status_with_metadata::{
|
||||
update_successful_task_status_with_metadata, UpdateSuccessfulTaskArgs,
|
||||
};
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
use tauri::AppHandle;
|
||||
@@ -255,8 +253,7 @@ async fn download_file(
|
||||
let filename = format!("fal_{}_{}.{}", generate_random_uuid(), index, extension);
|
||||
let download_path = tempdir.join(filename);
|
||||
|
||||
let mut file = File::create(&download_path)?;
|
||||
file.write_all(&bytes)?;
|
||||
tokio::fs::write(&download_path, &bytes).await?;
|
||||
|
||||
Ok(download_path)
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ async fn download_generated_results(
|
||||
}
|
||||
ensure!(!urls.is_empty(), "Completed task has no downloadable results");
|
||||
let path = checkpoint_path(root, task);
|
||||
let mut checkpoint: AutoDownloadCheckpoint = match std::fs::read(&path) {
|
||||
let mut checkpoint: AutoDownloadCheckpoint = match tokio::fs::read(&path).await {
|
||||
Ok(bytes) => serde_json::from_slice(&bytes)?,
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
AutoDownloadCheckpoint { download_time: Local::now(), saved: BTreeMap::new() }
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use errors::AnyhowResult;
|
||||
use reqwest::Client;
|
||||
use reqwest::Url;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
const USER_AGENT: &str = "storyteller-client/1.0";
|
||||
@@ -22,13 +20,7 @@ pub async fn simple_http_download<P: AsRef<Path>>(url: &Url, download_path: P) -
|
||||
//let response : Response = reqwest::get(url).await?;
|
||||
let bytes = response.bytes().await?;
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.create(true) // To create a new file
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.open(download_path)?;
|
||||
|
||||
file.write_all(&bytes)?;
|
||||
tokio::fs::write(download_path, &bytes).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+1
-4
@@ -33,8 +33,6 @@ use sqlite_tasks::queries::task::Task;
|
||||
use sqlite_tasks::queries::update_successful_task_status_with_metadata::{update_successful_task_status_with_metadata, UpdateSuccessfulTaskArgs};
|
||||
use sqlite_tasks::queries::update_task_status::{update_task_status, UpdateTaskArgs};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use artcraft_client::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
use artcraft_client::endpoints::media_files::get_media_file::get_media_file;
|
||||
@@ -213,8 +211,7 @@ async fn download_generation_item(
|
||||
|
||||
info!("Writing to path: {:?}", download_path);
|
||||
|
||||
let mut file = File::create(&download_path)?;
|
||||
file.write_all(&image_bytes)?;
|
||||
tokio::fs::write(&download_path, &image_bytes).await?;
|
||||
|
||||
Ok(download_path)
|
||||
}
|
||||
+1
-4
@@ -39,8 +39,6 @@ use sqlite_tasks::queries::task::Task;
|
||||
use sqlite_tasks::queries::update_successful_task_status_with_metadata::{update_successful_task_status_with_metadata, UpdateSuccessfulTaskArgs};
|
||||
use sqlite_tasks::queries::update_task_status::{update_task_status, UpdateTaskArgs};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
use artcraft_client::credentials::storyteller_credential_set::StorytellerCredentialSet;
|
||||
@@ -378,8 +376,7 @@ async fn download_spz(
|
||||
|
||||
info!("Writing to path: {:?}", download_path);
|
||||
|
||||
let mut file = File::create(&download_path)?;
|
||||
file.write_all(&image_bytes)?;
|
||||
tokio::fs::write(&download_path, &image_bytes).await?;
|
||||
|
||||
Ok(download_path)
|
||||
}
|
||||
@@ -19,6 +19,7 @@ tokens.workspace = true
|
||||
anyhow.workspace = true
|
||||
chrono.workspace = true
|
||||
log.workspace = true
|
||||
tokio = { workspace = true, features = ["fs"] }
|
||||
|
||||
# TODO(bt,2025-07-09): Update sqlx ASAP. We're stuck on 0.7 because of the complex use of internal types and macros in the database crate.
|
||||
# We're going to embed in-memory SQLite
|
||||
|
||||
@@ -22,7 +22,7 @@ impl TaskDbConnection {
|
||||
|
||||
info!("Deleting and recreating SQLite database at {:?}", database_file.as_ref());
|
||||
|
||||
if let Err(err) = std::fs::remove_file(&database_file) {
|
||||
if let Err(err) = tokio::fs::remove_file(&database_file).await {
|
||||
error!("Error deleting SQLite database file: {:?}", err);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="SwaggerUI" />
|
||||
<title>Storyteller API</title>
|
||||
<link rel="stylesheet" href="//unpkg.com/swagger-ui-dist@5.32.0/swagger-ui.css" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.32.0/swagger-ui.css" integrity="sha384-3nuX7df3EaAoiqLBeyS1Ola0Gpg9ryJKVtarubwfnA1cOH8AWHUdbPSIvEqPZ9VH" crossorigin="anonymous" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="//unpkg.com/swagger-ui-dist@5.32.0/swagger-ui-bundle.js" crossorigin></script>
|
||||
<script src="//unpkg.com/swagger-ui-dist@5.32.0/swagger-ui-standalone-preset.js" crossorigin></script>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@5.32.0/swagger-ui-bundle.js" integrity="sha384-7xcoc6ZKDFF7Ek627QTC3Bg/K+5Y36NJ8MWAE43D2m6+3Sh9XO3tdsfHhrS8gNIQ" crossorigin="anonymous"></script>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@5.32.0/swagger-ui-standalone-preset.js" integrity="sha384-FjFI+0PRyd5aAEoduVmUYk65iDC5+onNzam4WJtbAKKBim/kWvGUMk/2+9qRaYZb" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
window.onload = () => {
|
||||
window.ui = SwaggerUIBundle({
|
||||
|
||||
@@ -17,7 +17,7 @@ set -euxo pipefail
|
||||
echo 'TEMPORARY HACK: Build internal dependencies of artcraft since nx is not finding them...'
|
||||
|
||||
# A 'clean' will remove nx
|
||||
npm install
|
||||
npm install --ignore-scripts
|
||||
|
||||
# TODO: Temp commented out
|
||||
nx build "@storyteller/api"
|
||||
|
||||
@@ -37,11 +37,11 @@ rpmbuild --define "_topdir $work/rpmbuild" -bb rpmbuild/SPECS/artcraft.spec
|
||||
find rpmbuild/RPMS -name '*.rpm' -exec cp {} target/x86_64-unknown-linux-gnu/release/bundle/rpm/ \;
|
||||
printf 'appimage fixture\n' > target/x86_64-unknown-linux-gnu/release/bundle/appimage/ArtCraft.AppImage
|
||||
"$script" x86_64 x86_64-unknown-linux-gnu
|
||||
for format in deb rpm AppImage AppImage.zsync tar.gz; do test -s "dist/release/artcraft-0.42.0-linux-x86_64.$format"; done
|
||||
for format in deb rpm AppImage AppImage.zsync tar.gz; do [[ -s "dist/release/artcraft-0.42.0-linux-x86_64.$format" ]]; done
|
||||
mkdir unpacked
|
||||
tar -xzf dist/release/artcraft-0.42.0-linux-x86_64.tar.gz -C unpacked
|
||||
test -x unpacked/artcraft-0.42.0-linux-x86_64/bin/artcraft
|
||||
test -f unpacked/artcraft-0.42.0-linux-x86_64/share/applications/ai.artcraft.app.desktop
|
||||
[[ -x unpacked/artcraft-0.42.0-linux-x86_64/bin/artcraft ]]
|
||||
[[ -f unpacked/artcraft-0.42.0-linux-x86_64/share/applications/ai.artcraft.app.desktop ]]
|
||||
rm target/x86_64-unknown-linux-gnu/release/bundle/rpm/*.rpm
|
||||
if "$script" x86_64 x86_64-unknown-linux-gnu; then
|
||||
echo 'Packaging accepted a missing RPM' >&2
|
||||
|
||||
@@ -31,7 +31,7 @@ if [[ "${desktops[0]}" != "$work/$base/share/applications/ai.artcraft.app.deskto
|
||||
fi
|
||||
install -Dm644 "$script_dir/ai.artcraft.app.metainfo.xml" "$work/$base/share/metainfo/ai.artcraft.app.metainfo.xml"
|
||||
sed -i 's/^Name=.*/Name=ArtCraft Studio/' "$work/$base/share/applications/ai.artcraft.app.desktop"
|
||||
test -x "$work/$base/bin/artcraft"
|
||||
[[ -x "$work/$base/bin/artcraft" ]]
|
||||
case "$arch" in
|
||||
x86_64) machine='Advanced Micro Devices X86-64' ;;
|
||||
aarch64) machine='AArch64' ;;
|
||||
|
||||
@@ -15,7 +15,7 @@ config_path="${rust_crate_path}/tauri.conf.json"
|
||||
|
||||
pushd "${frontend_path}" || exit
|
||||
|
||||
npm install --verbose
|
||||
npm install --ignore-scripts --verbose
|
||||
|
||||
popd || exit
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ fi
|
||||
cd "${frontend_path}"
|
||||
if [[ ! -f node_modules/vite/package.json ]]; then
|
||||
# Do not use the legacy install helper: its failure recovery deletes caches.
|
||||
npm install
|
||||
npm install --ignore-scripts
|
||||
fi
|
||||
|
||||
exec node "${frontend_path}/scripts/unix-dev.mjs"
|
||||
@@ -9,7 +9,7 @@ echo ""
|
||||
|
||||
pushd "${frontend_path}" || exit
|
||||
|
||||
npm install --verbose
|
||||
npm install --ignore-scripts --verbose
|
||||
|
||||
export VITE_ENVIRONMENT_TYPE="production"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ fi
|
||||
|
||||
pushd "${frontend_path}" || exit
|
||||
|
||||
npm install --verbose
|
||||
npm install --ignore-scripts --verbose
|
||||
|
||||
export VITE_ENVIRONMENT_TYPE="production"
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ FRONTEND_MINIMUM_NODE_MAJOR=20
|
||||
frontend_preflight() {
|
||||
local frontend_path="$1"
|
||||
|
||||
if [ ! -d "${frontend_path}" ]; then
|
||||
if [[ ! -d "${frontend_path}" ]]; then
|
||||
echo "ERROR: frontend directory not found at: ${frontend_path}"
|
||||
echo "Run this script from the repository root."
|
||||
exit 1
|
||||
@@ -40,7 +40,7 @@ frontend_preflight() {
|
||||
# --- Node must be recent enough for Nx 21 / Vite 6 ---
|
||||
local node_major
|
||||
node_major=$(node --version | sed -E 's/^v([0-9]+).*/\1/')
|
||||
if [ "${node_major}" -lt "${FRONTEND_MINIMUM_NODE_MAJOR}" ]; then
|
||||
if [[ "${node_major}" -lt "${FRONTEND_MINIMUM_NODE_MAJOR}" ]]; then
|
||||
echo "ERROR: Node.js ${FRONTEND_MINIMUM_NODE_MAJOR}+ is required (found $(node --version))."
|
||||
echo "Upgrade via nvm ('nvm install --lts') or https://nodejs.org."
|
||||
exit 1
|
||||
@@ -50,13 +50,13 @@ frontend_preflight() {
|
||||
# pnpm was briefly adopted ("add pnpm to solve build issues") and then dropped
|
||||
# ("fix(frontend): consume video-editor libs via nx path aliases, drop pnpm").
|
||||
# A node_modules tree written by pnpm makes npm fail with ENOTEMPTY errors.
|
||||
if [ -e "${frontend_path}/pnpm-lock.yaml" ] \
|
||||
|| [ -e "${frontend_path}/pnpm-workspace.yaml" ] \
|
||||
|| [ -d "${frontend_path}/node_modules/.pnpm" ]; then
|
||||
if [[ -e "${frontend_path}/pnpm-lock.yaml" ]] \
|
||||
|| [[ -e "${frontend_path}/pnpm-workspace.yaml" ]] \
|
||||
|| [[ -d "${frontend_path}/node_modules/.pnpm" ]]; then
|
||||
echo "ERROR: Stale pnpm artifacts detected in ${frontend_path}."
|
||||
echo "The frontend uses npm (pnpm was dropped; see frontend/README.md)."
|
||||
echo "Clean up with:"
|
||||
echo " cd ${frontend_path} && rm -rf node_modules pnpm-lock.yaml pnpm-workspace.yaml && npm install"
|
||||
echo " cd ${frontend_path} && rm -rf node_modules pnpm-lock.yaml pnpm-workspace.yaml && npm install --ignore-scripts"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
@@ -66,7 +66,7 @@ frontend_preflight() {
|
||||
# layout causing ENOTEMPTY rename errors), wipe node_modules and the nx cache
|
||||
# and retry once before giving up.
|
||||
frontend_npm_install() {
|
||||
if npm install; then
|
||||
if npm install --ignore-scripts; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -77,7 +77,7 @@ frontend_npm_install() {
|
||||
|
||||
rm -rf node_modules .nx
|
||||
|
||||
if ! npm install; then
|
||||
if ! npm install --ignore-scripts; then
|
||||
echo ""
|
||||
echo "ERROR: npm install failed again. See the npm output above and the"
|
||||
echo "troubleshooting section in frontend/README.md."
|
||||
|
||||
@@ -6,3 +6,18 @@ sonar.organization=storytold
|
||||
# as filmcraft and lightcraft excluding tools/docs/examples.
|
||||
sonar.coverage.exclusions=**/*.ts,**/*.tsx,**/*.js,**/*.jsx
|
||||
|
||||
|
||||
# Not analysed: code that isn't ArtCraft's or isn't run by the app or CI.
|
||||
# - crates/vendor/: third-party crates kept in the tree.
|
||||
# - The Python beside the Grok and Sora clients: the upstream reference implementations the Rust ports
|
||||
# cite ("Based on Grok-Api/core/xctid.py"); nothing runs them.
|
||||
# - frontend/scripts/unix-dev.mjs and frontend/tools/performance/: developer tools run by hand
|
||||
# (script/artcraft/unix_dev.sh, `npm run perf:desktop`); they start git, cargo and a browser from
|
||||
# the developer's own PATH and write where the developer says.
|
||||
sonar.exclusions=crates/vendor/**,crates/api_clients/grok_consumer_client/src/credentials/_metadata/**,crates/api_clients/openai_sora_client/src/requests/auth_sentinel_2/metadata/python_impl/**,frontend/scripts/unix-dev.mjs,frontend/tools/performance/**
|
||||
|
||||
# S4347 (predictable seed): DeterministicRng is the fixed-seed generator for tests and dev seed
|
||||
# tools; being reproducible is its purpose.
|
||||
sonar.issue.ignore.multicriteria=deterministic_rng
|
||||
sonar.issue.ignore.multicriteria.deterministic_rng.ruleKey=rust:S4347
|
||||
sonar.issue.ignore.multicriteria.deterministic_rng.resourceKey=crates/schema/public/tokens/src/deterministic_rng.rs
|
||||
Reference in new issue
Block a user