diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 10907cd..9e09750 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -44,11 +44,24 @@ jobs: git archive --format=tar ${REF} \ --prefix "${name}/" | tar -xf - - while IFS=$'\t' read -r id path; do + while IFS=$'\t' read -r id path mime_type; do + case "${mime_type}" in + "") + # "confirm=t" skips the "Google Drive can't scan this + # file for viruses" confirmation page that is returned + # instead of the file itself for large (100MB+) files. + url="https://drive.usercontent.google.com/download?id=${id}&export=download&confirm=t" + ;; + application/vnd.google-apps.document) + # Google Docs is exported as PDF. + url="https://docs.google.com/document/d/${id}/export?format=pdf" + ;; + *) + echo "::error::Unsupported Google Workspace file: ${path} (${mime_type})" + exit 1 + ;; + esac mkdir -p "${name}/$(dirname "${path}")" - # "confirm=t" skips the "Google Drive can't scan this file - # for viruses" confirmation page that is returned instead - # of the file itself for large (100MB+) files. content_type=$(curl \ --fail \ --location \ @@ -56,7 +69,7 @@ jobs: --silent \ --output "${name}/${path}" \ --write-out '%{content_type}' \ - "https://drive.usercontent.google.com/download?id=${id}&export=download&confirm=t") + "${url}") case "${content_type}" in text/html*) echo "::error::Failed to download ${path} (${id}): Google Drive returned an HTML page instead of the file" diff --git a/dev/README.md b/dev/README.md index 1f7e211..495165f 100644 --- a/dev/README.md +++ b/dev/README.md @@ -2,8 +2,19 @@ ## How to release -```bash -git clone git@github.com:enactic/openarm_hardware.git -cd openarm_hardware -dev/release.sh ${VERSION} # e.g. dev/release.sh 1.0.0 -``` +1. Update `dev/google-drive-files/file-ids.tsv` to the latest + Google Drive contents and merge it to `main`. See + [`dev/google-drive-files/README.md`](google-drive-files/README.md) + for details. + + The release job downloads only the files listed in + `file-ids.tsv`. If a file in Google Drive is moved, replaced or + deleted, its old ID stops working and the release job fails. + +2. Tag and push: + + ```bash + git clone git@github.com:enactic/openarm_hardware.git + cd openarm_hardware + dev/release.sh ${VERSION} # e.g. dev/release.sh 1.0.0 + ``` diff --git a/dev/google-drive-files/README.md b/dev/google-drive-files/README.md index a8a86ad..14eca02 100644 --- a/dev/google-drive-files/README.md +++ b/dev/google-drive-files/README.md @@ -45,3 +45,13 @@ $ ./generate-file-ids.rb 1.1 This is a commit of file automatically generated by `generate-file-ids.rb`. If changes are made to Google Drive, please run `generate-file-ids.rb` and commit the changes. + +Each line has the following tab-separated columns: + +1. Google Drive file ID +2. Path in the release archive +3. (Optional) MIME type of Google Workspace files such as + `application/vnd.google-apps.document` (Google Docs). The release + job exports Google Docs as PDF and the path in the second column + has `.pdf` suffix. Other Google Workspace files (Sheets, Slides and + so on) aren't supported yet and `generate-file-ids.rb` skips them. diff --git a/dev/google-drive-files/file-ids.tsv b/dev/google-drive-files/file-ids.tsv index 06b35bd..91b0615 100644 --- a/dev/google-drive-files/file-ids.tsv +++ b/dev/google-drive-files/file-ids.tsv @@ -1,19 +1,40 @@ -1o3eUXLWWgTuWCb5OTmLyBQvEH0nXxT0w v2.0/Hardware/OpenArm Cell/Integration with OpenArm/OpenArm_Cell+OpenArm_2.0.STEP -1Ak9ZRbhdeep9R8xsPZbKWIEbY99sg-Am v2.0/Hardware/OpenArm Cell/JIG/OpenArmJIG_BOM.xlsx -1V3CDlTN64f95u9gtATIn5wNTBGyUE3tx v2.0/Hardware/OpenArm Cell/JIG/OpenArmJIG.STEP +1mP0gDFgGaX6Ufobr8ocyg71ccsYgfBDw v2.0/Hardware/OpenArm 2.0/Options/OpenArm_2.0_w_Head_Camera.STEP +15p1PYmEKcDmnYQ5Hy_trM8gIoFCADF5a v2.0/Hardware/OpenArm 2.0/OpenArm 2.0 BOM.xlsx +1aU-V3lt_aPrZoRM8FFx6dMQu2f28Ws0I v2.0/Hardware/OpenArm 2.0/OpenArm_2.0.STEP +1xHMssSOp9RfZD1K6H80Yyl4uTlpU3lTc v2.0/Hardware/OpenArm 2.0/README.docx 1dZNUfoNDauqLoxLAgfdjrjm5wZEi3KGA v2.0/Hardware/OpenArm Cell/Elec/CELL_WIRING.pdf 1BpHJtbkg-uVoz8ZZrl4nGJyacPUTmq8F v2.0/Hardware/OpenArm Cell/Elec/CELL_WIRING.xlsx 1-R55Idf_G9TvjUsMl-cZ8esXmvPLjKyC v2.0/Hardware/OpenArm Cell/Elec/PWR-CIRCUIT-DIN-RAIL-BUS_2.zip -1SmF1Q4BQa-QwytB2GYu1YTOXWrtz8T__ v2.0/Hardware/OpenArm Cell/README.docx +1o3eUXLWWgTuWCb5OTmLyBQvEH0nXxT0w v2.0/Hardware/OpenArm Cell/Integration with OpenArm/OpenArm_Cell+OpenArm_2.0.STEP +1qOt1T4XzuH-iukmT8rXmuCF_NDZwrPSZ v2.0/Hardware/OpenArm Cell/Integration with OpenArm/OpenArm_Cell_cover_a.STEP +1lne22UpsztWr2t0TdqJxpJoMEt5Z6LGA v2.0/Hardware/OpenArm Cell/Integration with OpenArm/OpenArm_Cell_cover_b.STEP +1V3CDlTN64f95u9gtATIn5wNTBGyUE3tx v2.0/Hardware/OpenArm Cell/JIG/OpenArmJIG.STEP +1Ak9ZRbhdeep9R8xsPZbKWIEbY99sg-Am v2.0/Hardware/OpenArm Cell/JIG/OpenArmJIG_BOM.xlsx 1KojBKJe4hC0Oqus8LIUvfkKwnr3xQx3F v2.0/Hardware/OpenArm Cell/OpenArm Cell BOM.xlsx -1CBgghd7gDeWnKbbH2SOlk3yypSj0Dy5a v2.0/Hardware/OpenArm Cell/OpenEvalCell_defeature.STEP 1il0ruNigmZ_AfcUPyRAz_hEbmok7gWX4 v2.0/Hardware/OpenArm Cell/OpenEvalCell_defeature.SLDPRT -1EoUKnqu8Qs1QVaPnXdhNQUHthIQg1fH5 v2.0/Hardware/OpenArm KER/TLE_BOM.xlsx -1RKXBXrd_-dBsxJVyOu0hJuj0XHoeMdKS v2.0/Hardware/OpenArm KER/TLE_V3_BOM.csv -1ZCQiBWh3blXyKXS7pP31KbtrNlMjSwNT v2.0/Hardware/OpenArm KER/TLE_V3_PCB.pdf -1AGhYBPp16XlNQGcyJr5s23KVswHtBjN6 v2.0/Hardware/OpenArm KER/TLE_V3_SCH.pdf -1yFu4qtWyz6Usl2Rlh5nw27mf3TAdeCEj v2.0/Hardware/OpenArm KER/Gerber_PCB2_5_2026-05-26.zip -1mP0gDFgGaX6Ufobr8ocyg71ccsYgfBDw v2.0/Hardware/OpenArm 2.0/Options/OpenArm_2.0_w_Head_Camera.STEP -15p1PYmEKcDmnYQ5Hy_trM8gIoFCADF5a v2.0/Hardware/OpenArm 2.0/OpenArm 2.0 BOM.xlsx -1xHMssSOp9RfZD1K6H80Yyl4uTlpU3lTc v2.0/Hardware/OpenArm 2.0/README.docx -1aU-V3lt_aPrZoRM8FFx6dMQu2f28Ws0I v2.0/Hardware/OpenArm 2.0/OpenArm_2.0.STEP +1CBgghd7gDeWnKbbH2SOlk3yypSj0Dy5a v2.0/Hardware/OpenArm Cell/OpenEvalCell_defeature.STEP +1SmF1Q4BQa-QwytB2GYu1YTOXWrtz8T__ v2.0/Hardware/OpenArm Cell/README.docx +1lFlYdutOH_qJoYCRDOVx_52406vT6uQZ v2.0/Hardware/OpenArm KER/Elec/Cable/KER_CABLE_E.png +165fgBqdHhQrPrDKcQ2ChiE1o8Egzvneh v2.0/Hardware/OpenArm KER/Elec/Cable/KER_CABLE_TOPO.png +10UM2Gz6qYCFwZwsiwa-YFEEOoj03MdE8 v2.0/Hardware/OpenArm KER/Elec/Cable/KER_System_Cable_Documentation_GoogleDocs.docx +1k6zJDhChShjfUxtmVolK55WeUalUOB73 v2.0/Hardware/OpenArm KER/Elec/Cable/XL2605270113-1.pdf +1BhYj9wDtuzjDPiUB79oO1CzT8MO2fW4W v2.0/Hardware/OpenArm KER/Elec/Cable/XL2605270113-2.pdf +1d2mmarW1wPEjvqmleEGBnS4tBeFIQRIk v2.0/Hardware/OpenArm KER/Elec/Cable/XL2605270113-3.pdf +15oduBPeBB_mvUxIssYLczjaK1JEAhQLR v2.0/Hardware/OpenArm KER/Elec/Cable/XL2605270113-4.pdf +116fQx4wdkW6PI5701_fPMBiE-dL3jFkN v2.0/Hardware/OpenArm KER/Elec/PCB/Encoder/Gerber_PCB2_5_2026-05-26.zip +1AsExdG6gjag34Bm5OCkV7l06xHI7n0JB v2.0/Hardware/OpenArm KER/Elec/PCB/Encoder/PickAndPlace_PCB2_5_2026_07_08.xlsx +1OUSSkXK_eH8Nuj2jC9KFM96A7DayR_nk v2.0/Hardware/OpenArm KER/Elec/PCB/Encoder/TLE_BOM.xlsx +1VBS0nRoqaKCasUxytcFdmCmuggOyAgJh v2.0/Hardware/OpenArm KER/Elec/PCB/Encoder/TLE_V3_BOM.csv +1PGFMlxTwNVaEApsOMtOu2dyte7oK4i2V v2.0/Hardware/OpenArm KER/Elec/PCB/Encoder/TLE_V3_PCB.pdf +1ZouTQ7XP46yTY4zb7zyZIrBTyxrGcYup v2.0/Hardware/OpenArm KER/Elec/PCB/Encoder/TLE_V3_SCH.pdf +1DT6S8nH_uEVGQ8Oq0kWuCKNv25_usvLO v2.0/Hardware/OpenArm KER/Elec/PCB/M5Stack/2d.png +1wuVkOq1jqacCah-n8RlzZopptEpdE6o- v2.0/Hardware/OpenArm KER/Elec/PCB/M5Stack/3d.png +1TnuaKxUKv-6MaXFQ8sizg6GM8fwEnZcw v2.0/Hardware/OpenArm KER/Elec/PCB/M5Stack/BOM_M5_485Bus_21_M5_485Bus_21_2026-06-26.xlsx +1QFaPZBisLbQaFaUZuOU9ElYhD3Se32CZ v2.0/Hardware/OpenArm KER/Elec/PCB/M5Stack/Gerber_M5_485Bus_21_2026-06-26.zip +1LS12aoe2XvksNp-gO-gARmlSx9lr3p3y v2.0/Hardware/OpenArm KER/Elec/PCB/M5Stack/Gerber_M5_485Bus_21_2026-08-13.zip +1RWZfWAQ--UOX6SdjN2S5AEbvBdpRBnC9 v2.0/Hardware/OpenArm KER/Elec/PCB/M5Stack/M5_485Bus_SCH.pdf +1NcvvQLV0GuhD0qJMuC_5LPs-KvzLs3BN v2.0/Hardware/OpenArm KER/Elec/PCB/M5Stack/PickAndPlace_M5_485Bus_21_2026-08-13.xlsx +1Su7q0tcZzUQrelV_wr5NAbwXlM4AE8qW v2.0/Hardware/OpenArm KER/OpenArm KER BOM.xlsx +1DWNSQFINY0sE20X86_kdmCDp1YGyWVNy v2.0/Hardware/OpenArm KER/OpenArm KER JIG BASE.STEP +1zlIPie9CycH_r2pLIHclKAHzV2yRIn3l v2.0/Hardware/OpenArm KER/OpenArm KER.STEP +1QCt_oB05_1-gnUoWseIl-wp4ZzqyQDysYyS23wMWsIw v2.0/Hardware/OpenArm KER/README.pdf application/vnd.google-apps.document diff --git a/dev/google-drive-files/generate-file-ids.rb b/dev/google-drive-files/generate-file-ids.rb index 1ab7418..1535a1d 100755 --- a/dev/google-drive-files/generate-file-ids.rb +++ b/dev/google-drive-files/generate-file-ids.rb @@ -44,6 +44,13 @@ def list_files(drive, folder_id, version, parent_path: "", page_token: nil) if item.mime_type == "application/vnd.google-apps.folder" next if EXCLUDED_DIRECTORIES.include?(item.name) list_files(drive, item.id, version, parent_path: "#{parent_path}#{item.name}/") + elsif item.mime_type == "application/vnd.google-apps.document" + # Google Docs can't be downloaded as is. The release job + # exports it as PDF. The MIME type in the third column tells + # the release job to do so. + puts "#{item.id}\t#{parent_path}#{item.name}.pdf\t#{item.mime_type}" + elsif item.mime_type.start_with?("application/vnd.google-apps.") + $stderr.puts "Skipped unsupported Google Workspace file: #{parent_path}#{item.name} (#{item.mime_type})" elsif output?(item.name, version) puts "#{item.id}\t#{parent_path}#{item.name}" end