diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..36550c95 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,34 @@ +version: 2 +updates: + # Cargo: security updates only, bundled into a single PR. + # + # This repo does not take routine version bumps -- `open-pull-requests-limit: 0` + # disables version updates while leaving Dependabot security updates enabled. + # Without the group below, each advisory opens its own PR (see #280, #283, + # #288, #289, #290, all of which sat open for months after the underlying + # bumps had already landed). + - package-ecosystem: cargo + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 0 + groups: + cargo-security: + applies-to: security-updates + patterns: + - "*" + + # GitHub Actions: group both version and security updates into one PR each. + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + groups: + actions-version: + applies-to: version-updates + patterns: + - "*" + actions-security: + applies-to: security-updates + patterns: + - "*" diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index c233f295..f43f0391 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest name: List screens steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - id: list-screens uses: screenly/cli@master with: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 16886a61..475b11a2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,8 +20,8 @@ jobs: docs_command_line_help: ${{ steps.filter.outputs.docs_command_line_help }} docs_edge_apps: ${{ steps.filter.outputs.docs_edge_apps }} steps: - - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v3 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3 id: filter with: list-files: shell @@ -40,13 +40,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Install Rust - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - target: x86_64-unknown-linux-gnu + run: | + rustup toolchain install stable --profile minimal + rustup default stable + rustup target add x86_64-unknown-linux-gnu - name: Generate documentation run: cargo run -- print-help-markdown > /tmp/CommandLineHelp.md diff --git a/.github/workflows/fmt.yml b/.github/workflows/fmt.yml index d30b1bca..e5beb621 100644 --- a/.github/workflows/fmt.yml +++ b/.github/workflows/fmt.yml @@ -12,13 +12,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: submodules: recursive ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} - - uses: dtolnay/rust-toolchain@nightly - with: - components: rustfmt + - name: Install rustfmt + run: rustup component add rustfmt - name: Run rustfmt check id: fmt diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b7cf69d7..aeb94a4d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,17 +7,17 @@ on: paths: - "**.rs" - "Cargo.toml" + - ".github/workflows/lint.yml" pull_request: branches: - master paths: - "**.rs" - "Cargo.toml" + - ".github/workflows/lint.yml" permissions: contents: read - pull-requests: write - checks: write jobs: lint: @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: submodules: recursive ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} @@ -33,8 +33,8 @@ jobs: - name: Install dependencies run: sudo apt -q -yy install libdbus-1-dev pkg-config libdbus-1-3 libsystemd0 libsystemd-dev - - name: rust-clippy-check - uses: actions-rs/clippy-check@v1.0.7 - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --manifest-path Cargo.toml + - name: Install clippy + run: rustup component add clippy + + - name: Run clippy + run: cargo clippy --manifest-path Cargo.toml --all-targets -- -D warnings diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index fa4f7ac7..29eb7cb9 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -33,13 +33,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout flake - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Install nix - uses: DeterminateSystems/nix-installer-action@v22 + uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22 - name: Setup FlakeHub Cache - uses: DeterminateSystems/flakehub-cache-action@main + uses: DeterminateSystems/flakehub-cache-action@3be0931021788e3bb4df65f59a555039c2fa2d46 # v3.21.7 - name: Build screenly-cli run: nix build .#screenly-cli diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 02cea212..af134c5e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,13 +65,13 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Install Rust - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} + run: | + rustup toolchain install ${{ matrix.rust }} --profile minimal + rustup default ${{ matrix.rust }} + rustup target add ${{ matrix.target }} - name: Use Cross shell: bash @@ -106,7 +106,7 @@ jobs: cd - - name: Publish - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 # TODO: if any of the build step fails, the release should be deleted. with: files: "screenly*" @@ -114,7 +114,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Attest - uses: actions/attest-build-provenance@v1 + uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1 with: subject-path: "${{ github.workspace }}/screenly*" @@ -125,7 +125,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Build container run: | @@ -141,7 +141,7 @@ jobs: - name: Login to DockerHub if: success() && github.event_name != 'pull_request' - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index d64f6cd7..29a1246d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -31,10 +31,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Cache Cargo & target directories - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: | ~/.cargo/bin/ diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml index 6d50ee98..0a2292cc 100644 --- a/.github/workflows/sbom.yml +++ b/.github/workflows/sbom.yml @@ -14,10 +14,10 @@ jobs: attestations: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Upload SBOM - uses: sbomify/github-action@master + uses: sbomify/github-action@ddf6a0d3d75b645153ad1ad60034b3fe2cb1eb63 # v26.7.0 env: TOKEN: ${{ secrets.SBOMIFY_TOKEN }} COMPONENT_ID: 'UUzAdk8ixV' @@ -29,6 +29,6 @@ jobs: ENRICH: true - name: Attest - uses: actions/attest-build-provenance@v1 + uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1 with: subject-path: '${{ github.workspace }}/cli.cdx.json' diff --git a/src/api/edge_app/setting.rs b/src/api/edge_app/setting.rs index a749fc59..2658e266 100644 --- a/src/api/edge_app/setting.rs +++ b/src/api/edge_app/setting.rs @@ -329,7 +329,7 @@ impl Api { payload.insert("app_id".to_owned(), json!(app_id)); payload.insert("name".to_owned(), json!(setting.name)); - debug!("Creating setting: {:?}", &payload); + debug!("Creating setting: {:?}", payload); commands::post(&self.authentication, "v4.1/edge-apps/settings", &payload) } @@ -338,7 +338,7 @@ impl Api { let mut payload = serde_json::from_value::>(value)?; payload.insert("name".to_owned(), json!(setting.name)); - debug!("Updating setting: {:?}", &payload); + debug!("Updating setting: {:?}", payload); commands::patch( &self.authentication, diff --git a/src/commands/asset.rs b/src/commands/asset.rs index 50f4496d..65034aa6 100644 --- a/src/commands/asset.rs +++ b/src/commands/asset.rs @@ -57,7 +57,7 @@ impl AssetCommand { } pub fn add(&self, path: &str, title: &str) -> anyhow::Result { - let url = format!("{}/v4/assets", &self.authentication.config.url); + let url = format!("{}/v4/assets", self.authentication.config.url); let mut headers = HeaderMap::new(); headers.insert("Prefer", "return=representation".parse()?); @@ -130,7 +130,7 @@ impl AssetCommand { } let headers = assets[0].get("headers").ok_or(CommandError::MissingField)?; let old_headers = serde_json::from_value::>(headers.clone())?; - debug!("Old headers {:?}", &old_headers); + debug!("Old headers {:?}", old_headers); for (key, value) in old_headers { new_headers.entry(key).or_insert(value); } diff --git a/src/commands/edge_app/app.rs b/src/commands/edge_app/app.rs index d5ed98d4..c8c7ba37 100644 --- a/src/commands/edge_app/app.rs +++ b/src/commands/edge_app/app.rs @@ -252,7 +252,7 @@ impl EdgeAppCommand { .api .get_version_asset_signatures(&actual_app_id, revision)?; let changed_files = detect_changed_files(&local_files, &remote_files)?; - debug!("Changed files: {:?}", &changed_files); + debug!("Changed files: {:?}", changed_files); let remote_settings = self.api.get_settings(&actual_app_id)?; @@ -421,7 +421,7 @@ impl EdgeAppCommand { } debug!( "ensure_assets_processing_finished: {:?}", - &asset_processing_statuses + asset_processing_statuses ); for asset_processing_status in &asset_processing_statuses { @@ -554,7 +554,7 @@ impl EdgeAppCommand { setting: &Setting, prompt_user: bool, ) -> Result<(), CommandError> { - debug!("Deleting setting: {:?}", &setting.name); + debug!("Deleting setting: {:?}", setting.name); let mut input_name = String::new(); @@ -627,7 +627,7 @@ impl EdgeAppCommand { path: &Path, _pb: &Arc>, ) -> Result<(), CommandError> { - let url = format!("{}/v4/assets", &self.api.authentication.config.url); + let url = format!("{}/v4/assets", self.api.authentication.config.url); let mut headers = HeaderMap::new(); headers.insert("Prefer", "return=representation".parse()?); @@ -659,7 +659,7 @@ impl EdgeAppCommand { let status = response.status(); if status != StatusCode::CREATED { - debug!("Response: {:?}", &response.text()); + debug!("Response: {:?}", response.text()); return Err(CommandError::WrongResponseStatus(status.as_u16())); } diff --git a/src/commands/edge_app/utils.rs b/src/commands/edge_app/utils.rs index 5b78aa46..6419b472 100644 --- a/src/commands/edge_app/utils.rs +++ b/src/commands/edge_app/utils.rs @@ -273,7 +273,7 @@ pub fn generate_file_tree(files: &[EdgeAppFile], root_path: &Path) -> HashMap Result { - let url = format!("{}/{}", &authentication.config.url, endpoint); + let url = format!("{}/{}", authentication.config.url, endpoint); debug!("GET {url}"); let mut headers = HeaderMap::new(); headers.insert("Prefer", "return=representation".parse()?); @@ -189,7 +189,7 @@ pub fn get( debug!("GET {url} -> {status}"); if status != StatusCode::OK { - println!("Response: {:?}", &response.text()); + println!("Response: {:?}", response.text()); return Err(CommandError::WrongResponseStatus(status.as_u16())); } Ok(serde_json::from_str(&response.text()?)?) @@ -200,7 +200,7 @@ pub fn post( endpoint: &str, payload: &T, ) -> Result { - let url = format!("{}/{}", &authentication.config.url, endpoint); + let url = format!("{}/{}", authentication.config.url, endpoint); let mut headers = HeaderMap::new(); headers.insert("Prefer", "return=representation".parse()?); @@ -216,7 +216,7 @@ pub fn post( // Ok, No_Content are acceptable because some of our RPC code returns that. if ![StatusCode::CREATED, StatusCode::OK, StatusCode::NO_CONTENT].contains(&status) { - debug!("Response: {:?}", &response.text()?); + debug!("Response: {:?}", response.text()?); return Err(CommandError::WrongResponseStatus(status.as_u16())); } if status == StatusCode::NO_CONTENT { @@ -227,13 +227,13 @@ pub fn post( } pub fn delete(authentication: &Authentication, endpoint: &str) -> anyhow::Result<(), CommandError> { - let url = format!("{}/{}", &authentication.config.url, endpoint); + let url = format!("{}/{}", authentication.config.url, endpoint); let response = authentication.build_client()?.delete(url).send()?; let status = response.status(); if ![StatusCode::OK, StatusCode::NO_CONTENT].contains(&status) { - debug!("Response: {:?}", &response.text()?); + debug!("Response: {:?}", response.text()?); return Err(CommandError::WrongResponseStatus(status.as_u16())); } Ok(()) @@ -244,7 +244,7 @@ pub fn patch( endpoint: &str, payload: &T, ) -> anyhow::Result { - let url = format!("{}/{}", &authentication.config.url, endpoint); + let url = format!("{}/{}", authentication.config.url, endpoint); let mut headers = HeaderMap::new(); headers.insert("Prefer", "return=representation".parse()?); @@ -257,7 +257,7 @@ pub fn patch( let status = response.status(); if status != StatusCode::OK { - debug!("Response: {:?}", &response.text()?); + debug!("Response: {:?}", response.text()?); return Err(CommandError::WrongResponseStatus(status.as_u16())); } diff --git a/src/commands/screen.rs b/src/commands/screen.rs index 15f32c2c..8e784b46 100644 --- a/src/commands/screen.rs +++ b/src/commands/screen.rs @@ -36,7 +36,7 @@ impl ScreenCommand { pin: &str, maybe_name: Option, ) -> anyhow::Result { - let url = format!("{}/v3/screens/", &self.authentication.config.url); + let url = format!("{}/v3/screens/", self.authentication.config.url); let mut payload = HashMap::new(); payload.insert("pin".to_string(), pin.to_string()); if let Some(name) = maybe_name {