diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml index ba5bef4f3f..81f4d631ea 100644 --- a/.github/actions/build-electron/action.yml +++ b/.github/actions/build-electron/action.yml @@ -219,6 +219,7 @@ runs: - name: Publish Electron Dist ${{ inputs.step-suffix }} if: ${{ inputs.is-release == 'true' }} shell: bash + id: github-upload run: | rm -rf src/out/Default/obj cd src/electron @@ -229,6 +230,11 @@ runs: echo 'Uploading Electron release distribution to GitHub releases' script/release/uploaders/upload.py --verbose fi + - name: Generate artifact attestation + if: ${{ inputs.is-release == 'true' }} + uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 + with: + subject-path: ${{ steps.github-upload.outputs.UPLOADED_PATHS }} - name: Generate siso report if: ${{ inputs.target-platform != 'win' && !cancelled() }} shell: bash diff --git a/.github/workflows/linux-publish.yml b/.github/workflows/linux-publish.yml index 0c197a23de..11ff9ac195 100644 --- a/.github/workflows/linux-publish.yml +++ b/.github/workflows/linux-publish.yml @@ -44,9 +44,11 @@ jobs: uses: ./src/electron/.github/actions/checkout publish-x64: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-linux with: environment: production-release @@ -61,9 +63,11 @@ jobs: secrets: inherit publish-arm: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-linux with: environment: production-release @@ -78,9 +82,11 @@ jobs: secrets: inherit publish-arm64: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-linux with: environment: production-release diff --git a/.github/workflows/macos-publish.yml b/.github/workflows/macos-publish.yml index 6adb2a88a1..f1673ad64c 100644 --- a/.github/workflows/macos-publish.yml +++ b/.github/workflows/macos-publish.yml @@ -48,9 +48,11 @@ jobs: target-platform: macos publish-x64-darwin: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-macos with: environment: production-release @@ -65,9 +67,11 @@ jobs: secrets: inherit publish-x64-mas: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-macos with: environment: production-release @@ -82,9 +86,11 @@ jobs: secrets: inherit publish-arm64-darwin: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-macos with: environment: production-release @@ -99,9 +105,11 @@ jobs: secrets: inherit publish-arm64-mas: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-macos with: environment: production-release diff --git a/.github/workflows/pipeline-electron-lint.yml b/.github/workflows/pipeline-electron-lint.yml index 9bbb40b5cf..e850def965 100644 --- a/.github/workflows/pipeline-electron-lint.yml +++ b/.github/workflows/pipeline-electron-lint.yml @@ -85,4 +85,8 @@ jobs: run: | cd src/electron node script/yarn.js tsc -p tsconfig.script.json - + - name: Check GHA Workflows + shell: bash + run: | + cd src/electron + node script/copy-pipeline-segment-publish.js --check diff --git a/.github/workflows/pipeline-segment-electron-publish.yml b/.github/workflows/pipeline-segment-electron-publish.yml new file mode 100644 index 0000000000..805d1e7ca0 --- /dev/null +++ b/.github/workflows/pipeline-segment-electron-publish.yml @@ -0,0 +1,242 @@ +# AUTOGENERATED FILE - DO NOT EDIT MANUALLY +# ONLY EDIT .github/workflows/pipeline-segment-electron-build.yml + +name: Pipeline Segment - Electron Build +on: + workflow_call: + inputs: + environment: + description: using the production or testing environment + required: false + type: string + target-platform: + type: string + description: Platform to run on, can be macos, win or linux + required: true + target-arch: + type: string + description: Arch to build for, can be x64, arm64, ia32 or arm + required: true + target-variant: + type: string + description: Variant to build for, no effect on non-macOS target platforms. Can + be darwin, mas or all. + default: all + build-runs-on: + type: string + description: What host to run the build + required: true + build-container: + type: string + description: JSON container information for aks runs-on + required: false + default: '{"image":null}' + is-release: + description: Whether this build job is a release job + required: true + type: boolean + default: false + gn-build-type: + description: The gn build type - testing or release + required: true + type: string + default: testing + generate-symbols: + description: Whether or not to generate symbols + required: true + type: boolean + default: false + upload-to-storage: + description: Whether or not to upload build artifacts to external storage + required: true + type: string + default: "0" + is-asan: + description: Building the Address Sanitizer (ASan) Linux build + required: false + type: boolean + default: false + upload-out-gen-artifacts: + description: Whether to upload the src/gen artifacts + required: false + type: boolean + default: false + enable-ssh: + description: Enable SSH debugging + required: false + type: boolean + default: false +permissions: {} +concurrency: + group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch + }}-${{ inputs.target-variant }}-${{ inputs.is-asan }}-${{ + github.ref_protected == true && github.run_id || github.ref }} + cancel-in-progress: ${{ github.ref_protected != true }} +env: + CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }} + CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }} + DD_API_KEY: ${{ secrets.DD_API_KEY }} + ELECTRON_ARTIFACTS_BLOB_STORAGE: ${{ secrets.ELECTRON_ARTIFACTS_BLOB_STORAGE }} + ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }} + SUDOWOODO_EXCHANGE_URL: ${{ secrets.SUDOWOODO_EXCHANGE_URL }} + SUDOWOODO_EXCHANGE_TOKEN: ${{ secrets.SUDOWOODO_EXCHANGE_TOKEN }} + GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && + '--custom-var=checkout_mac=True --custom-var=host_os=mac' || + inputs.target-platform == 'win' && '--custom-var=checkout_win=True' || + '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }} + ELECTRON_OUT_DIR: Default + ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }} +jobs: + build: + defaults: + run: + shell: bash + runs-on: ${{ inputs.build-runs-on }} + permissions: + attestations: write + contents: read + id-token: write + container: ${{ fromJSON(inputs.build-container) }} + environment: ${{ inputs.environment }} + env: + TARGET_ARCH: ${{ inputs.target-arch }} + TARGET_PLATFORM: ${{ inputs.target-platform }} + steps: + - name: Create src dir + run: | + mkdir src + - name: Checkout Electron + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + path: src/electron + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + - name: Setup SSH Debugging + if: ${{ inputs.target-platform == 'macos' && (inputs.enable-ssh || + env.ACTIONS_STEP_DEBUG == 'true') }} + uses: ./src/electron/.github/actions/ssh-debug + with: + tunnel: "true" + env: + CLOUDFLARE_TUNNEL_CERT: ${{ secrets.CLOUDFLARE_TUNNEL_CERT }} + CLOUDFLARE_TUNNEL_HOSTNAME: ${{ vars.CLOUDFLARE_TUNNEL_HOSTNAME }} + CLOUDFLARE_USER_CA_CERT: ${{ secrets.CLOUDFLARE_USER_CA_CERT }} + AUTHORIZED_USERS: ${{ secrets.SSH_DEBUG_AUTHORIZED_USERS }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Free up space (macOS) + if: ${{ inputs.target-platform == 'macos' }} + uses: ./src/electron/.github/actions/free-space-macos + - name: Check disk space after freeing up space + if: ${{ inputs.target-platform == 'macos' }} + run: df -h + - name: Setup Node.js/npm + if: ${{ inputs.target-platform == 'macos' }} + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 + with: + node-version: 22.21.x + cache: yarn + cache-dependency-path: src/electron/yarn.lock + - name: Install Dependencies + uses: ./src/electron/.github/actions/install-dependencies + - name: Install AZCopy + if: ${{ inputs.target-platform == 'macos' }} + run: brew install azcopy + - name: Set GN_EXTRA_ARGS for Linux + if: ${{ inputs.target-platform == 'linux' }} + run: > + if [ "${{ inputs.target-arch }}" = "arm" ]; then + if [ "${{ inputs.is-release }}" = true ]; then + GN_EXTRA_ARGS='target_cpu="arm" build_tflite_with_xnnpack=false symbol_level=1' + else + GN_EXTRA_ARGS='target_cpu="arm" build_tflite_with_xnnpack=false' + fi + elif [ "${{ inputs.target-arch }}" = "arm64" ]; then + GN_EXTRA_ARGS='target_cpu="arm64" fatal_linker_warnings=false enable_linux_installer=false' + elif [ "${{ inputs.is-asan }}" = true ]; then + GN_EXTRA_ARGS='is_asan=true' + fi + + echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV + - name: Set Chromium Git Cookie + uses: ./src/electron/.github/actions/set-chromium-cookie + - name: Install Build Tools + uses: ./src/electron/.github/actions/install-build-tools + - name: Generate DEPS Hash + run: | + node src/electron/script/generate-deps-hash.js + DEPSHASH=v1-src-cache-$(cat src/electron/.depshash) + echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV + echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV + - name: Restore src cache via AZCopy + if: ${{ inputs.target-platform != 'linux' }} + uses: ./src/electron/.github/actions/restore-cache-azcopy + with: + target-platform: ${{ inputs.target-platform }} + - name: Restore src cache via AKS + if: ${{ inputs.target-platform == 'linux' }} + uses: ./src/electron/.github/actions/restore-cache-aks + - name: Checkout Electron + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + path: src/electron + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + - name: Fix Sync + if: ${{ inputs.target-platform != 'linux' }} + uses: ./src/electron/.github/actions/fix-sync + with: + target-platform: ${{ inputs.target-platform }} + env: + ELECTRON_DEPOT_TOOLS_DISABLE_LOG: true + - name: Init Build Tools + run: > + e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} + --import ${{ inputs.gn-build-type }} --target-cpu ${{ + inputs.target-arch }} --remote-build siso + - name: Run Electron Only Hooks + run: | + e d gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" + - name: Regenerate DEPS Hash + run: > + (cd src/electron && git checkout .) && node + src/electron/script/generate-deps-hash.js + + echo "DEPSHASH=$(cat src/electron/.depshash)" >> $GITHUB_ENV + - name: Add CHROMIUM_BUILDTOOLS_PATH to env + run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV + - name: Free up space (macOS) + if: ${{ inputs.target-platform == 'macos' }} + uses: ./src/electron/.github/actions/free-space-macos + - name: Build Electron + if: ${{ inputs.target-platform != 'macos' || (inputs.target-variant == 'all' || + inputs.target-variant == 'darwin') }} + uses: ./src/electron/.github/actions/build-electron + with: + target-arch: ${{ inputs.target-arch }} + target-platform: ${{ inputs.target-platform }} + artifact-platform: ${{ inputs.target-platform == 'macos' && 'darwin' || + inputs.target-platform }} + is-release: ${{ inputs.is-release }} + generate-symbols: ${{ inputs.generate-symbols }} + upload-to-storage: ${{ inputs.upload-to-storage }} + is-asan: ${{ inputs.is-asan }} + upload-out-gen-artifacts: ${{ inputs.upload-out-gen-artifacts }} + - name: Set GN_EXTRA_ARGS for MAS Build + if: ${{ inputs.target-platform == 'macos' && (inputs.target-variant == 'all' || + inputs.target-variant == 'mas') }} + run: | + echo "MAS_BUILD=true" >> $GITHUB_ENV + GN_EXTRA_ARGS='is_mas_build=true' + echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV + - name: Build Electron (MAS) + if: ${{ inputs.target-platform == 'macos' && (inputs.target-variant == 'all' || + inputs.target-variant == 'mas') }} + uses: ./src/electron/.github/actions/build-electron + with: + target-arch: ${{ inputs.target-arch }} + target-platform: ${{ inputs.target-platform }} + artifact-platform: mas + is-release: ${{ inputs.is-release }} + generate-symbols: ${{ inputs.generate-symbols }} + upload-to-storage: ${{ inputs.upload-to-storage }} + step-suffix: (mas) diff --git a/.github/workflows/windows-publish.yml b/.github/workflows/windows-publish.yml index 991c535e15..7b53c04213 100644 --- a/.github/workflows/windows-publish.yml +++ b/.github/workflows/windows-publish.yml @@ -52,9 +52,11 @@ jobs: target-platform: win publish-x64-win: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-windows with: environment: production-release @@ -68,9 +70,11 @@ jobs: secrets: inherit publish-arm64-win: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-windows with: environment: production-release @@ -84,9 +88,11 @@ jobs: secrets: inherit publish-x86-win: - uses: ./.github/workflows/pipeline-segment-electron-build.yml + uses: ./.github/workflows/pipeline-segment-electron-publish.yml permissions: + attestations: write contents: read + id-token: write needs: checkout-windows with: environment: production-release diff --git a/package.json b/package.json index 49cd225135..4ca93a3bfe 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,8 @@ "url": "^0.11.4", "webpack": "^5.95.0", "webpack-cli": "^6.0.1", - "wrapper-webpack-plugin": "^2.2.0" + "wrapper-webpack-plugin": "^2.2.0", + "yaml": "^2.8.1" }, "private": true, "scripts": { @@ -132,6 +133,10 @@ "DEPS": [ "node script/gen-hunspell-filenames.js", "node script/gen-libc++-filenames.js" + ], + ".github/workflows/pipeline-segment-electron-build.yml": [ + "node script/copy-pipeline-segment-publish.js", + "git add .github/workflows/pipeline-segment-electron-publish.yml" ] }, "resolutions": { diff --git a/script/copy-pipeline-segment-publish.js b/script/copy-pipeline-segment-publish.js new file mode 100644 index 0000000000..f210f245d5 --- /dev/null +++ b/script/copy-pipeline-segment-publish.js @@ -0,0 +1,31 @@ +const yaml = require('yaml'); + +const fs = require('node:fs'); +const path = require('node:path'); + +const PREFIX = '# AUTOGENERATED FILE - DO NOT EDIT MANUALLY\n# ONLY EDIT .github/workflows/pipeline-segment-electron-build.yml\n\n'; + +const base = path.resolve(__dirname, '../.github/workflows/pipeline-segment-electron-build.yml'); +const target = path.resolve(__dirname, '../.github/workflows/pipeline-segment-electron-publish.yml'); + +const baseContents = fs.readFileSync(base, 'utf-8'); + +const parsedBase = yaml.parse(baseContents); +parsedBase.jobs.build.permissions = { + attestations: 'write', + contents: 'read', + 'id-token': 'write' +}; + +if (process.argv.includes('--check')) { + if (fs.readFileSync(target, 'utf-8') !== PREFIX + yaml.stringify(parsedBase)) { + console.error(`${target} is out of date`); + console.error('Please run "copy-pipeline-segment-publish.js" to update it'); + process.exit(1); + } +} else { + fs.writeFileSync( + target, + PREFIX + yaml.stringify(parsedBase) + ); +} diff --git a/script/release/uploaders/upload.py b/script/release/uploaders/upload.py index 36b5a3dd7f..640ddf9e46 100755 --- a/script/release/uploaders/upload.py +++ b/script/release/uploaders/upload.py @@ -369,6 +369,14 @@ def upload_io_to_github(release, filename, filepath, version): sys.stdout.buffer.write(c) sys.stdout.flush() + if "GITHUB_OUTPUT" in os.environ: + output_path = os.environ["GITHUB_OUTPUT"] + with open(output_path, "r+", encoding='utf-8') as github_output: + if len(github_output.readlines()) > 0: + github_output.write(",") + else: + github_output.write('UPLOADED_PATHS=') + github_output.write(filename) def upload_sha256_checksum(version, file_path, key_prefix=None): checksum_path = f'{file_path}.sha256sum' diff --git a/yarn.lock b/yarn.lock index 447278be9f..2fafb315ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -640,6 +640,7 @@ __metadata: webpack: "npm:^5.95.0" webpack-cli: "npm:^6.0.1" wrapper-webpack-plugin: "npm:^2.2.0" + yaml: "npm:^2.8.1" dependenciesMeta: abstract-socket: built: true @@ -15088,6 +15089,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.8.1": + version: 2.8.2 + resolution: "yaml@npm:2.8.2" + bin: + yaml: bin.mjs + checksum: 10c0/703e4dc1e34b324aa66876d63618dcacb9ed49f7e7fe9b70f1e703645be8d640f68ab84f12b86df8ac960bac37acf5513e115de7c970940617ce0343c8c9cd96 + languageName: node + linkType: hard + "yamux-js@npm:0.1.2": version: 0.1.2 resolution: "yamux-js@npm:0.1.2"