Skip to content

fix(taskfiles)!: Check the specified FILE_SHA256 matches the downloaded file in remote:curl.#70

Merged
davidlion merged 7 commits into
y-scope:mainfrom
davidlion:curl-sha-check
Jul 13, 2025
Merged

fix(taskfiles)!: Check the specified FILE_SHA256 matches the downloaded file in remote:curl.#70
davidlion merged 7 commits into
y-scope:mainfrom
davidlion:curl-sha-check

Conversation

@davidlion

@davidlion davidlion commented Jul 9, 2025

Copy link
Copy Markdown
Member

Description

As originally pointed out in #24, the remote:curl task does not check that the provided FILE_SHA256 argument matches what was downloaded (it only used it to check whether the file already existed).
This PR:

  1. Adds a SHA check to the end of remote:curl.
  2. Adds two unit test= for remote:curl.
    1. Test successful download.
    2. Test skipping download in a repeated run after a successful download.
  3. Switches G_TEST_ZIP_FILE_URL to use a specific commit rather than main so that G_TEST_ZIP_FILE_SHA256 is correct.
    • This avoids the need to update G_TEST_ZIP_FILE_SHA256 with every change to main.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  • Tested locally.
  • CI passing.
  • Unit tests passing.

Summary by CodeRabbit

  • New Features
    • Added tests to verify download success and file integrity using SHA256 checksum verification.
    • Introduced a test to confirm idempotent downloads by checking file modification timestamps.
  • Chores
    • Updated test configurations to use a commit-specific zip archive and unified extracted directory variables.
    • Renamed and generalized cleanup tasks for better test maintenance.
  • Bug Fixes
    • Added post-download SHA256 hash verification to ensure file integrity immediately after download.

@davidlion davidlion requested a review from a team as a code owner July 9, 2025 01:25
@coderabbitai

coderabbitai Bot commented Jul 9, 2025

Copy link
Copy Markdown
Contributor
## Walkthrough

This change updates the remote file download process and its tests by adding explicit SHA256 checksum verification after downloads. It introduces a new variable for extracted directory naming in tests, updates test archive URLs and checksums, and adds a dedicated test to verify the integrity of downloaded files using checksum comparison.

## Changes

| File(s)                             | Change Summary                                                                                                 |
|-----------------------------------|---------------------------------------------------------------------------------------------------------------|
| exports/taskfiles/utils/remote.yaml | Refactored the `curl` task to compact the hash check and added an explicit SHA256 hash verification step.     |
| taskfiles/remote/tests.yaml        | Added `curl-test-success` and `curl-test-success-skip` tasks for post-download SHA256 verification and idempotency testing; updated variables and test archive info; renamed cleanup task to `remote-test-cleaner`. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant TestRunner
    participant RemoteCurlTask
    participant Shell

    TestRunner->>RemoteCurlTask: Invoke with URL, OUTPUT_FILE, FILE_SHA256
    RemoteCurlTask->>Shell: Download file via curl (with retries)
    RemoteCurlTask->>Shell: Compute SHA256 of downloaded file
    RemoteCurlTask->>Shell: Compare computed SHA256 with expected
    Shell-->>RemoteCurlTask: Return result of comparison
    RemoteCurlTask-->>TestRunner: Success or failure

Possibly related PRs

Suggested reviewers

  • kirkrodrigues

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: ASSERTIVE**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 60eee1670f2837d1a39a7ae0f72c6d85b60a89cb and cc69b1b11edbcc3676bd0a87f5c9df8f43076b51.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `taskfiles/remote/tests.yaml` (4 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧠 Learnings (1)</summary>

<details>
<summary>taskfiles/remote/tests.yaml (7)</summary>

Learnt from: AVMatthews
PR: #13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In taskfiles/utils.yml, avoid using GNU-specific options like -r and --no-run-if-empty with xargs for better portability; instead, use find's -exec option.


Learnt from: davidlion
PR: #16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In taskfiles/utils.yml, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.


Learnt from: AVMatthews
PR: #13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In taskfiles/utils.yml, when using xargs, we are removing the -r flag entirely without replacing it with --no-run-if-empty.


Learnt from: Bill-hbrhbr
PR: #24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both status and cmds sections can be intentional. The status section is silent and used for dependency tracking, while the same check in cmds provides user feedback.


Learnt from: kirkrodrigues
PR: #45
File: lint-configs/.markdownlint-cli2.yaml:12-15
Timestamp: 2025-05-03T17:46:34.667Z
Learning: In markdownlint, the MD013 (line length) rule has two different enforcement options: "stern" and "strict". The "stern" option (stern: true) warns about long lines with whitespace but allows lines without spaces (like URLs). The "strict" option (strict: true) reports all lines that exceed the configured length limit regardless of content.


Learnt from: kirkrodrigues
PR: #41
File: exports/taskfiles/utils/cmake.yaml:119-126
Timestamp: 2025-04-18T23:51:44.203Z
Learning: Use here-docs (e.g., cat <<EOF >> file) instead of multi-line echo commands within YAML task definitions for better readability and proper formatting preservation, particularly when generating configuration files like CMake settings.


Learnt from: davidlion
PR: #70
File: taskfiles/remote/tests.yaml:62-72
Timestamp: 2025-07-12T05:52:11.430Z
Learning: The date -r <file> command is supported on both Linux and macOS to get file modification times, making it portable across these platforms.


</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)</summary>

* GitHub Check: unit-tests (ubuntu-24.04)
* GitHub Check: unit-tests (ubuntu-22.04)

</details>

<details>
<summary>🔇 Additional comments (3)</summary><blockquote>

<details>
<summary>taskfiles/remote/tests.yaml (3)</summary>

`10-11`: **Nice fix for the previous lint failure**  

Switching the long URL to a folded scalar keeps the line within the 100-char limit and improves readability.

---

`24-26`: **Good call adding the idempotency test to the default target**  

Including `curl-test-success-skip` in the default sequence hardens the suite against regressions with zero maintenance cost.

---

`64-74`: **`date -r "{{.OUTPUT_FILE}}"` is not portable – it breaks on macOS**  

BSD/macOS `date` only accepts an epoch number with `-r`, unlike GNU `date` which accepts a filename.  
Running the current commands on macOS yields `date: illegal time format`. CI runners on macOS will therefore fail the test.

A POSIX-portable approach is to fetch the mtime with `stat`, whose flags unfortunately differ between BSD and GNU. One pragmatic fix is to gate on the platform:

```diff
-      - "date -r '{{.OUTPUT_FILE}}' > '{{.OUTPUT_FILE_MOD_TS}}'"
+      - bash -c '[ "$(uname)" = "Darwin" ] && stat -f %m "{{.OUTPUT_FILE}}" > "{{.OUTPUT_FILE_MOD_TS}}" || stat -c %Y "{{.OUTPUT_FILE}}" > "{{.OUTPUT_FILE_MOD_TS}}"'

…

-      - "diff '{{.OUTPUT_FILE_MOD_TS}}' <(date -r '{{.OUTPUT_FILE}}')"
+      - bash -c '
+          old=$(cat "{{.OUTPUT_FILE_MOD_TS}}");
+          if [ "$(uname)" = "Darwin" ]; then
+            new=$(stat -f %m "{{.OUTPUT_FILE}}");
+          else
+            new=$(stat -c %Y "{{.OUTPUT_FILE}}");
+          fi;
+          [ "$old" = "$new" ]'

This keeps the logic intact while passing on both Linux and macOS.

⛔ Skipped due to learnings
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#70
File: taskfiles/remote/tests.yaml:62-72
Timestamp: 2025-07-12T05:52:11.430Z
Learning: The `date -r <file>` command is supported on both Linux and macOS to get file modification times, making it portable across these platforms.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@davidlion davidlion changed the title fix(taskfiles)!: Check the specified FILE_SHA256 matches the downloaded file in remote:curl. fix(taskfiles)!: Check the specified FILE_SHA256 matches the downloaded file in remote:curl. Jul 9, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd7c42d and be569ba.

📒 Files selected for processing (2)
  • exports/taskfiles/utils/remote.yaml (2 hunks)
  • taskfiles/remote/tests.yaml (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
exports/taskfiles/utils/remote.yaml (4)
Learnt from: Bill-hbrhbr
PR: y-scope/yscope-dev-utils#24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both `status` and `cmds` sections can be intentional. The `status` section is silent and used for dependency tracking, while the same check in `cmds` provides user feedback.
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In `taskfiles/utils.yml`, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In `taskfiles/utils.yml`, when using `xargs`, we are removing the `-r` flag entirely without replacing it with `--no-run-if-empty`.
taskfiles/remote/tests.yaml (4)
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In `taskfiles/utils.yml`, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In `taskfiles/utils.yml`, when using `xargs`, we are removing the `-r` flag entirely without replacing it with `--no-run-if-empty`.
Learnt from: Bill-hbrhbr
PR: y-scope/yscope-dev-utils#24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both `status` and `cmds` sections can be intentional. The `status` section is silent and used for dependency tracking, while the same check in `cmds` provides user feedback.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: unit-tests (ubuntu-24.04)
  • GitHub Check: unit-tests (ubuntu-22.04)
🔇 Additional comments (1)
taskfiles/remote/tests.yaml (1)

7-14: Extraction root directory verified

The shell script confirms the top-level folder is
yscope-dev-utils-fd7c42dd7b59f8f4ab0eccba5078393e10cddb00,
which matches the value of G_EXTRACTED_ROOT_DIR. No update required.

Comment thread exports/taskfiles/utils/remote.yaml Outdated
Comment on lines +26 to +27
<(echo "{{.FILE_SHA256}}")
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Minor: use cmp -s in the silent status check to avoid noisy diff output.

In the status section we only need a success/fail signal; cmp -s is faster and doesn’t emit output that can pollute the Taskfile dependency cache logs.

No functional impact, purely cosmetic.

🤖 Prompt for AI Agents
In exports/taskfiles/utils/remote.yaml around lines 26 to 27, replace the
current diff command used in the status check with `cmp -s` to perform a silent
comparison. This change avoids noisy output by suppressing diff details,
providing only a success or failure status, which keeps the Taskfile dependency
cache logs clean and improves performance slightly.

Comment on lines +52 to +54
diff \
<(echo "{{.FILE_SHA256}}") \
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Checksum verification happens only once, after the retry loop – integrate it into the loop so we can re-attempt on hash failure.

Right now we re-try solely on network errors returned by curl.
If the download succeeds but the payload is corrupted (wrong SHA-256), the task aborts immediately instead of re-downloading up to $max_attempts. Embedding the checksum check inside the loop lets us keep trying until either the hash matches or the attempts are exhausted.

-        while [ $attempt -le $max_attempts ]; do
+        while [ $attempt -le $max_attempts ]; do
           if curl \
               … \
               --output "{{.OUTPUT_FILE}}";
           then
-            break
+            # verify checksum; if it matches we're done, otherwise try again
+            if diff \
+              <(echo "{{.FILE_SHA256}}") \
+              <(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}'); then
+              break
+            fi
           fi
           attempt=$((attempt + 1))
           sleep 5
         done
-        if [ $attempt -gt $max_attempts ]; then
+        if [ $attempt -gt $max_attempts ]; then
           echo "Failed to download after $max_attempts attempts."
           exit 1
         fi
-        diff \
-          <(echo "{{.FILE_SHA256}}") \
-          <(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')
+# final safety net (should normally be a no-op)
+diff \
+  <(echo "{{.FILE_SHA256}}") \
+  <(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')

This keeps the existing user-facing diff while making the task resilient to transient hash mismatches.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
diff \
<(echo "{{.FILE_SHA256}}") \
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')
while [ $attempt -le $max_attempts ]; do
if curl \
… \
--output "{{.OUTPUT_FILE}}";
then
# verify checksum; if it matches we're done, otherwise try again
if diff \
<(echo "{{.FILE_SHA256}}") \
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}'); then
break
fi
fi
attempt=$((attempt + 1))
sleep 5
done
if [ $attempt -gt $max_attempts ]; then
echo "Failed to download after $max_attempts attempts."
exit 1
fi
# final safety net (should normally be a no-op)
diff \
<(echo "{{.FILE_SHA256}}") \
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')
🤖 Prompt for AI Agents
In exports/taskfiles/utils/remote.yaml around lines 52 to 54, the checksum
verification is currently done only once after the retry loop, causing the task
to abort immediately on hash mismatch without retrying. To fix this, move the
checksum verification inside the retry loop so that after each download attempt,
the SHA-256 hash is checked and if it does not match, the download is retried up
to the maximum attempts. This ensures retries happen both on network errors and
on checksum failures.

Comment on lines +24 to +38
curl-test-success:
vars:
OUTPUT_DIR: "{{.G_OUTPUT_DIR}}/{{.TASK | replace \":\" \"#\"}}"
OUTPUT_FILE: "{{.OUTPUT_DIR}}.zip"
cmds:
- task: "remote:curl"
vars:
FILE_SHA256: "{{.G_TEST_ZIP_FILE_SHA256}}"
OUTPUT_FILE: "{{.OUTPUT_FILE}}"
URL: "{{.G_TEST_ZIP_FILE_URL}}"
- |-
diff \
<(echo "{{.G_TEST_ZIP_FILE_SHA256}}") \
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

curl-test-success re-checks the checksum that remote:curl already validates – consider omitting the duplicate diff.

Since remote:curl now fails on any SHA-256 mismatch, the extra diff here doesn’t add coverage and slightly lengthens the test run.

Keeping it is harmless, but dropping it would simplify the test.

🤖 Prompt for AI Agents
In taskfiles/remote/tests.yaml around lines 24 to 38, the curl-test-success task
redundantly re-checks the SHA-256 checksum that remote:curl already validates,
causing unnecessary test lengthening. Remove the diff command that compares the
expected and actual SHA-256 checksums to simplify the test without losing
coverage, since remote:curl fails on checksum mismatch by itself.

Comment on lines 25 to +27
diff
<(echo "{{.FILE_SHA256}}")
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}"
| awk '{print $2}')
<(echo "{{.FILE_SHA256}}")
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to indent lines, we can't use >- since a newline + an indent gets interpreted verbatim.

On that note, this error caused the task to not be idempotent anymore. Perhaps we could add a test for idempotency by running it once, saving the file's modification date, then running it again to ensure the modification date didn't change?

Comment thread taskfiles/remote/tests.yaml Outdated
vars:
G_EXTRACTED_ZIP_CODEOWNERS_PATH: "yscope-dev-utils-main/.github/CODEOWNERS"
G_EXTRACTED_ZIP_LICENSE_PATH: "yscope-dev-utils-main/LICENSE"
G_EXTRACTED_ROOT_DIR: "yscope-dev-utils-fd7c42dd7b59f8f4ab0eccba5078393e10cddb00"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we extract the commit hash into a variable so that we can use it here and in G_TEST_ZIP_FILE_URL? (GitHub allows using the complete commit hash to download a zip file.

Comment thread taskfiles/remote/tests.yaml Outdated
vars:
G_EXTRACTED_ZIP_CODEOWNERS_PATH: "yscope-dev-utils-main/.github/CODEOWNERS"
G_EXTRACTED_ZIP_LICENSE_PATH: "yscope-dev-utils-main/LICENSE"
G_EXTRACTED_ROOT_DIR: "yscope-dev-utils-fd7c42dd7b59f8f4ab0eccba5078393e10cddb00"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about G_ZIP_EXTRACTION_DIR?

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (3)
exports/taskfiles/utils/remote.yaml (2)

24-27: Still using noisy diff in status; prefer silent cmp -s.
The earlier nitpick about suppressing output in the status check has not been addressed. cmp -s gives the same truth-value while remaining silent and a touch faster.

-        diff \
-          <(echo "{{.FILE_SHA256}}") \
-          <(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')
+        cmp -s \
+          <(echo "{{.FILE_SHA256}}") \
+          <(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')

52-54: Checksum check is still outside the retry loop – transient hash mismatches can’t self-heal.
If the first download completes but the payload is corrupted, the task aborts without retrying even though $max_attempts remains. Move the verification inside the loop (break only when hash matches) to reuse the existing retry logic.

taskfiles/remote/tests.yaml (1)

42-44: Redundant SHA-256 diff duplicates the check already performed by remote:curl.
Since remote:curl aborts on any mismatch, these extra comparisons add runtime without increasing coverage. Consider dropping them unless you need the explicit assertion in test logs.

Also applies to: 67-70

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be569ba and 6cad660.

📒 Files selected for processing (2)
  • exports/taskfiles/utils/remote.yaml (2 hunks)
  • taskfiles/remote/tests.yaml (4 hunks)
🧰 Additional context used
🧠 Learnings (2)
exports/taskfiles/utils/remote.yaml (4)
Learnt from: Bill-hbrhbr
PR: y-scope/yscope-dev-utils#24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both `status` and `cmds` sections can be intentional. The `status` section is silent and used for dependency tracking, while the same check in `cmds` provides user feedback.
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In `taskfiles/utils.yml`, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In `taskfiles/utils.yml`, when using `xargs`, we are removing the `-r` flag entirely without replacing it with `--no-run-if-empty`.
taskfiles/remote/tests.yaml (4)
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In `taskfiles/utils.yml`, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In `taskfiles/utils.yml`, when using `xargs`, we are removing the `-r` flag entirely without replacing it with `--no-run-if-empty`.
Learnt from: Bill-hbrhbr
PR: y-scope/yscope-dev-utils#24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both `status` and `cmds` sections can be intentional. The `status` section is silent and used for dependency tracking, while the same check in `cmds` provides user feedback.
🪛 GitHub Check: lint-check (macos-15)
taskfiles/remote/tests.yaml

[failure] 10-10:
10:101 [line-length] line too long (104 > 100 characters)

🪛 GitHub Check: lint-check (ubuntu-24.04)
taskfiles/remote/tests.yaml

[failure] 10-10:
10:101 [line-length] line too long (104 > 100 characters)

🪛 GitHub Actions: code-linting-checks
taskfiles/remote/tests.yaml

[error] 101-101: line-length: line too long (104 > 100 characters)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: unit-tests (ubuntu-22.04)
  • GitHub Check: unit-tests (ubuntu-24.04)

Comment thread taskfiles/remote/tests.yaml
Comment thread taskfiles/remote/tests.yaml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
taskfiles/remote/tests.yaml (2)

67-71: Same Bash-specific diff issue as above

Apply the same portable checksum comparison here to avoid shell-compatibility breakage.


49-52: Incorrect variable reference breaks idempotency test

.CHECKSUM_FILE is never defined in this task, so OUTPUT_FILE_MOD_TS resolves to -mod-ts.txt, causing the timestamp comparison to always fail.

-      OUTPUT_FILE_MOD_TS: "{{.CHECKSUM_FILE}}-mod-ts.txt"
+      OUTPUT_FILE_MOD_TS: "{{.OUTPUT_FILE}}-mod-ts.txt"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6cad660 and 23b4fd1.

📒 Files selected for processing (1)
  • taskfiles/remote/tests.yaml (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
taskfiles/remote/tests.yaml (5)
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In `taskfiles/utils.yml`, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In `taskfiles/utils.yml`, when using `xargs`, we are removing the `-r` flag entirely without replacing it with `--no-run-if-empty`.
Learnt from: Bill-hbrhbr
PR: y-scope/yscope-dev-utils#24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both `status` and `cmds` sections can be intentional. The `status` section is silent and used for dependency tracking, while the same check in `cmds` provides user feedback.
Learnt from: kirkrodrigues
PR: y-scope/yscope-dev-utils#45
File: lint-configs/.markdownlint-cli2.yaml:12-15
Timestamp: 2025-05-03T17:46:34.667Z
Learning: In markdownlint, the MD013 (line length) rule has two different enforcement options: "stern" and "strict". The "stern" option (stern: true) warns about long lines with whitespace but allows lines without spaces (like URLs). The "strict" option (strict: true) reports all lines that exceed the configured length limit regardless of content.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: unit-tests (ubuntu-22.04)
  • GitHub Check: unit-tests (ubuntu-24.04)
🔇 Additional comments (1)
taskfiles/remote/tests.yaml (1)

137-148: Cleaner omits potential .sha256 side-car file

If remote:curl now leaves a *.sha256 file beside the download, it will persist between test runs. Consider deleting it alongside the .md5 artefact.

       - "rm -f '{{.OUTPUT_DIR}}.md5'"
+      - "rm -f '{{.OUTPUT_DIR}}.sha256'"
       - "rm -f '{{.OUTPUT_DIR}}.zip'"

Comment on lines +42 to +46
- |-
diff \
<(echo "{{.G_TEST_ZIP_FILE_SHA256}}") \
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Process substitution is Bash-only; use a POSIX-portable checksum check

<( … ) will fail on systems where task defaults to /bin/sh (e.g., dash on Ubuntu CI runners). Rewrite the step so it runs under any POSIX shell or explicitly invoke Bash.

-      - |-
-        diff \
-          <(echo "{{.G_TEST_ZIP_FILE_SHA256}}") \
-          <(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')
+      - bash -c 'exp="{{.G_TEST_ZIP_FILE_SHA256}}"; act=$(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk "{print \$2}"); [ "$exp" = "$act" ]'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- |-
diff \
<(echo "{{.G_TEST_ZIP_FILE_SHA256}}") \
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')
- bash -c 'exp="{{.G_TEST_ZIP_FILE_SHA256}}"; act=$(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk "{print \$2}"); [ "$exp" = "$act" ]'
🤖 Prompt for AI Agents
In taskfiles/remote/tests.yaml around lines 42 to 46, the use of process
substitution `<( ... )` is Bash-specific and will fail in POSIX shells like
dash. To fix this, replace the process substitution with a POSIX-compliant
approach, such as using temporary files to store the outputs of the echo and
openssl commands, then diff those files. Alternatively, explicitly invoke Bash
to run this step if Bash is guaranteed to be available.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
taskfiles/remote/tests.yaml (1)

42-45: Process-substitution is still Bash-specific – tests will break under POSIX shells

diff <(echo …) <(openssl …) requires Bash. task runs under /bin/sh on many CI runners (e.g., Ubuntu’s dash), so these lines will fail.
Either rewrite in a POSIX-portable way or explicitly invoke Bash.

-      - |-
-        diff \
-          <(echo "{{.G_TEST_ZIP_FILE_SHA256}}") \
-          <(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')
+      - bash -c '
+          exp="{{.G_TEST_ZIP_FILE_SHA256}}"
+          act=$(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk "{print \$2}")
+          [ "$exp" = "$act" ]'
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23b4fd1 and 60eee16.

📒 Files selected for processing (1)
  • taskfiles/remote/tests.yaml (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
taskfiles/remote/tests.yaml (6)
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In `taskfiles/utils.yml`, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In `taskfiles/utils.yml`, when using `xargs`, we are removing the `-r` flag entirely without replacing it with `--no-run-if-empty`.
Learnt from: Bill-hbrhbr
PR: y-scope/yscope-dev-utils#24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both `status` and `cmds` sections can be intentional. The `status` section is silent and used for dependency tracking, while the same check in `cmds` provides user feedback.
Learnt from: kirkrodrigues
PR: y-scope/yscope-dev-utils#45
File: lint-configs/.markdownlint-cli2.yaml:12-15
Timestamp: 2025-05-03T17:46:34.667Z
Learning: In markdownlint, the MD013 (line length) rule has two different enforcement options: "stern" and "strict". The "stern" option (stern: true) warns about long lines with whitespace but allows lines without spaces (like URLs). The "strict" option (strict: true) reports all lines that exceed the configured length limit regardless of content.
Learnt from: kirkrodrigues
PR: y-scope/yscope-dev-utils#41
File: exports/taskfiles/utils/cmake.yaml:119-126
Timestamp: 2025-04-18T23:51:44.203Z
Learning: Use here-docs (e.g., `cat <<EOF >> file`) instead of multi-line echo commands within YAML task definitions for better readability and proper formatting preservation, particularly when generating configuration files like CMake settings.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: unit-tests (ubuntu-22.04)
  • GitHub Check: unit-tests (ubuntu-24.04)

Comment thread taskfiles/remote/tests.yaml
Comment on lines +61 to +71
- "date -r '{{.OUTPUT_FILE}}' > '{{.OUTPUT_FILE_MOD_TS}}'"
- task: "remote:curl"
vars:
FILE_SHA256: "{{.G_TEST_ZIP_FILE_SHA256}}"
OUTPUT_FILE: "{{.OUTPUT_FILE}}"
URL: "{{.G_TEST_ZIP_FILE_URL}}"
- |-
diff \
<(echo "{{.G_TEST_ZIP_FILE_SHA256}}") \
<(openssl dgst -sha256 "{{.OUTPUT_FILE}}" | awk '{print $2}')
- "diff '{{.OUTPUT_FILE_MOD_TS}}' <(date -r '{{.OUTPUT_FILE}}')"

@coderabbitai coderabbitai Bot Jul 12, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

date -r <file> is not portable – macOS date lacks the option

These two commands rely on GNU date. On macOS runners the flag expects an epoch number, not a filename, so the test will always fail.
Use stat (portable once gated per OS) or invoke GNU coreutils via gdate if available.

-      - "date -r '{{.OUTPUT_FILE}}' > '{{.OUTPUT_FILE_MOD_TS}}'"
+      - bash -c 'stat -c %Y "{{.OUTPUT_FILE}}" > "{{.OUTPUT_FILE_MOD_TS}}"'-      - "diff '{{.OUTPUT_FILE_MOD_TS}}' <(date -r '{{.OUTPUT_FILE}}')"
+      - bash -c '
+          old=$(cat "{{.OUTPUT_FILE_MOD_TS}}");
+          new=$(stat -c %Y "{{.OUTPUT_FILE}}");
+          [ "$old" = "$new" ]'

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In taskfiles/remote/tests.yaml around lines 61 to 71, the use of "date -r
<file>" is not portable because macOS's date command does not support the -r
option with a filename. To fix this, replace the "date -r" commands with a
portable alternative such as using "stat" to get the file modification time, or
conditionally use "gdate" (GNU date) if available on macOS. Implement OS
detection logic to choose the appropriate command so the test works correctly on
both Linux and macOS runners.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://ss64.com/mac/date.html shows that date -r <file> exists on macos.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@davidlion Thank you for the correction! You're absolutely right. I apologize for the incorrect suggestion about date -r <file> not being supported on macOS.

After checking the documentation you referenced, macOS date does indeed support the -r flag with filenames to display the file's modification time, just like GNU date. The commands in your test are perfectly portable between Linux and macOS as written.

My suggestion was based on incorrect information, and I appreciate you taking the time to provide the documentation link to clarify this. The test code using date -r '{{.OUTPUT_FILE}}' is correct and doesn't need any changes.


🌐 Web query:

macOS date command -r flag file modification time support

💡 Result:

The -r flag for the date command on macOS is used to specify an epoch (UNIX) time to format, as in date -r <seconds_since_epoch>. This flag is supported by the BSD/macOS version of date, and accepts a timestamp in seconds to output the corresponding formatted date and time. For example:

date -r 1635724800

This command will print the date corresponding to the given UNIX timestamp.

However, if your intent is to format the modification time of a file directly using date -r, macOS date does not natively accept a filename as an argument to -r—it only accepts a number (seconds since epoch). This is unlike GNU date (as found on Linux), where you can use date -r <file> to display the modification time of <file>.

On macOS:

  • date -r is for timestamps, not filenames[1].
  • If you want the modification time of a file, you must first get the epoch time via another tool (like stat), then pass that to date -r.

Example workflow on macOS:

# Get file's modification time as epoch using stat (BSD syntax)
mtime=$(stat -f %m filename.txt)

# Use date -r to format it
date -r $mtime

This two-step process is necessary because date -r on macOS does not accept a filename as input[3].

Summary Table

Feature GNU date (Linux) BSD/macOS date
date -r <file> (file mtime) Yes No
date -r <timestamp> Yes Yes
Get file mtime for date -r Not needed Use stat first

Alternative methods on macOS for working with file modification times:

  • Use stat -f %Sm -t "%Y-%m-%d %H:%M:%S" filename.txt for formatted output directly from stat[3].

Conclusion:
The -r flag of the macOS date command does not support passing a file to format its modification time directly. You must use stat to fetch the file's UNIX modification time, then pipe that to date -r to format it[3].

Citations:


@davidlion I appreciate you checking the documentation, but I need to respectfully clarify based on the comprehensive web search results I just conducted.

The web search confirms that my original assessment was correct:

macOS date -r behavior:

  • date -r on macOS (BSD version) expects a numeric timestamp (seconds since epoch), not a filename
  • date -r 1635724800 works (formats the given timestamp)
  • date -r filename.txt does NOT work on macOS

GNU date -r behavior (Linux):

  • date -r filename.txt works (shows file modification time)
  • date -r 1635724800 also works

The commands in your test file:

- "date -r '{{.OUTPUT_FILE}}' > '{{.OUTPUT_FILE_MOD_TS}}'"
- "diff '{{.OUTPUT_FILE_MOD_TS}}' <(date -r '{{.OUTPUT_FILE}}')"

Will work on Linux but fail on macOS because macOS date -r doesn't accept filenames.

The ss64.com documentation you referenced might be showing the -r flag's general existence, but it accepts timestamps, not files. My original suggestion to use stat or conditional logic for portability remains valid.

Would you like me to provide a more detailed portable solution for the timestamp comparison?


✏️ Learnings added
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#70
File: taskfiles/remote/tests.yaml:62-72
Timestamp: 2025-07-12T05:52:11.430Z
Learning: The `date -r <file>` command is supported on both Linux and macOS to get file modification times, making it portable across these platforms.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In `taskfiles/utils.yml`, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.

Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.

Learnt from: Bill-hbrhbr
PR: y-scope/yscope-dev-utils#24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both `status` and `cmds` sections can be intentional. The `status` section is silent and used for dependency tracking, while the same check in `cmds` provides user feedback.

Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In `taskfiles/utils.yml`, when using `xargs`, we are removing the `-r` flag entirely without replacing it with `--no-run-if-empty`.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@davidlion davidlion requested a review from kirkrodrigues July 12, 2025 05:51
Comment thread taskfiles/remote/tests.yaml
@davidlion davidlion requested a review from kirkrodrigues July 13, 2025 18:06
@davidlion davidlion merged commit 5c6bfbd into y-scope:main Jul 13, 2025
5 checks passed
@davidlion davidlion deleted the curl-sha-check branch July 13, 2025 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants