diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 90b6be2..51f70ff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -68,12 +68,12 @@ jobs: - name: Prepare Build Artifacts (!windows) working-directory: ./${{ env.DIST_DIR }} - run: tar -czf ${{ env.RELEASE_NAME }}.tar.gz arduino-flasher-cli -C ../ LICENSE + run: tar -czf ${{ env.RELEASE_NAME }}.tar.gz arduino-flasher-cli -C ../ LICENSE README.md if: matrix.os != 'windows' - name: Prepare Build Artifacts (windows) working-directory: ./${{ env.DIST_DIR }} - run: 7z a -tzip ${{ env.RELEASE_NAME }}.zip arduino-flasher-cli.exe ../LICENSE + run: 7z a -tzip ${{ env.RELEASE_NAME }}.zip arduino-flasher-cli.exe ../LICENSE ../README.md if: matrix.os == 'windows' - name: Upload artifacts @@ -125,7 +125,7 @@ jobs: - name: Prepare Build Artifacts run: | - ${{ env.SEVENZ_PATH }} a -tzip ${{ env.RELEASE_NAME }}.zip arduino-flasher-cli.exe LICENSE + ${{ env.SEVENZ_PATH }} a -tzip ${{ env.RELEASE_NAME }}.zip arduino-flasher-cli.exe LICENSE README.md - name: Upload artifacts uses: actions/upload-artifact@v4 @@ -137,7 +137,7 @@ jobs: # This step is needed because the self hosted runner does not delete files automatically - name: Cleanup - run: rm ${{ env.RELEASE_NAME }}.zip LICENSE arduino-flasher-cli.exe + run: rm ${{ env.RELEASE_NAME }}.zip LICENSE README.md arduino-flasher-cli.exe notarize-macos: name: Notarize macOS @@ -253,7 +253,7 @@ jobs: +x \ "${{ env.PROJECT_NAME }}" - tar -czf ${{ env.PACKAGE_FILENAME }} ${{ env.PROJECT_NAME }} LICENSE + tar -czf ${{ env.PACKAGE_FILENAME }} ${{ env.PROJECT_NAME }} LICENSE README.md - name: Replace artifact with notarized build uses: actions/upload-artifact@v4 diff --git a/README.md b/README.md index 2081623..7247529 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,13 @@ A tool to download and flash Debian images on the board. +## Docs + +For a full guide on how to use it, see the [User documentation](https://docs.arduino.cc/tutorials/uno-q/update-image/). + ## Build and test it locally -Build it with `task arduino-flasher-cli:build` and run: +Build it with `task build` and run: ```sh # Flash the latest release of the Debian image diff --git a/main.go b/main.go index 5d89119..fb9ffe8 100644 --- a/main.go +++ b/main.go @@ -19,10 +19,11 @@ import ( "context" "fmt" "log/slog" + "os" "github.com/spf13/cobra" "go.bug.st/cleanup" - + "github.com/arduino/arduino-flasher-cli/feedback" "github.com/arduino/arduino-flasher-cli/i18n" ) @@ -34,7 +35,9 @@ var format string func main() { rootCmd := &cobra.Command{ Use: "arduino-flasher-cli", - Short: "A CLI to update and flash the Debian image", + Short: "A CLI to update your Arduino UNO Q board, by downloading and flashing the latest Arduino Linux image", + Example: " " + os.Args[0] + " flash latest\n" + + " " + os.Args[0] + " list\n", PersistentPreRun: func(cmd *cobra.Command, args []string) { format, ok := feedback.ParseOutputFormat(format) if !ok { diff --git a/updater/download_image.go b/updater/download_image.go index 8c8b603..d5c1890 100644 --- a/updater/download_image.go +++ b/updater/download_image.go @@ -46,24 +46,27 @@ type Release struct { // DownloadConfirmCB is a function that is called when a Debian image is ready to be downloaded. type DownloadConfirmCB func(target string) (bool, error) -func DownloadAndExtract(client *Client, targetVersion string, upgradeConfirmCb DownloadConfirmCB, forceYes bool) (*paths.Path, error) { +func DownloadAndExtract(client *Client, targetVersion string, upgradeConfirmCb DownloadConfirmCB, forceYes bool) (*paths.Path, string, error) { tmpZip, version, err := DownloadImage(client, targetVersion, upgradeConfirmCb, forceYes) if err != nil { - return nil, fmt.Errorf("error downloading the image: %v", err) + return nil, "", fmt.Errorf("error downloading the image: %v", err) } // Download not confirmed if tmpZip == nil { - return nil, nil + return nil, "", nil } err = ExtractImage(tmpZip, tmpZip.Parent()) if err != nil { - return nil, fmt.Errorf("error extracting the image: %v", err) + return nil, "", fmt.Errorf("error extracting the image: %v", err) } imagePath := tmpZip.Parent().Join("arduino-unoq-debian-image-" + version) - return imagePath, nil + if targetVersion == "latest" { + version += "(latest)" + } + return imagePath, version, nil } func DownloadImage(client *Client, targetVersion string, upgradeConfirmCb DownloadConfirmCB, forceYes bool) (*paths.Path, string, error) { diff --git a/updater/flasher.go b/updater/flasher.go index f8edac2..0d7fd55 100644 --- a/updater/flasher.go +++ b/updater/flasher.go @@ -32,7 +32,7 @@ func Flash(ctx context.Context, imagePath *paths.Path, version string, forceYes if !imagePath.Exist() { client := NewClient() - tempImagePath, err := DownloadAndExtract(client, version, func(target string) (bool, error) { + tempImagePath, v, err := DownloadAndExtract(client, version, func(target string) (bool, error) { feedback.Printf("Found Debian image version: %s", target) feedback.Printf("Do you want to download it? (yes/no)") @@ -56,6 +56,7 @@ func Flash(ctx context.Context, imagePath *paths.Path, version string, forceYes defer tempImagePath.Parent().RemoveAll() + version = v imagePath = tempImagePath } else if !imagePath.IsDir() { temp, err := GetTempDir("extract-") @@ -77,7 +78,7 @@ func Flash(ctx context.Context, imagePath *paths.Path, version string, forceYes imagePath = tempContent[0] } - return FlashBoard(ctx, imagePath.String(), func(target string) (bool, error) { + return FlashBoard(ctx, imagePath.String(), version, func(target string) (bool, error) { feedback.Print("\nWARNING: flashing a new Linux image on the board will erase any existing data you have on it.") feedback.Printf("Do you want to procede and flash %s on the board? (yes/no)", target) @@ -91,9 +92,9 @@ func Flash(ctx context.Context, imagePath *paths.Path, version string, forceYes }, forceYes) } -func FlashBoard(ctx context.Context, downloadedImagePath string, upgradeConfirmCb DownloadConfirmCB, forceYes bool) error { +func FlashBoard(ctx context.Context, downloadedImagePath string, version string, upgradeConfirmCb DownloadConfirmCB, forceYes bool) error { if !forceYes { - res, err := upgradeConfirmCb(downloadedImagePath) + res, err := upgradeConfirmCb(version) if err != nil { return err } @@ -152,5 +153,7 @@ func FlashBoard(ctx context.Context, downloadedImagePath string, upgradeConfirmC return err } + feedback.Print("\nThe board has been successfully flashed. You can now power-cycle the board (unplug and re-plug). Remember to remove the jumper.") + return nil }