* feat(release): add guarded prerelease and stable pipeline * feat(release): add guided dws-release entry (cherry picked from commit f7fa7b78f325f3574f0487862fc3e65bba5cdc96)
351 lines
9.8 KiB
YAML
351 lines
9.8 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
pull_request:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
lint:
|
|
name: Lint
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Format Check
|
|
run: |
|
|
unformatted="$(find cmd internal test -name '*.go' -print0 | xargs -0r gofmt -l)"
|
|
test -z "$unformatted" || (printf '%s\n' "$unformatted" && exit 1)
|
|
|
|
- name: Go Vet
|
|
run: go vet ./...
|
|
|
|
# golangci-lint temporarily disabled: v1.64.8 built with Go 1.24 is incompatible with Go 1.25
|
|
# - name: golangci-lint
|
|
# uses: golangci/golangci-lint-action@v6
|
|
# with:
|
|
# version: v1.64.8
|
|
# args: ./...
|
|
|
|
test:
|
|
name: Test
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Install archive tooling
|
|
run: sudo apt-get update && sudo apt-get install -y zip unzip
|
|
|
|
- name: Build
|
|
run: make build
|
|
|
|
- name: Test with Race Detection
|
|
run: |
|
|
go test -v -race -count=1 -timeout=5m \
|
|
./cmd/... \
|
|
./internal/... \
|
|
./pkg/... \
|
|
./test/unit/...
|
|
go test -v -count=1 -timeout=5m \
|
|
./test/cli/...
|
|
|
|
- name: Test engineering scripts
|
|
run: go test -v -count=1 -timeout=5m ./test/scripts/...
|
|
|
|
test-darwin:
|
|
name: Test (macOS auth/keychain)
|
|
runs-on: macos-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Test macOS auth and Keychain paths with Race Detection
|
|
run: go test -v -race -count=1 -timeout=10m ./internal/keychain ./internal/auth ./internal/app
|
|
|
|
test-windows:
|
|
name: Test (Windows)
|
|
runs-on: windows-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Build Windows CLI
|
|
run: go build -o dws.exe ./cmd
|
|
|
|
- name: Test Windows auth and DPAPI paths
|
|
run: |
|
|
go test -v -count=1 -timeout=10m ./internal/keychain ./internal/auth
|
|
go test -v -count=1 -timeout=5m ./internal/app -run '^TestAuth(MigrateKeychain|StatusDiagnosticReportsCiphertextKeyMismatch)'
|
|
|
|
coverage:
|
|
name: Coverage
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Install archive tooling
|
|
run: sudo apt-get update && sudo apt-get install -y zip unzip
|
|
|
|
- name: Build
|
|
run: make build
|
|
|
|
- name: Run tests with coverage
|
|
run: |
|
|
go test -coverprofile=coverage.txt -covermode=atomic ./cmd/... ./internal/...
|
|
go tool cover -func=coverage.txt
|
|
|
|
- name: Generate coverage report
|
|
run: go tool cover -html=coverage.txt -o coverage.html
|
|
|
|
- name: Upload coverage artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: coverage-report
|
|
path: |
|
|
coverage.txt
|
|
coverage.html
|
|
|
|
policy:
|
|
name: Policy Check
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Build
|
|
run: make build
|
|
|
|
- name: Policy
|
|
run: make policy
|
|
|
|
- name: Generated Drift
|
|
run: ./scripts/policy/check-generated-drift.sh
|
|
|
|
edition-tests:
|
|
name: Edition Contract Tests
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Run edition contract tests
|
|
run: go test -v -count=1 ./pkg/editiontest/...
|
|
|
|
code-check:
|
|
name: Code Check
|
|
needs: [lint, test, test-darwin, test-windows, coverage, policy, edition-tests]
|
|
if: ${{ always() }}
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
permissions: {}
|
|
steps:
|
|
- name: Verify code checks
|
|
env:
|
|
LINT_RESULT: ${{ needs.lint.result }}
|
|
TEST_RESULT: ${{ needs.test.result }}
|
|
TEST_DARWIN_RESULT: ${{ needs.test-darwin.result }}
|
|
TEST_WINDOWS_RESULT: ${{ needs.test-windows.result }}
|
|
COVERAGE_RESULT: ${{ needs.coverage.result }}
|
|
POLICY_RESULT: ${{ needs.policy.result }}
|
|
EDITION_TESTS_RESULT: ${{ needs.edition-tests.result }}
|
|
run: |
|
|
set -eu
|
|
failed=0
|
|
for check in \
|
|
"Lint:$LINT_RESULT" \
|
|
"Test:$TEST_RESULT" \
|
|
"Test (macOS auth/keychain):$TEST_DARWIN_RESULT" \
|
|
"Test (Windows):$TEST_WINDOWS_RESULT" \
|
|
"Coverage:$COVERAGE_RESULT" \
|
|
"Policy Check:$POLICY_RESULT" \
|
|
"Edition Contract Tests:$EDITION_TESTS_RESULT"
|
|
do
|
|
name="${check%%:*}"
|
|
result="${check#*:}"
|
|
printf '%s: %s\n' "$name" "$result"
|
|
if [ "$result" != "success" ]; then
|
|
failed=1
|
|
fi
|
|
done
|
|
test "$failed" -eq 0
|
|
|
|
command-compatibility:
|
|
name: Command Compatibility
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
permissions:
|
|
actions: read
|
|
contents: read
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Fetch official release tags
|
|
run: |
|
|
git fetch --force --no-tags \
|
|
https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git \
|
|
'+refs/tags/v*:refs/tags/v*'
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Check command compatibility
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
PUSH_BEFORE_SHA: ${{ github.event.before }}
|
|
run: |
|
|
set -eu
|
|
base_ref="$PUSH_BEFORE_SHA"
|
|
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
|
|
base_ref="$PR_BASE_SHA"
|
|
fi
|
|
stable_ref="$(git tag --merged HEAD --list 'v*' --sort=-version:refname | awk '/^v[0-9]+\.[0-9]+\.[0-9]+$/ { print; exit }')"
|
|
test -n "$base_ref"
|
|
test -n "$stable_ref"
|
|
stable_commit="$(git rev-parse "$stable_ref^{commit}")"
|
|
./scripts/release/verify-delivered-stable.sh "$stable_ref" "$stable_commit"
|
|
./scripts/policy/check-command-compatibility.sh \
|
|
--base-ref "$base_ref" \
|
|
--stable-ref "$stable_ref"
|
|
|
|
cli-smoke:
|
|
name: CLI Smoke
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Run CLI smoke tests
|
|
run: go test -count=1 -timeout=5m ./test/smoke/...
|
|
|
|
mock-mcp-smoke:
|
|
name: Mock MCP Smoke
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Check out repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Run Mock MCP smoke tests
|
|
run: go test -count=1 -timeout=5m ./test/mock_mcp/...
|
|
|
|
ci-gate:
|
|
name: CI Gate
|
|
needs: [code-check, command-compatibility, cli-smoke, mock-mcp-smoke]
|
|
if: ${{ always() }}
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
permissions: {}
|
|
steps:
|
|
- name: Verify required checks
|
|
env:
|
|
CODE_CHECK_RESULT: ${{ needs.code-check.result }}
|
|
COMMAND_COMPATIBILITY_RESULT: ${{ needs.command-compatibility.result }}
|
|
CLI_SMOKE_RESULT: ${{ needs.cli-smoke.result }}
|
|
MOCK_MCP_SMOKE_RESULT: ${{ needs.mock-mcp-smoke.result }}
|
|
run: |
|
|
set -eu
|
|
failed=0
|
|
for check in \
|
|
"Code Check:$CODE_CHECK_RESULT" \
|
|
"Command Compatibility:$COMMAND_COMPATIBILITY_RESULT" \
|
|
"CLI Smoke:$CLI_SMOKE_RESULT" \
|
|
"Mock MCP Smoke:$MOCK_MCP_SMOKE_RESULT"
|
|
do
|
|
name="${check%%:*}"
|
|
result="${check#*:}"
|
|
printf '%s: %s\n' "$name" "$result"
|
|
if [ "$result" != "success" ]; then
|
|
failed=1
|
|
fi
|
|
done
|
|
test "$failed" -eq 0
|
|
|
|
notify-downstream:
|
|
name: Notify Wukong Overlay
|
|
needs: [ci-gate]
|
|
runs-on: ubuntu-latest
|
|
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
permissions: {}
|
|
steps:
|
|
- name: Trigger downstream CI
|
|
run: |
|
|
# Trigger internal GitLab CI pipeline via webhook.
|
|
# WUKONG_TRIGGER_TOKEN is a repository secret.
|
|
if [ -n "${{ secrets.WUKONG_TRIGGER_TOKEN }}" ]; then
|
|
curl --fail --silent --show-error \
|
|
-X POST \
|
|
-F "token=${{ secrets.WUKONG_TRIGGER_TOKEN }}" \
|
|
-F "ref=main" \
|
|
-F "variables[UPSTREAM_SHA]=${{ github.sha }}" \
|
|
"${{ secrets.WUKONG_TRIGGER_URL }}"
|
|
echo "Downstream CI triggered."
|
|
else
|
|
echo "No WUKONG_TRIGGER_TOKEN configured, skipping downstream notification."
|
|
fi
|