# Release workflow for @googleworkspace/cli # # Triggered by pushing a semver tag (e.g. v0.22.3). # Builds platform binaries, creates a GitHub Release, publishes to npm and crates.io. name: Release permissions: contents: write attestations: write id-token: write on: pull_request: push: tags: - 'v[0-9]+.[0-9]+.[0-9]+*' env: CARGO_TERM_COLOR: always jobs: plan: runs-on: ubuntu-latest outputs: version: ${{ steps.meta.outputs.version }} prerelease: ${{ steps.meta.outputs.prerelease }} publishing: ${{ github.ref_type == 'tag' }} steps: - id: meta run: | TAG="${GITHUB_REF_NAME}" VERSION="${TAG#v}" echo "version=${VERSION}" >> "$GITHUB_OUTPUT" if [[ "$VERSION" == *-* ]]; then echo "prerelease=true" >> "$GITHUB_OUTPUT" else echo "prerelease=false" >> "$GITHUB_OUTPUT" fi build: needs: plan strategy: fail-fast: false matrix: include: - target: aarch64-apple-darwin runner: macos-latest archive: tar.gz - target: x86_64-apple-darwin runner: macos-latest archive: tar.gz - target: aarch64-unknown-linux-gnu runner: ubuntu-latest archive: tar.gz cross: true - target: aarch64-unknown-linux-musl runner: ubuntu-latest archive: tar.gz cross: true - target: x86_64-unknown-linux-gnu runner: ubuntu-latest archive: tar.gz - target: x86_64-unknown-linux-musl runner: ubuntu-latest archive: tar.gz cross: true - target: x86_64-pc-windows-msvc runner: windows-latest archive: zip runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable with: targets: ${{ matrix.target }} - name: Install cross if: matrix.cross run: cargo install cross --git https://github.com/cross-rs/cross --tag v0.2.5 - name: Build run: | if [ "${{ matrix.cross }}" = "true" ]; then cross build --release --target ${{ matrix.target }} --locked else cargo build --release --target ${{ matrix.target }} --locked fi shell: bash - name: Package (unix) if: matrix.archive == 'tar.gz' run: | ARTIFACT="google-workspace-cli-${{ matrix.target }}" mkdir -p staging cp "target/${{ matrix.target }}/release/gws" staging/ cp LICENSE README.md CHANGELOG.md staging/ tar czf "${ARTIFACT}.tar.gz" -C staging . shasum -a 256 "${ARTIFACT}.tar.gz" > "${ARTIFACT}.tar.gz.sha256" shell: bash - name: Package (windows) if: matrix.archive == 'zip' run: | $ARTIFACT = "google-workspace-cli-${{ matrix.target }}" New-Item -ItemType Directory -Path $ARTIFACT Copy-Item "target/${{ matrix.target }}/release/gws.exe" "$ARTIFACT/" Copy-Item LICENSE, README.md, CHANGELOG.md "$ARTIFACT/" Compress-Archive -Path "$ARTIFACT/*" -DestinationPath "$ARTIFACT.zip" (Get-FileHash "$ARTIFACT.zip" -Algorithm SHA256).Hash.ToLower() + " $ARTIFACT.zip" | Out-File -Encoding ascii "$ARTIFACT.zip.sha256" shell: pwsh - name: Attest if: github.ref_type == 'tag' uses: actions/attest-build-provenance@43d14bc2b83dec42d39ecae14e916627a18bb661 # v3 with: subject-path: google-workspace-cli-${{ matrix.target }}.${{ matrix.archive }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: binary-${{ matrix.target }} path: | google-workspace-cli-${{ matrix.target }}.${{ matrix.archive }} google-workspace-cli-${{ matrix.target }}.${{ matrix.archive }}.sha256 release: needs: [plan, build] if: github.ref_type == 'tag' runs-on: ubuntu-latest steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: pattern: binary-* path: artifacts/ merge-multiple: true - name: Create GitHub Release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | PRERELEASE_FLAG="" if [ "${{ needs.plan.outputs.prerelease }}" = "true" ]; then PRERELEASE_FLAG="--prerelease" fi NOTES="## Installation Download the archive for your OS and architecture from the assets below. ### Linux / macOS Replace \`\` with your platform (e.g., \`aarch64-apple-darwin\` or \`x86_64-unknown-linux-gnu\`). \`\`\`bash # 1. Download the archive and its checksum curl -sLO https://github.com/googleworkspace/cli/releases/download/${{ github.ref_name }}/google-workspace-cli-.tar.gz curl -sLO https://github.com/googleworkspace/cli/releases/download/${{ github.ref_name }}/google-workspace-cli-.tar.gz.sha256 # 2. Verify the checksum shasum -a 256 -c google-workspace-cli-.tar.gz.sha256 # 3. Extract and install tar -xzf google-workspace-cli-.tar.gz chmod +x gws sudo mv gws /usr/local/bin/ \`\`\` ### Windows 1. Download \`google-workspace-cli-x86_64-pc-windows-msvc.zip\` and its \`.sha256\` file 2. Verify the checksum (e.g., using PowerShell \`Get-FileHash\`) 3. Extract the archive and move \`gws.exe\` to a directory included in your system \`PATH\`. --- " gh release create "${{ github.ref_name }}" \ --target "${{ github.sha }}" \ --title "${{ github.ref_name }}" \ --notes "$NOTES" \ --generate-notes \ $PRERELEASE_FLAG \ artifacts/* publish-npm: needs: [plan, release] runs-on: ubuntu-latest if: ${{ needs.plan.outputs.publishing == 'true' && needs.plan.outputs.prerelease == 'false' }} steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version: '20.x' registry-url: 'https://wombat-dressing-room.appspot.com' - name: Publish to npm working-directory: npm run: npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} publish-cargo: needs: [plan, release] runs-on: ubuntu-latest if: ${{ needs.plan.outputs.publishing == 'true' && needs.plan.outputs.prerelease == 'false' }} steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable # Publish library crate first (CLI depends on it) - name: Publish google-workspace run: cargo publish --package google-workspace env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} # Wait for crates.io to index the library crate - name: Wait for crates.io index run: sleep 30 - name: Publish google-workspace-cli run: cargo publish --package google-workspace-cli env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}