diff --git a/.github/workflows/check-sample.yml b/.github/workflows/check-sample.yml index c49895f9b..516363816 100644 --- a/.github/workflows/check-sample.yml +++ b/.github/workflows/check-sample.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Check for required files run: | @@ -37,14 +37,14 @@ jobs: - [ ] I have documented how to provision any third-party services in the readme - [ ] I have documented how to run the sample in the readme (locally and with Defang) `; - + // Get the current PR const { data: pullRequest } = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, pull_number: pr_number }); - + // Check if the checklist already exists in the PR description if (!pullRequest.body.includes(checklist)) { // Update the PR description with the checklist diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 085c43bcb..bf5fd87aa 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -27,13 +27,13 @@ jobs: run: go test -test.short -v ./... working-directory: src - - name: Build MacOS binary - run: GOOS=darwin go build ./cmd/cli - working-directory: src + # - name: Build MacOS binary + # run: GOOS=darwin go build ./cmd/cli + # working-directory: src - - name: Build Windows binary - run: GOOS=windows go build ./cmd/cli - working-directory: src + # - name: Build Windows binary + # run: GOOS=windows go build ./cmd/cli + # working-directory: src - name: Verify Go modules working-directory: src @@ -43,6 +43,7 @@ jobs: nix-shell-test: runs-on: ubuntu-latest + needs: go-test steps: - uses: actions/checkout@v4 @@ -54,7 +55,7 @@ jobs: - name: Check nix-shell default.nix run: | set -o pipefail - nix-shell --pure -E 'with import {}; mkShell { buildInputs = [ (import ./default.nix {}) ]; }' --run defang 2>&1 | sed -u 's|\s\+got:|::error file=pkgs/defang/cli.nix,line=6::Replace the vendorHash with the correct value:|' + nix-shell --pure -E 'with import {}; mkShell { buildInputs = [ (import ./default.nix {}) ]; }' --run defang 2>&1 | sed -u 's|\s\+got:|::error file=pkgs/defang/cli.nix,line=9::Replace the vendorHash with the correct value:|' # go-byoc-test: # runs-on: ubuntu-latest @@ -114,16 +115,17 @@ jobs: run: go run ./cmd/cli compose stop -f tests/sanity/compose.yaml --debug working-directory: src - go-release: - if: startsWith(github.ref, 'refs/tags/v') # only run this step on tagged commits + build-and-sign: + name: Build app and sign files with Trusted Signing + environment: release needs: go-test - runs-on: macos-latest - permissions: - contents: write # to upload archives as GitHub Releases + runs-on: windows-latest # for signtool + env: # from https://github.com/spiffe/spire/pull/5158 + GOPATH: 'D:\golang\go' + GOCACHE: 'D:\golang\cache' + GOMODCACHE: 'D:\golang\modcache' steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 # for release notes - name: Set up Go uses: actions/setup-go@v5 @@ -135,36 +137,148 @@ jobs: run: go mod download working-directory: src - - name: Install Nix (for nix-prefetch-url) - uses: cachix/install-nix-action@v26 + - name: Run GoReleaser (Windows and Linux) + uses: goreleaser/goreleaser-action@v5 + with: + # distribution: goreleaser-pro # either 'goreleaser' (default) or 'goreleaser-pro' + # version: latest + args: build --id defang-cli ${{ !startsWith(github.ref, 'refs/tags/v') && '--snapshot' }} + workdir: src - - name: Run GoReleaser + # From https://github.com/Azure/trusted-signing-action/pull/37 + - name: Azure login + uses: azure/login@v1 + if: startsWith(github.ref, 'refs/tags/v') # only run this step on tagged commits + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Trusted Signing + uses: Azure/trusted-signing-action@v0.3.20 + if: startsWith(github.ref, 'refs/tags/v') # only run this step on tagged commits + with: + endpoint: https://wus2.codesigning.azure.net/ # from Azure portal + trusted-signing-account-name: DefangLabs # from Azure portal + certificate-profile-name: signed-binary-test # from Azure portal + files-folder: ${{ github.workspace }}\src\dist + files-folder-filter: exe # no dll + files-folder-recurse: true + file-digest: SHA256 + timestamp-rfc3161: http://timestamp.acs.microsoft.com + timestamp-digest: SHA256 + exclude-environment-credential: true + exclude-workload-identity-credential: true + exclude-managed-identity-credential: true + exclude-shared-token-cache-credential: true + exclude-visual-studio-credential: true + exclude-visual-studio-code-credential: true + exclude-azure-cli-credential: false + exclude-azure-powershell-credential: true + exclude-azure-developer-cli-credential: true + exclude-interactive-browser-credential: true + + - name: Upload dist-win folder + uses: actions/upload-artifact@v4 + with: + name: dist-win + path: src/dist + if-no-files-found: error + + build-and-sign-mac: + name: Build app and sign MacOS + needs: go-test + runs-on: macos-latest # for codesign and notarytool + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: src/go.mod + cache-dependency-path: src/go.sum + + # - name: Download Go dependencies + # run: go mod download + # working-directory: src + + - name: Run GoReleaser (macOS) uses: goreleaser/goreleaser-action@v5 with: # distribution: goreleaser-pro # either 'goreleaser' (default) or 'goreleaser-pro' # version: latest - args: release --clean + args: build --id defang-mac ${{ !startsWith(github.ref, 'refs/tags/v') && '--snapshot' }} workdir: src env: - GH_PAT_WINGET: ${{ secrets.GH_PAT_WINGET }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GITHUB_TOKEN is limited to the current repository MACOS_CERTIFICATE_NAME: ${{ secrets.MACOS_CERTIFICATE_NAME }} MACOS_P12_BASE64: ${{ secrets.MACOS_P12_BASE64 }} MACOS_P12_PASSWORD: ${{ secrets.MACOS_P12_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + + - name: Upload dist-mac folder + uses: actions/upload-artifact@v4 + with: + name: dist-mac + path: src/dist + if-no-files-found: error + + go-release: + # environment: release + if: startsWith(github.ref, 'refs/tags/v') # only run this step on tagged commits + needs: + - build-and-sign-mac + - build-and-sign + runs-on: macos-latest # for notarization + permissions: + contents: write # to upload archives as GitHub Releases + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # for release notes + + - name: Install Nix (for nix-prefetch-url) + uses: cachix/install-nix-action@v26 + + - name: Download dist-mac folder + uses: actions/download-artifact@v4 + with: + name: dist-mac + path: src/dist + + - name: Download dist-win folder + uses: actions/download-artifact@v4 + with: + name: dist-win + path: src/dist + + - name: List files + run: ls -lR src/dist + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + distribution: goreleaser-pro # either 'goreleaser' (default) or 'goreleaser-pro' + # version: latest + args: release --config .goreleaser-prebuilt.yml + workdir: src + env: + GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} + GH_PAT_WINGET: ${{ secrets.GH_PAT_WINGET }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GITHUB_TOKEN is limited to the current repository DISCORD_WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }} DISCORD_WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} - - name: Notarize macOS app + - name: Notarize macOS app # TODO: move to goreleaser.yml shell: bash run: | - xcrun notarytool submit src/dist/defang_*_macOS.zip --apple-id "$MACOS_NOTARIZATION_APPLE_ID" --team-id "$MACOS_NOTARIZATION_TEAM_ID" --password "$MACOS_NOTARIZATION_APP_PW" + bin/notarize.sh dist/defang_*_macOS.zip + working-directory: src env: MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }} MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }} MACOS_NOTARIZATION_APP_PW: ${{ secrets.MACOS_NOTARIZATION_APP_PW }} - post-build: + post-release: runs-on: ubuntu-latest needs: go-release @@ -200,7 +314,7 @@ jobs: client-payload: '{"version": "${{ github.ref_name }}"}' - name: Trigger Homebrew Formula Update - uses: peter-evans/repository-dispatch@v1 + uses: peter-evans/repository-dispatch@v3 with: token: ${{ secrets.HOMEBREW_ACTION_TRIGGER_TOKEN }} repository: DefangLabs/homebrew-defang @@ -228,7 +342,7 @@ jobs: # install dependencies npm ci --ignore-scripts - #b uild + # build npm run build # make the cli.js executable diff --git a/flake.nix b/flake.nix index d9997d9c5..a085e5525 100644 --- a/flake.nix +++ b/flake.nix @@ -16,6 +16,7 @@ gnumake gnused # force Linux `sed` everywhere go_1_21 + goreleaser nixfmt nodejs_20 # for Pulumi, must match values in package.json pulumi-bin diff --git a/src/.goreleaser-prebuilt.yml b/src/.goreleaser-prebuilt.yml new file mode 100644 index 000000000..29314ae48 --- /dev/null +++ b/src/.goreleaser-prebuilt.yml @@ -0,0 +1,102 @@ +# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json +project_name: defang +builds: + - builder: prebuilt + goos: + - linux + - windows + - darwin + goarch: + - amd64 + - arm64 + # - 386 + goamd64: + - v1 + prebuilt: + path: dist-{{ .Os }}/defang_{{ .Os }}_{{ .Arch }}{{ with .Amd64 }}_{{ . }}{{ end }}/defang{{ .Ext }} + binary: defang + +source: + enabled: false + +archives: + - format_overrides: + - goos: darwin + format: zip + - goos: windows + format: zip + # replace "darwin" with "macOS" in the filename; replace "all" with ""; NOTE: if you change this, also change go.yml GitHub Actions workflow + name_template: '{{ .ProjectName }}_{{ .Version }}_{{ if eq .Os "darwin" }}macOS{{ else }}{{ .Os }}{{ end }}{{ if ne .Arch "all" }}_{{ .Arch }}{{ end }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}' + hooks: + after: + - '{{ if eq .Os "darwin" }}./bin/notarize.sh "{{ .Path }}"{{ else }}true{{ end }}' + +release: + github: + owner: DefangLabs + name: defang + header: | + # Defang CLI + This is the Command Line Interface (CLI) for [Defang](https://defang.io). This is a beta version and is provided as-is, intended primarily for testing purposes. + For alternative installation methods, please check the [README](https://github.com/DefangLabs/defang/blob/main/README.md). + ## Manual installation Instructions + 1. Download the archive file for your Operating System. + 2. Extract the archive. This should reveal the binary file for Defang. + 3. Manually place the binary file in a directory that's included in your system's `PATH` environment variable. + ### Additional Step for MacOS Users + If you're having trouble running the binary on MacOS, please check our [FAQs](https://docs.defang.io/docs/faq#im-having-trouble-running-the-binary-on-my-mac-what-should-i-do). + + Please remember this software is in beta, so please report any issues or feedback through our GitHub page. Your help in improving Defang is greatly appreciated! + # mode: keep-existing + # draft: true + # replace_existing_draft: true + # prerelease: "true" + +nix: + # commit_author: defang-io + - homepage: https://defang.io/ + description: Defang is the easiest way for developers to create and deploy their containerized applications + license: "mit" + repository: + owner: DefangLabs + name: defang + post_install: | + installShellCompletion --cmd defang \ + --bash <($out/bin/defang completion bash) \ + --zsh <($out/bin/defang completion zsh) \ + --fish <($out/bin/defang completion fish) + +changelog: + filters: + exclude: + # Ignore messages like "defang: v0.5.3 -> v0.5.4" (which are actually for the previous version) + - "^defang: v[0-9]+\\.[0-9]+\\.[0-9]+ -> v[0-9]+\\.[0-9]+\\.[0-9]+$" + - "^Merge branch " + - "^Merge remote-tracking branch " + - "^New version: DefangLabs." + +winget: + - publisher: DefangLabs + name: Defang + short_description: The Defang command-line interface (CLI) + description: Defang is the easiest way for developers to create and deploy their containerized applications to the cloud. + license: MIT + publisher_url: https://defang.io/ + homepage: https://github.com/DefangLabs/defang/ + publisher_support_url: https://github.com/DefangLabs/defang/issues/ + repository: + token: "{{ .Env.GH_PAT_WINGET }}" + owner: DefangLabs + name: winget-pkgs + branch: "Defang-{{.Version}}" + pull_request: + enabled: true + draft: true + base: + owner: microsoft + name: winget-pkgs + branch: master + +announce: + discord: + enabled: true diff --git a/src/.goreleaser.yml b/src/.goreleaser.yml index 542f21779..b111f8df0 100644 --- a/src/.goreleaser.yml +++ b/src/.goreleaser.yml @@ -36,7 +36,8 @@ universal_binaries: - ./bin/codesign.sh "{{ .Path }}" archives: - - format_overrides: + - id: defang-archive + format_overrides: - goos: darwin format: zip - goos: windows diff --git a/src/bin/notarize.sh b/src/bin/notarize.sh new file mode 100755 index 000000000..8c90d4cee --- /dev/null +++ b/src/bin/notarize.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -e + +# Bail if we didn't get one (and only one) argument +if [ $# -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +if [ -z "$MACOS_NOTARIZATION_APPLE_ID" ]; then + echo "Error: missing env var MACOS_NOTARIZATION_APPLE_ID" + exit 2 +fi + +if [ -z "$MACOS_NOTARIZATION_TEAM_ID" ]; then + echo "Error: missing env var MACOS_NOTARIZATION_TEAM_ID" + exit 3 +fi + +if [ -z "$MACOS_NOTARIZATION_APP_PW" ]; then + echo "Error: missing env var MACOS_NOTARIZATION_APP_PW" + exit 4 +fi + +[ "$ACTIONS_STEP_DEBUG" = 'true' ] || [ "$DEBUG" = 'true' ] && set -x + +xcrun notarytool submit "$1" --apple-id "$MACOS_NOTARIZATION_APPLE_ID" --team-id "$MACOS_NOTARIZATION_TEAM_ID" --password "$MACOS_NOTARIZATION_APP_PW"