mirror of
https://github.com/googleworkspace/cli.git
synced 2026-09-14 16:47:13 +08:00
298 lines
9.0 KiB
YAML
298 lines
9.0 KiB
YAML
# Copyright 2026 Google LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
|
|
jobs:
|
|
test:
|
|
name: Test
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
matrix:
|
|
os: [ubuntu-latest, macos-latest]
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@v0.0.7
|
|
|
|
- name: Cache cargo
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
key: test-${{ matrix.os }}
|
|
|
|
- name: Run tests
|
|
run: cargo test --verbose
|
|
|
|
lint:
|
|
name: Lint
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: rustfmt, clippy
|
|
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@v0.0.7
|
|
|
|
- name: Cache cargo
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
key: lint
|
|
|
|
- name: Check formatting
|
|
run: |
|
|
if ! cargo fmt --all -- --check; then
|
|
echo "::error::Cargo fmt failed. Please run 'cargo fmt --all' locally and commit the changes."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Clippy
|
|
run: cargo clippy -- -D warnings
|
|
|
|
policy-check:
|
|
name: Policy Check
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
- name: Enforce AGENTS.md rules
|
|
run: |
|
|
if grep -qE "^google-[a-zA-Z0-9_-]+[[:space:]]*=" Cargo.toml; then
|
|
echo "::error file=Cargo.toml::Violates AGENTS.md: Adding generated google-* crates is prohibited. The CLI uses dynamic schema discovery at runtime."
|
|
exit 1
|
|
fi
|
|
echo "Policy check passed."
|
|
- name: Enforce Changeset File
|
|
if: github.event_name == 'pull_request'
|
|
run: |
|
|
git fetch origin ${{ github.base_ref }}
|
|
if ! git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "^.changeset/.*\.md$"; then
|
|
echo "::error::A Changeset file is required! Please run 'npx changeset' or manually create a markdown file in the .changeset directory describing your changes to automatically version and release this PR."
|
|
exit 1
|
|
fi
|
|
echo "Changeset file found!"
|
|
|
|
skills:
|
|
name: Verify Skills
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@v0.0.7
|
|
|
|
- name: Cache cargo
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
key: skills
|
|
|
|
- name: Regenerate skills
|
|
run: cargo run -- generate-skills --output-dir skills
|
|
|
|
- name: Check for drift
|
|
run: |
|
|
if ! git diff --exit-code skills/; then
|
|
echo "::error::Skills are out of date. Run 'cargo run -- generate-skills' and commit the changes."
|
|
exit 1
|
|
fi
|
|
|
|
coverage:
|
|
name: Coverage
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: llvm-tools-preview
|
|
- name: Cache cargo
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
key: coverage
|
|
- name: Install cargo-llvm-cov
|
|
uses: taiki-e/install-action@cargo-llvm-cov
|
|
- name: Generate code coverage
|
|
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
|
|
|
|
build:
|
|
name: Build
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
- os: ubuntu-latest
|
|
target: x86_64-unknown-linux-gnu
|
|
- os: ubuntu-latest
|
|
target: aarch64-unknown-linux-gnu
|
|
- os: macos-latest
|
|
target: x86_64-apple-darwin
|
|
- os: macos-latest
|
|
target: aarch64-apple-darwin
|
|
- os: windows-latest
|
|
target: x86_64-pc-windows-msvc
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: ${{ matrix.target }}
|
|
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@v0.0.7
|
|
|
|
- name: Cache cargo
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
key: build-${{ matrix.target }}
|
|
|
|
- name: Install cross-compilation tools
|
|
if: matrix.target == 'aarch64-unknown-linux-gnu'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y gcc-aarch64-linux-gnu
|
|
|
|
- name: Disable Windows Defender scanning for cargo
|
|
if: runner.os == 'Windows'
|
|
run: |
|
|
Add-MpPreference -ExclusionPath "$env:USERPROFILE\.cargo"
|
|
Add-MpPreference -ExclusionPath "$env:USERPROFILE\.rustup"
|
|
Add-MpPreference -ExclusionPath "${{ github.workspace }}\target"
|
|
|
|
- name: Build
|
|
run: cargo build --release --target ${{ matrix.target }}
|
|
env:
|
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
|
|
|
- name: Upload binary
|
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: gws-linux-x86_64
|
|
path: target/x86_64-unknown-linux-gnu/release/gws
|
|
retention-days: 1
|
|
|
|
smoketest:
|
|
name: API Smoketest
|
|
needs: build
|
|
if: github.event.pull_request.head.repo.full_name == github.repository || github.event_name != 'pull_request'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Download binary
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: gws-linux-x86_64
|
|
path: ./bin
|
|
|
|
- name: Make binary executable
|
|
run: chmod +x ./bin/gws
|
|
|
|
- name: Decode credentials
|
|
env:
|
|
GOOGLE_CREDENTIALS_JSON: ${{ secrets.GOOGLE_CREDENTIALS_JSON }}
|
|
run: |
|
|
if [ -z "$GOOGLE_CREDENTIALS_JSON" ]; then
|
|
echo "::error::GOOGLE_CREDENTIALS_JSON secret is not set"
|
|
exit 1
|
|
fi
|
|
echo "$GOOGLE_CREDENTIALS_JSON" | base64 -d > /tmp/credentials.json
|
|
|
|
- name: Smoketest — help
|
|
run: ./bin/gws --help
|
|
|
|
- name: Smoketest — schema introspection
|
|
run: ./bin/gws schema drive.files.list | jq -e '.httpMethod'
|
|
|
|
- name: Smoketest — Drive files list
|
|
env:
|
|
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE: /tmp/credentials.json
|
|
run: |
|
|
./bin/gws drive files list \
|
|
--params '{"pageSize": 1, "fields": "files(id,mimeType)"}' \
|
|
| jq -e '.files'
|
|
|
|
- name: Smoketest — Gmail messages
|
|
env:
|
|
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE: /tmp/credentials.json
|
|
run: |
|
|
./bin/gws gmail users messages list \
|
|
--params '{"userId": "me", "maxResults": 1, "fields": "messages(id)"}' \
|
|
| jq -e '.messages'
|
|
|
|
- name: Smoketest — Calendar events
|
|
env:
|
|
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE: /tmp/credentials.json
|
|
run: |
|
|
./bin/gws calendar events list \
|
|
--params '{"calendarId": "primary", "maxResults": 1, "fields": "kind,items(id,status)"}' \
|
|
| jq -e '.kind'
|
|
|
|
- name: Smoketest — Slides presentation
|
|
env:
|
|
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE: /tmp/credentials.json
|
|
run: |
|
|
./bin/gws slides presentations get \
|
|
--params '{"presentationId": "1knOKD_87JWE4qsEbO4r5O91IxTER5ybBBhOJgZ1yLFI", "fields": "presentationId,slides(objectId)"}' \
|
|
| jq -e '.presentationId'
|
|
|
|
- name: Smoketest — pagination
|
|
env:
|
|
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE: /tmp/credentials.json
|
|
run: |
|
|
LINES=$(./bin/gws drive files list \
|
|
--params '{"pageSize": 1, "fields": "nextPageToken,files(id)"}' \
|
|
--page-all --page-limit 2 \
|
|
| wc -l)
|
|
if [ "$LINES" -lt 2 ]; then
|
|
echo "::error::Expected at least 2 NDJSON lines from pagination, got $LINES"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Smoketest — error handling
|
|
run: |
|
|
if ./bin/gws fakeservice list 2>&1; then
|
|
echo "::error::Expected exit code 1 for unknown service"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Cleanup credentials
|
|
if: always()
|
|
run: rm -f /tmp/credentials.json
|