diff --git a/.github/workflows/_reusable_build_package.yml b/.github/workflows/_reusable_build_package.yml index 85cb395d..d3ad4eff 100644 --- a/.github/workflows/_reusable_build_package.yml +++ b/.github/workflows/_reusable_build_package.yml @@ -3,25 +3,15 @@ name: '_reusable_build_package' on: workflow_call: inputs: - otc_version: - required: true - type: string - otc_sumo_version: - required: true - type: string otc_build_number: - required: false + required: true type: string cmake_target: required: true type: string workflow_id: - required: false + required: true type: string - use_release_artifacts: - required: false - type: boolean - default: false runs_on: required: true type: string @@ -61,6 +51,17 @@ on: required: true packagecloud_token: required: true + aws_access_key_id: + required: true + aws_secret_access_key: + required: true + outputs: + otc_version: + description: "The version of the package" + value: ${{ jobs.build_package.outputs.otc_version }} + otc_build_number: + description: "The build number of the package" + value: ${{ jobs.build_package.outputs.otc_build_number }} defaults: run: @@ -72,19 +73,29 @@ jobs: name: Build (CMake) if: inputs.build_tool == 'cmake' outputs: + otc_version: ${{ steps.get-otc-version.outputs.otc_version }} + otc_build_number: ${{ steps.get-build-number.outputs.otc_build_number }} package_path: ${{ steps.package.outputs.path }} steps: - name: Checkout uses: actions/checkout@v4 - name: Workflow URL for sumologic-otel-collector - if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }} run: | org="SumoLogic" repo="sumologic-otel-collector" workflow_id="${{ inputs.workflow_id }}" echo "https://github.com/${org}/${repo}/actions/runs/${workflow_id}" + # Only output build number on one target so that it can be read by other + # jobs + - name: Output Build Number + if: inputs.cmake_target == 'otc_linux_amd64_deb' + id: get-build-number + run: | + build_number=${{ inputs.otc_build_number }} + echo "otc_build_number=${build_number}" >> $GITHUB_OUTPUT + - name: Determine if MacOS package should be signed if: runner.os == 'macOS' env: @@ -99,10 +110,6 @@ jobs: if: runner.os != 'Linux' run: mkdir build - - name: Use GitHub Artifacts for binaries - if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }} - run: echo "OTC_ARTIFACTS_SOURCE=github-artifacts" >> $GITHUB_ENV - # TODO: Go back to using Apple-Actions/import-codesign-certs once https://github.com/Apple-Actions/import-codesign-certs/pull/58 is merged - name: Import macOS Code-Signing Certificates if: ${{ runner.os == 'macOS' && env.MACOS_SIGNING_ENABLED == 'true' }} @@ -116,13 +123,37 @@ jobs: /usr/bin/security set-key-partition-list -S apple-tool:,apple: -k ${{ secrets.apple_developer_certificate_password }} signing_temp.keychain /usr/bin/security list-keychains -d user -s signing_temp.keychain login.keychain + - name: Fetch version artifact + if: runner.os == 'Linux' + uses: ./ci/github-actions/cmake + with: + args: -P version_artifact.cmake + gh_token: ${{ secrets.gh_artifacts_token }} + workflow_id: ${{ inputs.workflow_id }} + work_dir: . + + - name: Fetch version artifact + if: runner.os != 'Linux' + env: + GH_TOKEN: ${{ secrets.gh_artifacts_token }} + GH_WORKFLOW_ID: ${{ inputs.workflow_id }} + run: cmake -P version_artifact.cmake + + - name: Output OTC Version + id: get-otc-version + if: inputs.cmake_target == 'otc_linux_amd64_deb' + working-directory: build/version_detection + run: | + version=$(./otelcol-sumo --version | + sed -E -n 's/.* v([0-9]+\.[0-9]+\.[0-9]+)\-sumo.*/\1/p') && + echo otc_version="${version}" >> $GITHUB_OUTPUT + - name: Build Makefile id: cmake-linux if: runner.os == 'Linux' uses: ./ci/github-actions/cmake with: - otc_version: ${{ inputs.otc_version }} - otc_sumo_version: ${{ inputs.otc_sumo_version }} + gh_token: ${{ secrets.gh_artifacts_token }} otc_build_number: ${{ inputs.otc_build_number }} target: ${{ inputs.cmake_target }} workflow_id: ${{ inputs.workflow_id }} @@ -131,11 +162,11 @@ jobs: id: cmake-other if: runner.os != 'Linux' env: - OTC_VERSION: ${{ inputs.otc_version }} - OTC_SUMO_VERSION: ${{ inputs.otc_sumo_version }} + GH_TOKEN: ${{ secrets.gh_artifacts_token }} + GH_WORKFLOW_ID: ${{ inputs.workflow_id }} OTC_BUILD_NUMBER: ${{ inputs.otc_build_number }} - TARGET: ${{ inputs.cmake_target }} PRODUCTBUILD_IDENTITY_NAME: ${{ secrets.productbuild_identity_name }} + TARGET: ${{ inputs.cmake_target }} working-directory: build run: cmake ../ @@ -150,62 +181,17 @@ jobs: run: > echo path="$PACKAGE_NAME" >> $GITHUB_OUTPUT - - name: Set simple otc-bin outputs - id: bin - if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }} - env: - OTC_BIN: >- - ${{ - steps.cmake-linux.outputs.otc-bin || - steps.cmake-other.outputs.otc-bin - }} - OTC_CONFIG_BIN: >- - ${{ - steps.cmake-linux.outputs.otc-config-bin || - steps.cmake-other.outputs.otc-config-bin - }} - run: > - echo otelcol_sumo_path="$OTC_BIN" >> $GITHUB_OUTPUT && - echo otelcol_config_path="$OTC_CONFIG_BIN" >> $GITHUB_OUTPUT - - # Download the artifacts required to build the package target. If - # inputs.workflow_id is empty then this will be skipped and CMake will - # attempt to fetch the artifacts from a GitHub Release matching - # otc_version and otc_sumo_version. - - name: Download otelcol-sumo artifact from sumologic-otel-collector - uses: dawidd6/action-download-artifact@v3.1.4 - if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }} - with: - github_token: ${{ secrets.gh_artifacts_token }} - repo: SumoLogic/sumologic-otel-collector - run_id: ${{ inputs.workflow_id }} - workflow: dev_builds.yml - workflow_conclusion: success - name: ${{ steps.bin.outputs.otelcol_sumo_path }} - path: ./build/gh-artifacts - if_no_artifact_found: fail - - - name: Download otelcol-config artifact from sumologic-otel-collector - uses: dawidd6/action-download-artifact@v3.1.4 - if: inputs.workflow_id != '' - with: - github_token: ${{ secrets.gh_artifacts_token }} - repo: SumoLogic/sumologic-otel-collector - run_id: ${{ inputs.workflow_id }} - workflow: dev_builds.yml - workflow_conclusion: success - name: ${{ steps.bin.outputs.otelcol_config_path }} - path: ./build/gh-artifacts - if_no_artifact_found: fail - - name: Build package if: runner.os == 'Linux' uses: ./ci/github-actions/make with: + gh_token: ${{ secrets.gh_artifacts_token }} target: package - name: Build package if: runner.os != 'Linux' + env: + GH_TOKEN: ${{ secrets.gh_artifacts_token }} working-directory: build run: make package @@ -216,19 +202,30 @@ jobs: path: ./build/${{ steps.package.outputs.path }} if-no-files-found: error - - name: Publish package to Packagecloud + - name: Publish packages if: runner.os == 'Linux' uses: ./ci/github-actions/make with: target: publish-package - packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }} + packagecloud_token: ${{ secrets.PACKAGECLOUD_TOKEN }} + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + - name: Publish packages + if: runner.os != 'Linux' + working-directory: build + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }} + run: make publish-package - name: Wait for Packagecloud packages to be indexed if: runner.os == 'Linux' uses: ./ci/github-actions/make with: target: wait-for-packagecloud-indexing - packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }} + packagecloud_token: ${{ secrets.PACKAGECLOUD_TOKEN }} test_package: runs-on: ${{ inputs.runs_on }} @@ -253,14 +250,11 @@ jobs: runs-on: ${{ inputs.runs_on }} name: Build (WiX) ${{ inputs.fips && 'FIPS' || '' }} if: inputs.build_tool == 'wix' - env: - PRODUCT_VERSION: ${{ inputs.otc_version }}.${{ inputs.otc_build_number }} steps: - name: Checkout uses: actions/checkout@v4 - name: Workflow URL for sumologic-otel-collector - if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }} run: | org="SumoLogic" repo="sumologic-otel-collector" @@ -273,54 +267,40 @@ jobs: - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v2 - - name: Use GitHub Artifacts for binaries - if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }} - run: echo "OTC_ARTIFACTS_SOURCE=github-artifacts" >> $GITHUB_ENV + - name: Fetch version artifact + env: + GH_TOKEN: ${{ secrets.gh_artifacts_token }} + GH_WORKFLOW_ID: ${{ inputs.workflow_id }} + shell: cmd + run: cmake -P version_artifact.cmake + + - name: Determine version from binary + id: get-version + working-directory: ./build/version_detection + run: > + version=$(./otelcol-sumo.exe --version | + sed -E -n 's/.* v([0-9]+\.[0-9]+\.[0-9]+)\-sumo.*/\1/p') && + echo product_version="${version}.${{ inputs.otc_build_number }}" >> $GITHUB_OUTPUT && + echo version="${version}-${{ inputs.otc_build_number }}" >> $GITHUB_OUTPUT - name: Determine artifact names run: | echo "OTC_WORKFLOW_ARTIFACT_NAME=otelcol-sumo-${{ inputs.fips && 'fips-' || '' }}windows_${{ inputs.goarch }}.exe" >> $GITHUB_ENV - echo "OTC_RELEASE_ARTIFACT_NAME=otelcol-sumo-${{ inputs.otc_version }}-sumo-${{inputs.otc_sumo_version }}-${{ inputs.fips && 'fips-' || '' }}windows_${{ inputs.goarch }}.exe" >> $GITHUB_ENV echo "OTC_BUILD_INPUT_NAME=otelcol-sumo-windows_${{ inputs.goarch }}.exe" >> $GITHUB_ENV - # Download the artifacts required to build the package target. If - # inputs.workflow_id is empty then this will be skipped and an attempt - # will be made to fetch the artifacts from a GitHub Release matching - # otc_version and otc_sumo_version. - - name: Download artifact from workflow + # Download the artifacts required to build the package target. + - name: Download otelcol-sumo artifact from workflow uses: dawidd6/action-download-artifact@v3.1.4 - if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }} with: github_token: ${{ secrets.gh_artifacts_token }} repo: SumoLogic/sumologic-otel-collector run_id: ${{ inputs.workflow_id }} - workflow: dev_builds.yml workflow_conclusion: success name: ${{ env.OTC_WORKFLOW_ARTIFACT_NAME }} path: ./build/artifacts if_no_artifact_found: fail - # Download the artifacts, required to build the package target, from a - # GitHub Release. - - name: Download artifact from GitHub Release - uses: robinraju/release-downloader@v1.10 - if: ${{ inputs.use_release_artifacts && inputs.workflow_id == '' }} - with: - repository: SumoLogic/sumologic-otel-collector - tag: v${{ inputs.otc_version }}-sumo-${{ inputs.otc_sumo_version }} - fileName: ${{ env.OTC_RELEASE_ARTIFACT_NAME }} - out-file-path: build/artifacts - - - name: Rename GitHub Release artifact - if: ${{ inputs.use_release_artifacts && inputs.workflow_id == '' }} - working-directory: ./build/artifacts - env: - MV_FROM: ${{ env.OTC_RELEASE_ARTIFACT_NAME }} - MV_TO: ${{ env.OTC_BUILD_INPUT_NAME }} - run: mv -n "$MV_FROM" "$MV_TO" - - name: Rename GitHub Workflow artifact - if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }} working-directory: ./build/artifacts env: MV_FROM: ${{ env.OTC_WORKFLOW_ARTIFACT_NAME }} @@ -332,6 +312,7 @@ jobs: working-directory: ./msi/wix env: PLATFORM: ${{ inputs.package_arch }} + PRODUCT_VERSION: ${{ steps.get-version.outputs.product_version }} run: | msbuild.exe -p:Configuration=Release \ -p:Platform=$PLATFORM \ @@ -358,6 +339,19 @@ jobs: path: ${{ steps.build.outputs.package_path }} if-no-files-found: error + - name: Publish packages + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REGION: us-west-2 + VERSION: ${{ steps.get-version.outputs.version }} + PKG_PATH: ${{ steps.build.outputs.package_path }} + PKG_NAME: ${{ steps.build.outputs.package_filename }} + S3_BUCKET: sumologic-osc-ci-builds + run: | + aws.exe s3 cp $PKG_PATH \ + s3://${S3_BUCKET}/${VERSION}/${PKG_NAME} + test_wixext: name: Test (SumoLogic.wixext) if: inputs.build_tool == 'wix' diff --git a/.github/workflows/build_packages.yml b/.github/workflows/build_packages.yml index 92bfbf43..d43ff617 100644 --- a/.github/workflows/build_packages.yml +++ b/.github/workflows/build_packages.yml @@ -4,37 +4,13 @@ # upgrades from one build to the next. name: 'Build packages' -# Sets the name of the CI run based on whether the run was triggered by a push -# or remotely with or without workflow_run_id or use_release_artifacts set. The -# name used for push events is the full commit message as I have not been able -# to find a way to only show the commit title (first 72 characters of commit -# message) - Justin K. +# Sets the name of the CI run based on whether the run was triggered with or +# without a workflow_id set. run-name: > ${{ - (inputs.use_release_artifacts && - inputs.otc_version != '' && - inputs.otc_sumo_version != '') && - format('Build for GitHub Release: {0}-sumo-{1}, Version: {0}-sumo-{1}', inputs.otc_version, inputs.otc_sumo_version) + inputs.workflow_id == '' && format('Build for Remote Workflow: latest-main') || - (inputs.use_release_artifacts && - (inputs.otc_version == '' || - inputs.otc_sumo_version == '')) && - 'Build for GitHub Release: latest' - || - (inputs.workflow_id != '' && - inputs.otc_version != '' && - inputs.otc_sumo_version != '') && - format('Build for Remote Workflow: {0}, Version: {1}-sumo-{2}', inputs.workflow_id, inputs.otc_version, inputs.otc_sumo_version) - || - (inputs.workflow_id == '' && - inputs.otc_version != '' && - inputs.otc_sumo_version != '') && - format('Build for Remote Workflow: latest-main, Version: {0}-sumo-{1}', inputs.otc_version, inputs.otc_sumo_version) - || - inputs.workflow_id != '' && - format('Build for Remote Workflow: {0}, Version: unknown', inputs.workflow_id) - || - github.event.head_commit.message + inputs.workflow_id != '' && format('Build for Remote Workflow: {0}', inputs.workflow_id) }} on: @@ -52,29 +28,6 @@ on: are being built for. required: false type: string - otc_version: - description: | - Version of otelcol-sumo to package in A.B.C format. - required: false - type: string - otc_sumo_version: - description: | - Sumo version of otelcol-sumo to package. E.g. the X in A.B.C-sumo-X. - required: false - type: string - release: - description: Publish draft release - type: boolean - required: false - default: false - use_release_artifacts: - description: | - Fetch artifacts from a GitHub Release instead of the artifacts from a - GitHub CI run. Both otc_version and otc_sumo_version are required if - this is set to true. - type: boolean - required: false - default: false jobs: determine_workflow: @@ -107,65 +60,6 @@ jobs: - name: Output Remote Workflow URL run: echo ::notice title=Remote Workflow URL::https://github.com/SumoLogic/sumologic-otel-collector/actions/runs/${{ steps.workflow.outputs.id }} - # Determines the latest version which will be used to fetch artifacts from a - # GitHub Release and as the version of the packages being built. This is - # skipped if the otc_version and otc_sumo_version inputs have been set. - determine_version: - runs-on: ubuntu-latest - name: Determine version - outputs: - otc_version: ${{ steps.versions.outputs.otc_version }} - otc_sumo_version: ${{ steps.versions.outputs.otc_sumo_version }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - # Determine the latest release version if either otc_version or - # otc_sumo_version are empty. - - name: Determine latest release version - id: release - if: > - inputs.otc_version == '' && - inputs.otc_sumo_version == '' - env: - GH_TOKEN: ${{ github.token }} - run: | - TAG_NAME=$(gh release view -R SumoLogic/sumologic-otel-collector --jq ".tagName" --json "tagName") - echo "tag_name=$TAG_NAME" >> "$GITHUB_OUTPUT" - - - name: Determine version core from release - id: version-core - if: > - inputs.otc_version == '' && - inputs.otc_sumo_version == '' - env: - VERSION_TAG: ${{ steps.release.outputs.tag_name }} - run: > - ./ci/get_version.sh otc_version > /tmp/otc_version && - cat /tmp/otc_version && - echo "version=$(cat /tmp/otc_version)" >> $GITHUB_OUTPUT - - - name: Determine sumo version from release - id: sumo-version - if: > - inputs.otc_version == '' && - inputs.otc_sumo_version == '' - env: - VERSION_TAG: ${{ steps.release.outputs.tag_name }} - run: > - ./ci/get_version.sh otc_sumo_version > /tmp/otc_sumo_version && - cat /tmp/otc_sumo_version && - echo "version=$(cat /tmp/otc_sumo_version)" >> $GITHUB_OUTPUT - - - name: Set output versions - id: versions - run: | - echo "otc_version=${{ inputs.otc_version || steps.version-core.outputs.version }}" >> $GITHUB_OUTPUT - echo "otc_sumo_version=${{ inputs.otc_sumo_version || steps.sumo-version.outputs.version }}" >> $GITHUB_OUTPUT - - - name: Output App Version - run: echo ::notice title=App Version::${{ steps.versions.outputs.otc_version }}-sumo-${{ steps.versions.outputs.otc_sumo_version }} - # Builds a package for each target in the matrix. The target must be an # existing file name (without extension) in the targets directory when # build_tool is cmake. @@ -174,14 +68,10 @@ jobs: uses: ./.github/workflows/_reusable_build_package.yml needs: - determine_workflow - - determine_version with: - otc_version: ${{ needs.determine_version.outputs.otc_version }} - otc_sumo_version: ${{ needs.determine_version.outputs.otc_sumo_version }} otc_build_number: ${{ github.run_number }} cmake_target: ${{ matrix.target }} workflow_id: ${{ needs.determine_workflow.outputs.workflow_id }} - use_release_artifacts: ${{ inputs.use_release_artifacts || false }} runs_on: ${{ matrix.runs_on }} goarch: ${{ matrix.goarch }} package_arch: ${{ matrix.package_arch }} @@ -199,7 +89,8 @@ jobs: microsoft_description: ${{ secrets.MICROSOFT_DESCRIPTION }} gh_ci_token: ${{ secrets.GH_CI_TOKEN }} packagecloud_token: ${{ secrets.PACKAGECLOUD_TOKEN }} - + aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} strategy: matrix: include: @@ -249,6 +140,15 @@ jobs: install-script: name: Store install script runs-on: ubuntu-latest + needs: + - build_packages + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: us-east-1 + AWS_S3_BUCKET: sumologic-osc-ci-builds + OTC_VERSION: ${{ needs.build_packages.outputs.otc_version }} + OTC_BUILD_NUMBER: ${{ needs.build_packages.outputs.otc_build_number }} steps: - uses: actions/checkout@v4 @@ -266,78 +166,28 @@ jobs: path: ./install-script/install.ps1 if-no-files-found: error - publish_release: - name: Publish Release - runs-on: ubuntu-latest - needs: - - build_packages - - determine_version - permissions: - contents: write - if: inputs.release - env: - OTC_APP_VERSION: v${{ needs.determine_version.outputs.otc_version }}-sumo-${{ needs.determine_version.outputs.otc_sumo_version }} - RELEASE_TAG_NAME: v${{ needs.determine_version.outputs.otc_version }}-${{ github.run_number }} - steps: - - name: Download all packages stored as artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts/ - - # Create the release tag separately to add a message to it - # NOTE: As per the github API, we need to create the tag object first, and then the git reference - - name: Create release tag - uses: actions/github-script@v7 - with: - script: | - const tagRequest = await github.rest.git.createTag({ - owner: context.repo.owner, - repo: context.repo.repo, - tag: '${{ env.RELEASE_TAG_NAME }}', - message: `App Version: ${{ env.OTC_APP_VERSION }}`, - object: context.sha, - type: 'commit', - tagger: { - name: "${{ github.actor }}", - email: "${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com", - }, - }) - github.rest.git.createRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: 'refs/tags/${{ env.RELEASE_TAG_NAME }}', - sha: tagRequest.data.sha - }) - - - uses: ncipollo/release-action@v1 - with: - name: v${{ needs.determine_version.outputs.otc_version }}-${{ github.run_number }} - commit: ${{ github.sha }} - tag: ${{ env.RELEASE_TAG_NAME }} - - draft: true - generateReleaseNotes: true - prerelease: false - - allowUpdates: true - omitBodyDuringUpdate: true - omitNameDuringUpdate: true - - artifacts: "artifacts/*/*" - artifactErrorsFailBuild: true - replacesArtifacts: true - - body: | - This release packages [${{ env.OTC_APP_VERSION }}](https://github.com/SumoLogic/sumologic-otel-collector/releases/tag/${{ env.OTC_APP_VERSION }}). + - name: Store install scripts on S3 + run: | + version=${OTC_VERSION}-${OTC_BUILD_NUMBER} + s3_path="${version}/" + aws s3 cp install-script/install.ps1 s3://${AWS_S3_BUCKET}/${s3_path} + aws s3 cp install-script/install.sh s3://${AWS_S3_BUCKET}/${s3_path} - The changelog below is for the package itself, rather than the Sumo Logic Distribution for OpenTelemetry Collector. + - name: Create latest_version file + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: | + version=${OTC_VERSION}-${OTC_BUILD_NUMBER} + echo "${version}" >> latest_version + aws s3 cp --content-type "text/plain" latest_version \ + s3://${AWS_S3_BUCKET}/ test-install-script: name: Test Install Script runs-on: ${{ matrix.runs_on }} timeout-minutes: 60 needs: - - determine_version - build_packages strategy: fail-fast: false @@ -352,7 +202,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_CI_TOKEN: ${{ secrets.GITHUB_TOKEN }} - OTC_VERSION: ${{ needs.determine_version.outputs.otc_version }} + OTC_VERSION: ${{ needs.build_packages.outputs.otc_version }} OTC_BUILD_NUMBER: ${{ github.run_number }} PACKAGECLOUD_MASTER_TOKEN: ${{ secrets.PACKAGECLOUD_MASTER_TOKEN }} PACKAGECLOUD_REPO: ci-builds @@ -386,12 +236,17 @@ jobs: ls -l artifacts/ ls -l artifacts/**/* - - name: Set DARWIN_PKG_URL + - name: Set DARWIN_PKG_URL (macOS) if: ${{ steps.changed-files.outputs.any_changed == 'true' && runner.os == 'macOS' }} run: | fp="$(readlink -f artifacts/otelcol-sumo_*-intel.pkg/otelcol-sumo_*-intel.pkg)" echo DARWIN_PKG_URL="file://${fp}" >> $GITHUB_ENV + - name: Set S3_BUCKET (macOS) + if: ${{ steps.changed-files.outputs.any_changed == 'true' && runner.os == 'macOS' }} + run: | + echo S3_BUCKET="sumologic-osc-ci-builds" >> $GITHUB_ENV + - name: Run install script tests (*nix) if: steps.changed-files.outputs.any_changed == 'true' && runner.os != 'Windows' working-directory: install-script/test @@ -401,4 +256,8 @@ jobs: shell: powershell if: steps.changed-files.outputs.any_changed == 'true' && runner.os == 'Windows' working-directory: install-script/test + env: + S3_BUCKET: sumologic-osc-ci-builds + OVERRIDE_ARCH: x64 + SKIP_ARCH_DETECTION: 1 run: make test diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml new file mode 100644 index 00000000..326e05f7 --- /dev/null +++ b/.github/workflows/releases.yml @@ -0,0 +1,168 @@ +name: 'Publish release' + +run-name: > + ${{ format('Publish Release for Workflow: {0}', inputs.workflow_id) }} + +on: + workflow_dispatch: + inputs: + workflow_id: + description: | + Workflow Run ID from this repository to fetch artifacts from for this + release. + required: true + type: string + +defaults: + run: + shell: bash + +jobs: + get-version: + name: Get application version for this revision + runs-on: ubuntu-latest + outputs: + git-sha: ${{ steps.get-version.outputs.git-sha }} + otc-version: ${{ steps.get-version.outputs.otc-version }} + sumo-version: ${{ steps.get-version.outputs.sumo-version }} + binary-version: ${{ steps.get-version.outputs.binary-version }} + version: ${{ steps.get-version.outputs.version }} + steps: + - uses: actions/checkout@v4 + + - name: Outuput Workflow ID + run: echo ::notice title=Workflow ID::${{ inputs.workflow_id }} + + - name: Output Workflow URL + run: | + repo_url="https://github.com/SumoLogic/sumologic-otel-collector-packaging" + url="${repo_url}/actions/runs/${{ inputs.workflow_id }}" + echo ::notice title=Workflow URL::${url} + + - name: Determine Workflow Run ID from workflow + id: get-run-number + run: | + workflow="11673248730" + run_number=$(gh run view "${workflow}" --json number -t '{{.number}}') + echo "run-number=$run_number" >> $GITHUB_OUTPUT + + - name: Output Workflow Run Number + run: | + run_number=${{ steps.get-run-number.outputs.run-number }} + echo ::notice title=Workflow Run Number::${run_number} + + - name: Download otelcol-sumo artifact from workflow + uses: actions/download-artifact@v4 + with: + name: otelcol-sumo-linux_amd64 + path: artifacts/ + merge-multiple: true + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ inputs.workflow_id }} + + - name: Determine version from artifact + id: get-version + run: | + artifact="artifacts/otelcol-sumo-linux_amd64" + chmod +x "${artifact}" + script="ci/get_version_from_binary.sh" + core="$("$script" core "${artifact}")" + sumo="$("$script" sumo "${artifact}")" + run_number=${{ steps.get-run-number.outputs.run-number }} + echo "otc-version=$core" >> $GITHUB_OUTPUT + echo "sumo-version=$sumo" >> $GITHUB_OUTPUT + echo "binary-version=${core}-sumo-${sumo}" >> $GITHUB_OUTPUT + echo "version=${core}-${run_number}" >> $GITHUB_OUTPUT + + - name: Output Binary Version + run: | + binary_version=${{ steps.get-version.outputs.binary-version }} + echo ::notice title=Binary Version::${binary_version} + + - name: Output Package Version + run: | + package_version=${{ steps.get-version.outputs.version }} + echo ::notice title=Package Version::${package_version} + + - name: Determine Git SHA of workflow + id: get-sha + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + workflow=${{ inputs.workflow_id }} + sha="$(gh run view ${workflow} --json headSha -t '{{.headSha}}')" + echo "git-sha=$sha" >> $GITHUB_OUTPUT + + - name: Output Git SHA + run: | + echo ::notice title=Git SHA::${{ steps.get-sha.outputs.git-sha }} + + # Store the install script from the packaging repository as a release + # artifact. + install-script: + name: Store install script + runs-on: ubuntu-latest + needs: + - get-version + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.get-version.outputs.git-sha }} + + - name: Store Linux install script as action artifact + uses: actions/upload-artifact@v4 + with: + name: install.sh + path: ./install-script/install.sh + if-no-files-found: error + + - name: Store Windows install script as action artifact + uses: actions/upload-artifact@v4 + with: + name: install.ps1 + path: ./install-script/install.ps1 + if-no-files-found: error + + create-release: + name: Create Github release + runs-on: ubuntu-20.04 + needs: + - get-version + permissions: + contents: write + steps: + - name: Download all artifacts from workflow + uses: actions/download-artifact@v4 + with: + path: artifacts/ + merge-multiple: true + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ inputs.workflow_id }} + + - uses: ncipollo/release-action@v1 + with: + name: v${{ needs.get-version.outputs.version }} + commit: ${{ needs.get-version.outputs.git-sha }} + tag: v${{ needs.get-version.outputs.version }} + + draft: true + generateReleaseNotes: true + prerelease: false + + allowUpdates: true + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + + artifacts: "artifacts/*/*" + artifactErrorsFailBuild: true + replacesArtifacts: true + + body: | + This release packages + [${{ needs.get-version.outputs.version }}](https://github.com/SumoLogic/sumologic-otel-collector/releases/tag/v${{ needs.get-version.outputs.binary-version }}). + + The changelog below is for the package itself, rather than the Sumo + Logic Distribution for OpenTelemetry Collector. The changelog for + the Sumo Logic Distribution for OpenTelemetry Collector can be found + on the collector's + [release page](https://github.com/SumoLogic/sumologic-otel-collector/releases/tag/v${{ needs.get-version.outputs.binary-version }}). diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dbefff8..e03002fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,26 @@ # Require CMake >= 3.24.1 cmake_minimum_required(VERSION 3.24.1 FATAL_ERROR) +# Required environment variables +if(NOT DEFINED ENV{GH_TOKEN}) + message(FATAL_ERROR "GH_TOKEN environment variable must be set") +endif() + +if(NOT DEFINED ENV{GH_WORKFLOW_ID}) + message(FATAL_ERROR "GH_WORKFLOW_ID environment variable must be set") +endif() + +set(GH_TOKEN "$ENV{GH_TOKEN}") +set(GH_WORKFLOW_ID "$ENV{GH_WORKFLOW_ID}") + # Required and optional programs. Attempts to find required and optional # programs used to build the packages. find_program(PACKAGECLOUD_PROGRAM packagecloud) +find_program(GH_PROGRAM gh REQUIRED) + +# Include utils +set(UTILS_DIR "${CMAKE_SOURCE_DIR}/utils") +include("${CMAKE_SOURCE_DIR}/utils.cmake") # Set version information include("${CMAKE_SOURCE_DIR}/version.cmake") @@ -16,17 +33,13 @@ include(CPackComponent) set(ASSETS_DIR "${CMAKE_SOURCE_DIR}/assets") set(COMPONENTS_DIR "${CMAKE_SOURCE_DIR}/components") set(DISTRIBUTIONS_DIR "${CMAKE_SOURCE_DIR}/distributions") -set(EXTERNAL_PROJECTS_DIR "${CMAKE_SOURCE_DIR}/external_projects") set(SETTINGS_DIR "${CMAKE_SOURCE_DIR}/settings") set(TARGETS_DIR "${CMAKE_SOURCE_DIR}/targets") set(TEMPLATES_DIR "${CMAKE_SOURCE_DIR}/templates") set(TEMPLATES_OUTPUT_DIR "${CMAKE_BINARY_DIR}/templates_output") -set(UTILS_DIR "${CMAKE_SOURCE_DIR}/utils") # Include CMake files -include("${CMAKE_SOURCE_DIR}/utils.cmake") include("${CMAKE_SOURCE_DIR}/components.cmake") -include("${CMAKE_SOURCE_DIR}/external_projects.cmake") include("${CMAKE_SOURCE_DIR}/templates.cmake") include("${CMAKE_SOURCE_DIR}/packages.cmake") include("${CMAKE_SOURCE_DIR}/distributions.cmake") diff --git a/Dockerfile b/Dockerfile index cc7607cc..baa2e385 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,8 @@ RUN apk add --no-cache \ curl \ bash \ tar \ - gzip + gzip \ + aws-cli COPY docker/install-deps.sh /install-deps.sh diff --git a/Makefile b/Makefile index 5dce5e65..5d572ecc 100644 --- a/Makefile +++ b/Makefile @@ -2,30 +2,55 @@ mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) mkfile_dir ?= $(patsubst %/,%,$(dir $(mkfile_path))) build_dir ?= $(mkfile_dir)/build -OTC_ARTIFACTS_SOURCE ?= github-artifacts - -ifeq ($(strip $(PACKAGECLOUD_TOKEN)),) -$(error "PACKAGECLOUD_TOKEN must be set") -endif +require-%: + @: $(if ${${*}},,$(error Required environment variable was not found: $*)) + @echo 'Required environment variable was found: $*' .PHONY: docker-image docker-image: docker buildx bake --load -.PHONY: build -build: docker-image -build: +.PHONY: version-artifact +version-artifact: require-GH_TOKEN +version-artifact: require-GH_WORKFLOW_ID +version-artifact: docker-image +version-artifact: + docker run \ + -e GH_TOKEN="$(GH_TOKEN)" \ + -e GH_WORKFLOW_ID="$(GH_WORKFLOW_ID)" \ + -e WORK_DIR="/src" \ + -v "$(mkfile_dir):/src" \ + -v "$(build_dir):/build" \ + otelcol-sumo/cmake \ + cmake -P version_artifact.cmake + +.PHONY: generate +generate: require-TARGET +generate: require-OTC_BUILD_NUMBER +generate: require-GH_TOKEN +generate: require-GH_WORKFLOW_ID +generate: version-artifact +generate: docker run \ -e TARGET="$(TARGET)" \ - -e OTC_VERSION="$(OTC_VERSION)" \ - -e OTC_SUMO_VERSION="$(OTC_SUMO_VERSION)" \ -e OTC_BUILD_NUMBER="$(OTC_BUILD_NUMBER)" \ - -e OTC_ARTIFACTS_SOURCE="$(OTC_ARTIFACTS_SOURCE)" \ + -e GH_TOKEN="$(GH_TOKEN)" \ + -e GH_WORKFLOW_ID="$(GH_WORKFLOW_ID)" \ -v "$(mkfile_dir):/src" \ -v "$(build_dir):/build" \ otelcol-sumo/cmake \ cmake /src +.PHONY: build +build: generate +build: + docker run \ + -e GH_TOKEN="$(GH_TOKEN)" \ + -v "$(mkfile_dir):/src" \ + -v "$(build_dir):/build" \ + otelcol-sumo/cmake \ + make + .PHONY: package package: build package: @@ -36,12 +61,16 @@ package: make package .PHONY: publish-package +publish-package: require-PACKAGECLOUD_TOKEN publish-package: package publish-package: docker run \ + -e PACKAGECLOUD_TOKEN="$(PACKAGECLOUD_TOKEN)" \ -v "$(mkfile_dir):/src" \ -v "$(build_dir):/build" \ -e PACKAGECLOUD_TOKEN="$(PACKAGECLOUD_TOKEN)" \ + -e AWS_ACCESS_KEY_ID="$(AWS_ACCESS_KEY_ID)" \ + -e AWS_SECRET_ACCESS_KEY="$(AWS_SECRET_ACCESS_KEY)" \ otelcol-sumo/cmake \ make publish-package diff --git a/README.md b/README.md index b4bc4fce..701107f6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + # sumologic-otel-collector-packaging ## Building diff --git a/assets/.keep b/assets/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/ci/github-actions/cmake/action.yml b/ci/github-actions/cmake/action.yml index 56e71f5d..1b8d628d 100644 --- a/ci/github-actions/cmake/action.yml +++ b/ci/github-actions/cmake/action.yml @@ -1,27 +1,35 @@ name: 'Run CMake' inputs: - otc_version: - required: true - type: string - otc_sumo_version: - required: true + args: + required: false type: string + default: '../' otc_build_number: required: false type: string target: required: true type: string + work_dir: + required: false + type: string workflow_id: required: false type: string + gh_token: + required: false + type: string runs: using: 'docker' image: '../../../Dockerfile' env: + GH_TOKEN: ${{ inputs.gh_token }} + GH_WORKFLOW_ID: ${{ inputs.workflow_id }} + OTC_BUILD_NUMBER: ${{ inputs.otc_build_number }} TARGET: ${{ inputs.target }} + WORK_DIR: ${{ inputs.work_dir }} args: - cmake - - ../ + - ${{ inputs.args }} diff --git a/ci/github-actions/make/action.yml b/ci/github-actions/make/action.yml index 85391fd1..0b58427c 100644 --- a/ci/github-actions/make/action.yml +++ b/ci/github-actions/make/action.yml @@ -4,7 +4,16 @@ inputs: target: required: true type: string - packagecloud-token: + gh_token: + required: false + type: string + packagecloud_token: + required: false + type: string + aws-access-key-id: + required: false + type: string + aws-secret-access-key: required: false type: string @@ -12,7 +21,10 @@ runs: using: 'docker' image: '../../../Dockerfile' env: - PACKAGECLOUD_TOKEN: ${{ inputs.packagecloud-token }} + AWS_ACCESS_KEY_ID: ${{ inputs.aws-access-key-id }} + AWS_SECRET_ACCESS_KEY: ${{ inputs.aws-secret-access-key }} + GH_TOKEN: ${{ inputs.gh_token }} + PACKAGECLOUD_TOKEN: ${{ inputs.packagecloud_token }} args: - make - ${{ inputs.target }} diff --git a/components/otelcol-sumo.cmake b/components/otelcol-sumo.cmake index 60d441e8..466605ca 100644 --- a/components/otelcol-sumo.cmake +++ b/components/otelcol-sumo.cmake @@ -203,18 +203,18 @@ endmacro() macro(install_otc_binary) require_variables( "OTC_BIN_DIR" - "OTC_BINARY" - "SOURCE_OTC_BINARY_PATH" + "OTC_BIN" + "REMOTE_OTC_BIN_PATH" ) install( - FILES "${SOURCE_OTC_BINARY_PATH}" + FILES "${REMOTE_OTC_BIN_PATH}" DESTINATION "${OTC_BIN_DIR}" PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE - RENAME "${OTC_BINARY}" + RENAME "${OTC_BIN}" COMPONENT otelcol-sumo ) endmacro() @@ -223,18 +223,18 @@ endmacro() macro(install_otc_config_binary) require_variables( "OTC_BIN_DIR" - "OTC_CONFIG_BINARY" - "SOURCE_OTC_CONFIG_BINARY_PATH" + "OTC_CONFIG_BIN" + "REMOTE_OTC_CONFIG_BIN_PATH" ) install( - FILES "${SOURCE_OTC_CONFIG_BINARY_PATH}" + FILES "${REMOTE_OTC_CONFIG_BIN_PATH}" DESTINATION "${OTC_BIN_DIR}" PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE - RENAME "${OTC_CONFIG_BINARY}" + RENAME "${OTC_CONFIG_BIN}" COMPONENT otelcol-sumo ) endmacro() diff --git a/distributions.cmake b/distributions.cmake index 98758fa5..a517f18c 100644 --- a/distributions.cmake +++ b/distributions.cmake @@ -1,3 +1,6 @@ +# Checks if the Packagecloud distro supports the package architecture and if it +# does it will be added to the list of Packagecloud distributions to upload the +# package to. macro(check_architecture_support) if(NOT ${package_arch} IN_LIST _supported_architectures) message(FATAL_ERROR "${_distro_name} does not support architecture: ${package_arch}") diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 838b1dea..47cb0877 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -1,27 +1,18 @@ #!/bin/sh -l set -e -if [ "${INPUT_OTC_VERSION}" != "" ]; then - OTC_VERSION="$(echo "$INPUT_OTC_VERSION" | xargs)" - export OTC_VERSION -fi - -if [ "${INPUT_OTC_SUMO_VERSION}" != "" ]; then - OTC_SUMO_VERSION="$(echo "$INPUT_OTC_SUMO_VERSION" | xargs)" - export OTC_SUMO_VERSION -fi - if [ "${INPUT_OTC_BUILD_NUMBER}" != "" ]; then OTC_BUILD_NUMBER="$(echo "$INPUT_OTC_BUILD_NUMBER" | xargs)" export OTC_BUILD_NUMBER fi -if [ "${INPUT_WORKFLOW_ID}" != "" ]; then - export OTC_ARTIFACTS_SOURCE="github-artifacts" -fi - mkdir -p build -cd build || exit + +if [ -n "${WORK_DIR}" ]; then + cd "${WORK_DIR}" || exit +else + cd build || exit +fi # shellcheck disable=SC2068 $@ diff --git a/docker/install-deps.sh b/docker/install-deps.sh index 007958cf..858580cf 100755 --- a/docker/install-deps.sh +++ b/docker/install-deps.sh @@ -4,6 +4,7 @@ set -euxo pipefail targetarch="$1" +GITHUB_CLI_VERSION="2.60.1" PACKAGECLOUD_GO_VERSION="0.2.2" # Convert between Docker CPU architecture names and other names such as Go's @@ -16,6 +17,25 @@ else GOARCH="amd64" fi +function install_github_cli() { + base_url="https://github.com/cli/cli/releases/download" + version="${GITHUB_CLI_VERSION}" + file="gh_${version}_linux_${GOARCH}.tar.gz" + url="${base_url}/v${version}/${file}" + + # Download GitHub CLI + curl -Lo /tmp/github-cli.tar.gz "${url}" + + # Verify that the file is gzip compressed data to prevent cases where + # outages, site changes, etc. result in the downloaded file being HTML text. + file /tmp/github-cli.tar.gz | grep "gzip compressed data" + + # Install GitHub CLI + mkdir /tmp/github-cli + tar -C /tmp/github-cli -zxf /tmp/github-cli.tar.gz --strip-components=1 + mv /tmp/github-cli/bin/gh /usr/local/bin/gh +} + function install_packagecloud_go() { base_url="https://github.com/amdprophet/packagecloud-go/releases/download" version="${PACKAGECLOUD_GO_VERSION}" @@ -34,4 +54,5 @@ function install_packagecloud_go() { mv /tmp/packagecloud /usr/local/bin/packagecloud } +install_github_cli install_packagecloud_go diff --git a/docs/release.md b/docs/release.md index e69de29b..9ae1dc91 100644 --- a/docs/release.md +++ b/docs/release.md @@ -0,0 +1,122 @@ +# Releasing + +## How to release + +### Check end-to-end tests + +Check if the Sumo internal e2e tests are passing. + +### Determine the Workflow Run ID to release + +We can begin the process of creating a release once QE has given a thumbs up for +a given package version and the [collector release steps][collector_release] +have already been performed. We can determine the Workflow Run ID to use for a +release using the following steps: + +#### Find the package build number + +Each package has a build number and it's included in the package version & +filename. For example, if the package version that QE validates is 0.108.0-1790 +then the build number is 1790. + +#### Find the collector workflow run + +We can find the workflow used to build the packages by using the package build +number. + +The build number corresponds directly to the GitHub Run Number for a packaging +workflow run in GitHub Actions. Unfortunately, there does not currently appear to +be a way to reference a workflow run using the run number. Instead, we can use +one of two methods to find the workflow run: + +#### Option 1 - Use the `gh` cli tool to find the workflow + +```shell +PAGER=""; BUILD_NUMBER="1790"; \ +gh run list -R sumologic/sumologic-otel-collector-packaging -s success \ +-w build_packages.yml -L 200 -b main --json displayTitle,databaseId,number,url \ +-q ".[] | select(.number == ${BUILD_NUMBER})" +``` + +This will output a number of fields, for example: + +```json +{ + "databaseId": 11673248730, + "displayTitle": "Build for Remote Workflow: 11672946742, Version: 0.108.0-sumo-1\n", + "number": 1790, + "url": "https://github.com/SumoLogic/sumologic-otel-collector-packaging/actions/runs/11673248730" +} +``` + +The number in the `databaseId` field is the ID for the workflow run that built +the packages. + +The workflow run can be viewed by visiting the URL in the `url` field. + +#### Option 2 - Search the GitHub website manually + +Manually search for the run number on the +[Build packages workflow][build_workflow] page. Search for the build number +(e.g. 1790) until you find the corresponding workflow. + +![Finding the packaging workflow run][release_0] + +Once you've found the packaging workflow run, click it to navigate to the +details of the workflow run. The Workflow Run ID can be found in the last part +of the URL in the address bar: + +![Finding the packaging workflow ID][release_1] + +### Trigger the release + +Now that we have the Workflow Run ID we can trigger a release. There are two +methods of doing this. + +#### Option 1 - Use the `gh` cli tool to trigger the release + +A release can be triggered by using the following command (be sure to replace +`WORKFLOW_ID` with the Workflow Run ID from the previous step): + +```shell +PAGER=""; WORKFLOW_ID="11673248730"; \ +gh workflow run build_packages.yml \ +-R sumologic/sumologic-otel-collector-packaging -f workflow_id=${WORKFLOW_ID} +``` + +The status of running workflows can be viewed with the `gh run watch` command. +You will have to manually select the correct workflow run. The name of the run +should have a title similiar to `Publish Release for Workflow: x`). Once you +have selected the correct run the screen will periodically update to show the +status of the run's jobs. + +#### Option 2 - Use the GitHub website to trigger the release + +Navigate to the [Publish release][releases_workflow] workflow in GitHub Actions. +Find and click the `Run workflow` button on the right-hand side of the page. +Fill in the Workflow Run ID from the previous step. If the release should be +considered to be the latest version, click the checkbox for `Latest version`. +Click the `Run workflow` button to trigger the release. + +![Triggering a release][release_2] + +### Publish GitHub release + +The GitHub release is created as draft by the +[releases](../.github/workflows/releases.yml) GitHub Action. + +After the release draft is created, go to [GitHub releases](https://github.com/SumoLogic/sumologic-otel-collector-packaging/releases), +edit the release draft and fill in missing information: + +- Specify versions for upstream OT core and contrib releases +- Copy and paste the Changelog entry for this release from [CHANGELOG.md][changelog] + +After verifying that the release text and all links are good, publish the release. + +[build_workflow]: https://github.com/SumoLogic/sumologic-otel-collector-packaging/actions/workflows/build_packages.yml?query=branch%3Amain +[changelog]: https://github.com/SumoLogic/sumologic-otel-collector/blob/main/CHANGELOG.md +[collector_release]: https://github.com/SumoLogic/sumologic-otel-collector/blob/main/docs/release.md +[release_0]: ../images/release_0.png +[release_1]: ../images/release_1.png +[release_1]: ../images/release_2.png +[releases_workflow]: https://github.com/SumoLogic/sumologic-otel-collector-packaging/actions/workflows/releases.yml diff --git a/external_projects.cmake b/external_projects.cmake deleted file mode 100644 index 7c4604f8..00000000 --- a/external_projects.cmake +++ /dev/null @@ -1 +0,0 @@ -include("${EXTERNAL_PROJECTS_DIR}/otelcol_sumo.cmake") diff --git a/external_projects/otelcol_sumo.cmake b/external_projects/otelcol_sumo.cmake deleted file mode 100644 index 7771e719..00000000 --- a/external_projects/otelcol_sumo.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# An external project to download a remote artifact from a GitHub Release. -# src: name of the remote artifact -# dest: destination file name which src will be renamed to -# tag: name of tag for the GitHub Release used to download artifacts from -function(create_otelcol_sumo_target src dest tag download_dir) - set(base_url "https://github.com/SumoLogic/sumologic-otel-collector") - set(file_url "${base_url}/releases/download/${tag}/${src}") - - ExternalProject_Add("${src}" - URL "${file_url}" - DOWNLOAD_DIR "${download_dir}" - DOWNLOAD_NAME "${dest}" - DOWNLOAD_NO_EXTRACT true - # We only care about downloading; disable all other commands - CONFIGURE_COMMAND "" - UPDATE_COMMAND "" - PATCH_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" - ) - - message(STATUS "The ${src} artifact will be fetched from:") - message(STATUS "\t${file_url}") -endfunction() diff --git a/images/release_0.png b/images/release_0.png new file mode 100644 index 00000000..2847d3ec Binary files /dev/null and b/images/release_0.png differ diff --git a/images/release_1.png b/images/release_1.png new file mode 100644 index 00000000..6e365b97 Binary files /dev/null and b/images/release_1.png differ diff --git a/images/release_2.png b/images/release_2.png new file mode 100644 index 00000000..8961b7f5 Binary files /dev/null and b/images/release_2.png differ diff --git a/install-script/install.ps1 b/install-script/install.ps1 index 92e7c629..3334ac94 100644 --- a/install-script/install.ps1 +++ b/install-script/install.ps1 @@ -31,11 +31,44 @@ param ( [string] $Api, # The OpAmp Endpoint used to communicate with the OpAmp backend - [string] $OpAmpApi + [string] $OpAmpApi, + + # OverrideArch overrides the architecture detected by this script. This can + # enable installation of x64 packages on an ARM64 system. The default value + # is set to the value of the OVERRIDE_ARCH environment variable. + [string] $OverrideArch = $env:OVERRIDE_ARCH, + + # SkipArchDetection will disable the detection of the CPU architecture. + # CPU architecture detection is slow. Using OverrideArch with this flag + # improves the overall time it takes to execute this script. + [bool] $SkipArchDetection, + + # S3Bucket is used to specify which S3 bucket to download the MSI package + # from. The default value is set to the value of the S3_BUCKET environment + # variable. + [string] $S3Bucket = $env:S3_BUCKET, + + # S3Region is used to specify which S3 region to download the MSI package + # from. The default value is set to the value of the S3_REGION environment + # variable. + [string] $S3Region = $env:S3_REGION ) -$PackageGithubOrg = "SumoLogic" -$PackageGithubRepo = "sumologic-otel-collector-packaging" +# If the environment variable SKIP_ARCH_DETECTION is set and is not +# equal to "0" then set $SkipArchDetection to $True. +if ($env:SKIP_ARCH_DETECTION -ne "" -and $env:SKIP_ARCH_DETECTION -ne "0") { + $SkipArchDetection = $True +} + +if ($S3Bucket -eq "") { + $S3Bucket = "sumologic-osc-stable" +} + +if ($S3Region -eq "") { + $S3Region = "us-west-2" +} + +$S3URI = "https://" + $S3Bucket + ".s3." + $S3Region + ".amazonaws.com" ## # Security tweaks @@ -146,6 +179,11 @@ function Get-OSName } function Get-ArchName { + param ( + [Parameter(Mandatory, Position=0)] + [bool] $AllowUnsupported + ) + Write-Host "Detecting architecture..." [int] $archId = (Get-CimInstance Win32_Processor)[0].Architecture @@ -160,13 +198,26 @@ function Get-ArchName { switch ($arch) { + x86 { $archName = "x86" } x64 { $archName = "x64" } + MIPS { $archName = "MIPS" } + Alpha { $archName = "Alpha" } + PowerPC { $archName = "PowerPC" } + ia64 { $archName = "ia64" } + ARM64 { $archName = "ARM64" } default { Write-Error "Unsupported architecture:`t${arch}" -ErrorAction Stop } } + # Only x64 is supported at the moment + if (!($AllowUnsupported)) { + if ($archName -ne "x64") { + Write-Error "Unsupported architecture:`t${archName}" -ErrorAction Stop + } + } + return $archName } @@ -210,98 +261,18 @@ function Get-InstalledPackageVersion { return $package.Version.Replace("-", ".") } -function Get-Version { +function Get-LatestVersion { param ( - [Parameter(Mandatory, Position=0)] - [ValidateSet("All", "Latest")] - [string] $Command, - [Parameter(Mandatory, Position=1)] [HttpClient] $HttpClient ) - switch ($Command) { - All { - $request = [HttpRequestMessage]::new() - $request.Method = "GET" - $request.RequestURI = "https://api.github.com/repos/" + $PackageGithubOrg + "/" + $PackageGithubRepo + "/releases" - $request.Headers.Add("Accept", "application/vnd.github+json") - $request.Headers.Add("X-GitHub-Api-Version", "2022-11-28") - - $response = $HttpClient.SendAsync($request).GetAwaiter().GetResult() - if (!($response.IsSuccessStatusCode)) { - $statusCode = [int]$response.StatusCode - $reasonPhrase = $response.StatusCode.ToString() - $errMsg = "${statusCode} ${reasonPhrase}" - - if ($response.Content -ne $null) { - $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() - $errMsg += ": ${content}" - } - - Write-Error $errMsg -ErrorAction Stop - } - - $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() - $releases = $content | ConvertFrom-Json - $filtered = @() - - foreach ($release in $releases) { - # Skip draft releases - if ($release.Draft -eq $true) { - Write-Debug "Skipping draft release: ${release.Name}" - continue - } - - # Skip prereleases - if ($release.Prerelease -eq $true) { - Write-Debug "Skipping prerelease: ${release.Name}" - continue - } - - $filtered += $release.Tag_name.TrimStart("v") - } - - return $filtered - } - - Latest { - $request = [HttpRequestMessage]::new() - $request.Method = "GET" - $request.RequestURI = "https://github.com/" + $PackageGithubOrg + "/" + $PackageGithubRepo + "/releases/latest" - $request.Headers.Add("Accept", "application/json") - - $response = $HttpClient.SendAsync($request).GetAwaiter().GetResult() - if (!($response.IsSuccessStatusCode)) { - $statusCode = [int]$response.StatusCode - $reasonPhrase = $response.StatusCode.ToString() - $errMsg = "${statusCode} ${reasonPhrase}" - - if ($response.Content -ne $null) { - $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() - $errMsg += ": ${content}" - } - - Write-Error $errMsg -ErrorAction Stop - } - - $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() - $release = $content | ConvertFrom-Json - - return $release.Tag_name.TrimStart("v") - } - } -} - -function Get-Changelog { - param ( - [Parameter(Mandatory, Position=0)] - [HttpClient] $HttpClient - ) - + $URI = $S3URI + "/latest_version" $request = [HttpRequestMessage]::new() $request.Method = "GET" - $request.RequestURI = "https://raw.githubusercontent.com/SumoLogic/sumologic-otel-collector/main/CHANGELOG.md" + $request.RequestURI = $URI + + Write-Host "Fetching latest version from: ${URI}" $response = $HttpClient.SendAsync($request).GetAwaiter().GetResult() if (!($response.IsSuccessStatusCode)) { @@ -317,53 +288,14 @@ function Get-Changelog { Write-Error $errMsg -ErrorAction Stop } - return $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() + $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult() + return $content -replace "`n","" -replace "`r","" } -function Show-BreakingChanges { +function Get-BinaryFromURI { param ( [Parameter(Mandatory, Position=0)] - [string[]] $Versions, - - [Parameter(Mandatory, Position=1)] - [string] $Changelog - ) - - $splitChangelog = $Changelog -Split "\n" - $breakingVersions = @() - - foreach ($version in $Versions) { - # Get lines matching the following and join them into a string: - # * ## - # * ## Breaking - # * breaking changes - $matchingRegex = "^## |^### Breaking|breaking changes" - $matchingLines = ( - $splitChangelog | Select-String -Pattern $matchingRegex - ) -Join "`r`n" - - # Find the section for $version and get the content between it and the - # next version section. - $isBreakingRegex = "(?s)(?<=## \[v${version}\]).*?(?=\r\n## )" - $isBreakingChange = ( - $matchingLines | Select-String -Pattern $isBreakingRegex - ).Matches.Value -ne "" - - if ($isBreakingChange) { - $breakingVersions += $version - } - } - - if ($breakingVersions.Count -gt 0) { - $versionsStr = $breakingVersions -Join ", v" - Write-Host "The following versions contain breaking changes: v${versionsStr}! Please make sure to read the linked Changelog file." - } -} - -function Get-BinaryFromUri { - param ( - [Parameter(Mandatory, Position=0)] - [string] $Uri, + [string] $URI, [Parameter(Mandatory, Position=1)] [string] $Path, @@ -377,10 +309,10 @@ function Get-BinaryFromUri { Remove-Item $Path } - Write-Host "Preparing to download ${Uri}" - $requestUri = [System.Uri]$Uri + Write-Host "Preparing to download ${URI}" + $requestURI = [System.Uri]$URI $optReadHeaders = [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead - $response = $HttpClient.GetAsync($requestUri, $optReadHeaders).GetAwaiter().GetResult() + $response = $HttpClient.GetAsync($requestURI, $optReadHeaders).GetAwaiter().GetResult() $responseMsg = $response.EnsureSuccessStatusCode() $httpStream = $response.Content.ReadAsStreamAsync().GetAwaiter().GetResult() @@ -391,7 +323,7 @@ function Get-BinaryFromUri { ) $copier = $httpStream.CopyToAsync($fileStream) - Write-Host "Downloading ${requestUri}" + Write-Host "Downloading ${requestURI}" $copier.Wait() $fileStream.Close() $httpStream.Close() @@ -409,9 +341,22 @@ try { } $osName = Get-OSName - $archName = Get-ArchName Write-Host "Detected OS type:`t${osName}" - Write-Host "Detected architecture:`t${archName}" + + if ($SkipArchDetection -eq $False) { + $archName = Get-ArchName -AllowUnsupported ($OverrideArch -ne "") + Write-Host "Detected architecture:`t${archName}" + } else { + if ($OverrideArch -eq "") { + Write-Error "OverrideArch flag must be set when using SkipArchDetection" + } + Write-Host "Skipping architecture detection" + } + + if ($OverrideArch -ne "") { + $archName = $OverrideArch + Write-Host "Architecture overridden: `t${archName}" + } $handler = New-Object HttpClientHandler $handler.AllowAutoRedirect = $true @@ -443,47 +388,22 @@ try { Write-Host "Installed app version:`t${installedAppVersionStr}" Write-Host "Installed package version:`t${installedPackageVersionStr}" - # Get versions, but ignore errors as we fallback to other methods later - Write-Host "Getting versions..." - $versions = Get-Version -Command All -HttpClient $httpClient - # Use user's version if set, otherwise get latest version from API (or website) if ($Version -eq "") { - if ($versions.Count -eq 1) { - $Version = $versions - } elseif ($versions.Count -gt 1) { - $Version = $versions[0] - } else { - $Version = Get-Version -Command Latest -HttpClient $httpClient - } + Write-Host "Getting latest version..." + $Version = Get-LatestVersion -HttpClient $httpClient } - # tags in the packaging repository have a dash before the build number, the Windows convention is a stop - $Tag = $Version - $Version = $Version.Replace("-", ".") + # versions have a dash before the build number, the Windows convention is a dot + $msiVersion = $Version.Replace("-", ".") Write-Host "Package version to install:`t${Version}" # Check if otelcol is already in newest version - if ($installedPackageVersion -eq $Version) { - Write-Host "OpenTelemetry collector is already in newest (${Version}) version" - } else { - # add newline before breaking changes and changelog - Write-Host "" - if (($installedVersion -ne "") -And ($versions -ne $null)) { - # Take versions from installed up to the newest - $index = $versions.IndexOf($installedVersion) - if ($index -gt 0) { - $changelog = Get-Changelog $httpClient - Show-BreakingChanges $versions[0..($index-1)] $changelog - } - } + if ($installedPackageVersion -eq $msiVersion) { + Write-Host "OpenTelemetry collector is already in newest (${msiVersion}) version" } - Write-Host "Changelog:`t`thttps://github.com/SumoLogic/sumologic-otel-collector/blob/main/CHANGELOG.md" - # add newline after breaking changes and changelog - Write-Host "" - # Add -fips to the msi filename if necessary $fipsSuffix = "" if ($Fips -eq $true) { @@ -493,11 +413,10 @@ try { # Download MSI $msiLanguage = "en-US" - $msiFileName = "otelcol-sumo_${Version}_${msiLanguage}.${archName}${fipsSuffix}.msi" - $msiUri = "https://github.com/" + $PackageGithubOrg + "/" + $PackageGithubRepo + "/releases/download/" - $msiUri += "v${Tag}/${msiFileName}" + $msiFileName = "otelcol-sumo_${msiVersion}_${msiLanguage}.${archName}${fipsSuffix}.msi" + $msiURI = $S3URI + "/" + $Version + "/" + $msiFileName $msiPath = "${env:TEMP}\${msiFileName}" - Get-BinaryFromUri $msiUri -Path $msiPath -HttpClient $httpClient + Get-BinaryFromURI $msiURI -Path $msiPath -HttpClient $httpClient # Install MSI [string[]] $msiProperties = @() @@ -533,4 +452,6 @@ try { msiexec.exe /i "$msiPath" /passive $msiProperties } catch [HttpRequestException] { Write-Error $_.Exception.InnerException.Message -} \ No newline at end of file +} + +Write-Host "Installation successful" diff --git a/install-script/install.sh b/install-script/install.sh index cac7adb9..fa7ffe8e 100755 --- a/install-script/install.sh +++ b/install-script/install.sh @@ -110,8 +110,10 @@ KEEP_DOWNLOADS=false CURL_MAX_TIME=1800 -PACKAGE_GITHUB_ORG="SumoLogic" -PACKAGE_GITHUB_REPO="sumologic-otel-collector-packaging" +# NB: the S3 variables are only used on Darwin +S3_BUCKET="${S3_BUCKET:-sumologic-osc-stable}" +S3_REGION="${S3_REGION:-us-west-2}" +S3_URI="https://${S3_BUCKET}.s3.${S3_REGION}.amazonaws.com" PACKAGECLOUD_ORG="${PACKAGECLOUD_ORG:-sumologic}" PACKAGECLOUD_REPO="${PACKAGECLOUD_REPO:-stable}" @@ -312,11 +314,6 @@ function parse_options() { done } -# Get github rate limit -function github_rate_limit() { - curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 --retry-max-time 150 -X GET https://api.github.com/rate_limit -v 2>&1 | grep x-ratelimit-remaining | grep -oE "[0-9]+" -} - # Ensure TMPDIR is set to a directory where we can safely store temporary files function set_tmpdir() { # generate a new tmpdir using mktemp @@ -350,47 +347,11 @@ function check_dependencies() { fi } -function get_latest_github_package_version() { - local versions - readonly versions="${1}" - - # get latest version directly from website if there is no versions from api - if [[ -z "${versions}" ]]; then - curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 \ - --retry-max-time 150 -s \ - "https://github.com/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/releases" \ - | grep -oE '/'${PACKAGE_GITHUB_ORG}'/'${PACKAGE_GITHUB_REPO}'/releases/tag/(.*)"' \ - | head -n 1 \ - | sed 's%/'${PACKAGE_GITHUB_ORG}'/'${PACKAGE_GITHUB_REPO}'/releases/tag/v\([^"]*\)".*%\1%g' - else - # sed 's/ /\n/g' converts spaces to new lines - echo "${versions}" | sed 's/ /\n/g' | head -n 1 - fi -} - -# Get available versions of otelcol-sumo -# skip prerelease and draft releases -# sort it from last to first -# remove v from beginning of version -function get_github_package_versions() { - # returns empty in case we exceeded github rate limit. This can happen if we are running this script too many times in a short period. - if [[ "$(github_rate_limit)" == "0" ]]; then - return - fi - - curl \ - --connect-timeout 5 \ - --max-time 30 \ - --retry 5 \ - --retry-delay 0 \ - --retry-max-time 150 \ - -sH "Accept: application/vnd.github.v3+json" \ - https://api.github.com/repos/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/releases \ - | grep -E '(tag_name|"(draft|prerelease)")' \ - | sed 'N;N;s/.*true.*//' \ - | grep -o 'v.*"' \ - | sort -rV \ - | sed 's/^v//;s/"$//' +# NB: this function is only for Darwin +function get_latest_s3_package_version() { + curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 \ + --retry-max-time 150 -s \ + "${S3_URI}/latest_version" | tr -d '\n' } # Get OS type (linux or darwin) @@ -781,81 +742,6 @@ function write_opamp_extension() { } # NB: this function is only for Darwin -function get_package_from_branch() { - local branch - readonly branch="${1}" - - local name - readonly name="${2}" - - local actions_url actions_output artifacts_link artifact_id - readonly actions_url="https://api.github.com/repos/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/actions/runs?status=success&branch=${branch}&event=push&per_page=1" - echo -e "Getting artifacts from latest CI run for branch \"${branch}\":\t\t${actions_url}" - actions_output="$(curl -f -sS \ - --connect-timeout 5 \ - --max-time 30 \ - --retry 5 \ - --retry-delay 0 \ - --retry-max-time 150 \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${actions_url}")" - readonly actions_output - - # get latest action run - artifacts_link="$(echo "${actions_output}" | grep '"url"' | grep -oE '"https.*packaging/actions.*"' -m 1)" - - # strip first and last double-quote from $artifacts_link - artifacts_link=${artifacts_link%\"} - artifacts_link="${artifacts_link#\"}" - artifacts_link="${artifacts_link}/artifacts" - readonly artifacts_link - - echo -e "Getting artifact id for CI run:\t\t${artifacts_link}" - artifact_id="$(curl -f -sS \ - --connect-timeout 5 \ - --max-time 30 \ - --retry 5 \ - --retry-delay 0 \ - --retry-max-time 150 \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${artifacts_link}" \ - | grep -E '"(id|name)"' \ - | grep -B 1 "\"${name}\"" -m 1 \ - | grep -oE "[0-9]+" -m 1)" - readonly artifact_id - - echo "Artifact ID: ${artifact_id}" - - local artifact_url download_path curl_args - readonly artifact_url="https://api.github.com/repos/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/actions/artifacts/${artifact_id}/zip" - readonly download_path="${DOWNLOAD_CACHE_DIR}/${artifact_id}.zip" - echo -e "Downloading package from: ${artifact_url}" - curl_args=( - "-fL" - "--connect-timeout" "5" - "--max-time" "${CURL_MAX_TIME}" - "--retry" "5" - "--retry-delay" "0" - "--retry-max-time" "150" - "--output" "${download_path}" - "--progress-bar" - ) - if [ "${KEEP_DOWNLOADS}" == "true" ]; then - curl_args+=("-z" "${download_path}") - fi - curl "${curl_args[@]}" \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - "${artifact_url}" - - unzip -p "$download_path" > "${TMPDIR}/otelcol-sumo.pkg" - if [ "${KEEP_DOWNLOADS}" == "false" ]; then - rm -f "${download_path}" - fi -} - function get_package_from_url() { local url download_filename download_path curl_args readonly url="${1}" @@ -995,6 +881,15 @@ function install_linux_package() { } function check_deprecated_linux_flags() { + if [[ -n "${BINARY_BRANCH}" ]]; then + echo "warning: --binary-branch is deprecated" + exit 1 + fi + + if [[ -n "${CONFIG_BRANCH}" ]]; then + echo "warning: --config-branch is deprecated" + fi + if [[ "${OS_TYPE}" == "darwin" ]]; then return fi @@ -1003,15 +898,6 @@ function check_deprecated_linux_flags() { echo "--download-only is only supported on darwin, use 'install.sh --upgrade' to upgrade otelcol-sumo" exit 1 fi - - if [[ -n "${BINARY_BRANCH}" ]]; then - echo "--binary-branch is only supported on darwin, use --version, --channel, and --channel-token on linux" - exit 1 - fi - - if [[ -n "${CONFIG_BRANCH}" ]]; then - echo "warning: --config-branch is deprecated" - fi } function is_package_installed() { @@ -1192,13 +1078,6 @@ if [[ "${OS_TYPE}" == "darwin" ]]; then fi fi - set +u - if [[ -n "${BINARY_BRANCH}" && -z "${GITHUB_TOKEN}" ]]; then - echo "GITHUB_TOKEN env is required for '${ARG_LONG_BINARY_BRANCH}' option" - exit 1 - fi - set -u - package_arch="" case "${ARCH_TYPE}" in "amd64") package_arch="intel" ;; @@ -1210,38 +1089,29 @@ if [[ "${OS_TYPE}" == "darwin" ]]; then esac readonly package_arch - if [[ -z "${DARWIN_PKG_URL}" ]]; then - echo -e "Getting versions..." - # Get versions, but ignore errors as we fallback to other methods later - VERSIONS="$(get_github_package_versions || echo "")" + pkg_url="" + if [[ -z "${DARWIN_PKG_URL}" ]]; then # Use user's version if set, otherwise get latest version from API (or website) if [[ -z "${VERSION}" ]]; then - VERSION="$(get_latest_github_package_version "${VERSIONS}")" + echo -e "Getting latest version..." + VERSION="$(get_latest_s3_package_version)" fi - readonly VERSIONS VERSION + readonly VERSION echo -e "Version to install:\t${VERSION}" - package_suffix="${package_arch}.pkg" - - if [[ -n "${BINARY_BRANCH}" ]]; then - artifact_name="otelcol-sumo_.*-${package_suffix}" - get_package_from_branch "${BINARY_BRANCH}" "${artifact_name}" - else - artifact_name="otelcol-sumo_${VERSION}-${package_suffix}" - readonly artifact_name + artifact_name="otelcol-sumo_${VERSION}-${package_arch}.pkg" + readonly artifact_name - LINK="https://github.com/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/releases/download/v${VERSION}/${artifact_name}" - readonly LINK - - get_package_from_url "${LINK}" - fi + pkg_url="${S3_URI}/${VERSION}/${artifact_name}" else - get_package_from_url "${DARWIN_PKG_URL}" + pkg_url="${DARWIN_PKG_URL}" fi + get_package_from_url "${pkg_url}" + pkg="${TMPDIR}/otelcol-sumo.pkg" if [[ "${DOWNLOAD_ONLY}" == "true" ]]; then diff --git a/install-script/test/Makefile b/install-script/test/Makefile index 335c4041..bb5a717f 100644 --- a/install-script/test/Makefile +++ b/install-script/test/Makefile @@ -3,7 +3,15 @@ ifeq ($(OS),Windows_NT) endif ifneq ($(OS),windows) - GOTESTPREFIX ?= sudo env PATH="${PATH}" GH_CI_TOKEN="${GITHUB_TOKEN}" DARWIN_PKG_URL="${DARWIN_PKG_URL}" PACKAGECLOUD_MASTER_TOKEN="${PACKAGECLOUD_MASTER_TOKEN}" PACKAGECLOUD_REPO="${PACKAGECLOUD_REPO}" OTC_VERSION="${OTC_VERSION}" OTC_BUILD_NUMBER="${OTC_BUILD_NUMBER}" + GOTESTPREFIX ?= sudo env \ + PATH="${PATH}" \ + GH_CI_TOKEN="${GITHUB_TOKEN}" \ + DARWIN_PKG_URL="${DARWIN_PKG_URL}" \ + PACKAGECLOUD_MASTER_TOKEN="${PACKAGECLOUD_MASTER_TOKEN}" \ + PACKAGECLOUD_REPO="${PACKAGECLOUD_REPO}" \ + OTC_VERSION="${OTC_VERSION}" \ + OTC_BUILD_NUMBER="${OTC_BUILD_NUMBER}" \ + S3_BUCKET="${S3_BUCKET}" endif LINT=golangci-lint diff --git a/install-script/test/command_windows.go b/install-script/test/command_windows.go index cea52c45..59d6a0af 100644 --- a/install-script/test/command_windows.go +++ b/install-script/test/command_windows.go @@ -18,6 +18,7 @@ type installOptions struct { installHostmetrics bool remotelyManaged bool ephemeral bool + version string } func (io *installOptions) string() []string { @@ -52,6 +53,15 @@ func (io *installOptions) string() []string { opts = append(opts, "-Api", mockAPIBaseURL) } + otc_version := os.Getenv("OTC_VERSION") + otc_build_number := os.Getenv("OTC_BUILD_NUMBER") + + if io.version != "" { + opts = append(opts, "-Version", io.version) + } else if otc_version != "" && otc_build_number != "" { + opts = append(opts, "-Version", fmt.Sprintf("%s-%s", otc_version, otc_build_number)) + } + return opts } diff --git a/packages.cmake b/packages.cmake index fd3f8011..faa7fb8b 100644 --- a/packages.cmake +++ b/packages.cmake @@ -6,18 +6,41 @@ function(append_to_publish_targets) set_property(GLOBAL PROPERTY _all_publish_targets "${tmp}") endfunction() +function(download_github_artifact _slug _workflow_id _remote_filename _target) + if(TARGET ${_target}) + message(STATUS "Target already exists: ${_remote_filename}") + else() + message(STATUS "Creating target: ${_remote_filename}") + set(_cmd_str "${GH_PROGRAM} run download -R ${_gh_slug} ${_gh_workflow} -n ${_remote_filename}") + separate_arguments(_cmd UNIX_COMMAND "${_cmd_str}") + add_custom_command( + OUTPUT ${_remote_filename} + COMMAND ${_cmd} + COMMENT "Downloading ${_remote_filename} from GitHub" + VERBATIM + ) + add_custom_target(${_target} ALL DEPENDS ${_remote_filename}) + endif() +endfunction() + # Build CPackConfig, create a target for building the package and add the target # to the list of all package targets macro(build_cpack_config) require_variables( "CPACK_PACKAGE_FILE_NAME" + "GH_WORKFLOW_ID" "PACKAGE_FILE_EXTENSION" - "OTC_BINARY" - "OTC_CONFIG_BINARY" - "SOURCE_OTC_BINARY" - "SOURCE_OTC_CONFIG_BINARY" + "OTC_BIN" + "OTC_CONFIG_BIN" + "REMOTE_OTC_BIN" ) + set(_gh_slug "SumoLogic/sumologic-otel-collector") + set(_gh_workflow "${GH_WORKFLOW_ID}") + + download_github_artifact(${_gh_slug} ${_gh_workflow} ${REMOTE_OTC_BIN} ${OTC_BIN}) + download_github_artifact(${_gh_slug} ${_gh_workflow} ${REMOTE_OTC_CONFIG_BIN} ${OTC_CONFIG_BIN}) + # Set a GitHub output with a name matching ${target_name}-pkg and a value # equal to the filename of the package that will be built. This provides # GitHub Actions with the package filename so that it can be uploaded as a @@ -25,96 +48,6 @@ macro(build_cpack_config) set(package_file_name "${CPACK_PACKAGE_FILE_NAME}.${PACKAGE_FILE_EXTENSION}") set_github_output("package_name" "${package_file_name}") - # Set a GitHub output with a name matching ${target_name}-otc-bin and a value - # equal to the name of the otelcol-sumo binary artifact that we want GitHub - # Actions to fetch from the sumologic-otel-collector's GitHub Workflow - # artifacts. This is only used when the OTC_ARTIFACTS_SOURCE environment - # variable is set to "github-artifacts" which disables fetching artifacts from - # a GitHub Release. - if(DEFINED ENV{OTC_ARTIFACTS_SOURCE}) - if($ENV{OTC_ARTIFACTS_SOURCE} STREQUAL "github-artifacts") - require_variables( - "GH_ARTIFACTS_DIR" - "GH_OUTPUT_OTC_BIN" - "GH_OUTPUT_OTC_CONFIG_BIN" - ) - - file(MAKE_DIRECTORY "${GH_ARTIFACTS_DIR}") - file(CHMOD_RECURSE "${GH_ARTIFACTS_DIR}" - DIRECTORY_PERMISSIONS - OWNER_WRITE OWNER_READ OWNER_EXECUTE - GROUP_WRITE GROUP_READ GROUP_EXECUTE - WORLD_WRITE WORLD_READ WORLD_EXECUTE - ) - set_github_output("otc-bin" "${GH_OUTPUT_OTC_BIN}") - set_github_output("otc-config-bin" "${GH_OUTPUT_OTC_CONFIG_BIN}") - else() - message(FATAL_ERROR - "Unsupported value for OTC_ARTIFACTS_SOURCE environment variable: $ENV{OTC_ARTIFACTS_SOURCE}" - ) - endif() - - # Create a target, if the target does not yet exist, for copying the - # otelcol-sumo binary from the gh-actions directory to the artifacts - # directory - if(TARGET "${SOURCE_OTC_BINARY}") - message(STATUS "Target already exists: ${SOURCE_OTC_BINARY}") - else() - message(STATUS "Creating target: ${SOURCE_OTC_BINARY}") - file(MAKE_DIRECTORY "${SOURCE_OTC_BINARY_DIR}") - add_custom_target("${SOURCE_OTC_BINARY}" - ALL - COMMAND ${CMAKE_COMMAND} -E copy ${GH_ARTIFACT_OTC_BINARY_PATH} ${SOURCE_OTC_BINARY_PATH} - VERBATIM - ) - endif() - - # Create a target, if the target does not yet exist, for copying the - # otelcol-config binary from the gh-actions directory to the artifacts - # directory - if(TARGET "${SOURCE_OTC_CONFIG_BINARY}") - message(STATUS "Target already exists: ${SOURCE_OTC_CONFIG_BINARY}") - else() - message(STATUS "Creating target: ${SOURCE_OTC_CONFIG_BINARY}") - file(MAKE_DIRECTORY "${SOURCE_OTC_CONFIG_BINARY_DIR}") - add_custom_target("${SOURCE_OTC_CONFIG_BINARY}" - ALL - COMMAND ${CMAKE_COMMAND} -E copy ${GH_ARTIFACT_OTC_CONFIG_BINARY_PATH} ${SOURCE_OTC_CONFIG_BINARY_PATH} - VERBATIM - ) - endif() - else() - # Create a target for downloading the otelcol-sumo binary from GitHub - # Releases if the target does not exist yet - if(TARGET "${SOURCE_OTC_BINARY}") - message(STATUS "Target already exists: ${SOURCE_OTC_BINARY}") - else() - message(STATUS "Creating target: ${SOURCE_OTC_BINARY}") - require_variables("OTC_GIT_TAG") - create_otelcol_sumo_target( - "${SOURCE_OTC_BINARY}" - "${OTC_BINARY}" - "${OTC_GIT_TAG}" - "${SOURCE_OTC_BINARY_DIR}" - ) - endif() - - # Create a target for downloading the otelcol-config binary from GitHub - # Releases if the target does not exist yet - if(TARGET "${SOURCE_OTC_CONFIG_BINARY}") - message(STATUS "Target already exists: ${SOURCE_OTC_CONFIG_BINARY}") - else() - message(STATUS "Creating target: ${SOURCE_OTC_CONFIG_BINARY}") - require_variables("OTC_GIT_TAG") - create_otelcol_sumo_target( - "${SOURCE_OTC_CONFIG_BINARY}" - "${OTC_CONFIG_BINARY}" - "${OTC_GIT_TAG}" - "${SOURCE_OTC_CONFIG_BINARY_DIR}" - ) - endif() - endif() - set(_package_file "${CPACK_PACKAGE_FILE_NAME}.${PACKAGE_FILE_EXTENSION}") set(_package_output "${CMAKE_BINARY_DIR}/${_package_file}") @@ -135,6 +68,13 @@ macro(build_cpack_config) create_packagecloud_publish_target(${_pc_user} ${_pc_repo} ${_pc_distro} ${_package_output}) endforeach() + # Add a target for uploading the package to Amazon S3 + set(_s3_channel "ci-builds") + set(_version "${OTC_VERSION}-${BUILD_NUMBER}") + set(_s3_bucket "sumologic-osc-${_s3_channel}") + set(_s3_path "${_version}/") + create_s3_cp_target(${_s3_bucket} ${_s3_path} ${_package_output}) + # Add a publish-package target to publish the package built above get_property(_all_publish_targets GLOBAL PROPERTY _all_publish_targets) add_custom_target(publish-package @@ -182,6 +122,18 @@ function(create_wait_for_packagecloud_indexing_target _pc_user _pc_repo _pkg_pat DEPENDS ${_pc_output}) endfunction() +# Create an Amazon S3 publish target for uploading a package to an S3 bucket. +function(create_s3_cp_target _s3_bucket _s3_path _pkg_path) + set(_s3_output "${_pkg_path}-s3-${_s3_bucket}") + separate_arguments(_s3_cp_cmd UNIX_COMMAND "aws s3 cp ${_pkg_path} s3://${_s3_bucket}/${_s3_path}") + add_custom_command(OUTPUT ${_s3_output} + COMMAND ${_s3_cp_cmd} + DEPENDS ${_pkg_path} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + VERBATIM) + append_to_publish_targets(${_s3_output}) +endfunction() + # Sets a GitHub output parameter by appending a statement to the file defined by # the GITHUB_OUTPUT environment variable. It enables the passing of data from # this CMake project to GitHub Actions. diff --git a/settings/common.cmake b/settings/common.cmake index 632d2bab..6619f007 100644 --- a/settings/common.cmake +++ b/settings/common.cmake @@ -9,5 +9,5 @@ macro(set_common_settings) #set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE) set(ARTIFACTS_DIR "${CMAKE_BINARY_DIR}/artifacts") - set(GH_ARTIFACTS_DIR "${CMAKE_BINARY_DIR}/gh-artifacts") + set(ACL_LOG_FILE_PATHS "/var/log") endmacro() diff --git a/settings/otc.cmake b/settings/otc.cmake index b30c4f80..7aeea2a5 100644 --- a/settings/otc.cmake +++ b/settings/otc.cmake @@ -7,11 +7,6 @@ macro(set_otc_settings) "package_arch" ) - # OTC_GIT_TAG is used to determine which GitHub Release to fetch artifacts - # from. If ENV{OTC_ARTIFACTS_SOURCE} is set as then OTC_GIT_TAG will be - # ignored and the artifacts will be fetched from another source. - set(OTC_GIT_TAG "v${OTC_VERSION}-sumo-${OTC_SUMO_VERSION}") - ## # Destination file & directory names & paths # @@ -20,12 +15,12 @@ macro(set_otc_settings) ## # File names - set(OTC_BINARY "otelcol-sumo") - set(OTC_CONFIG_BINARY "otelcol-config") - set(OTC_LAUNCHD_CONFIG "com.sumologic.otelcol-sumo.plist") - set(OTC_SERVICE_SCRIPT "otelcol-sumo.sh") + set(OTC_BIN "otelcol-sumo") + set(OTC_CONFIG_BIN "otelcol-config") set(OTC_SUMOLOGIC_CONFIG "sumologic.yaml") set(OTC_SYSTEMD_CONFIG "otelcol-sumo.service") + set(OTC_SERVICE_SCRIPT "otelcol-sumo.sh") + set(OTC_LAUNCHD_CONFIG "com.sumologic.otelcol-sumo.plist") # Directories set(OTC_BIN_DIR "usr/local/bin") @@ -45,42 +40,29 @@ macro(set_otc_settings) endif() # File paths - set(OTC_BIN_PATH "${OTC_BIN_DIR}/${OTC_BINARY}") + set(OTC_BIN_PATH "${OTC_BIN_DIR}/${OTC_BIN}") set(OTC_SUMOLOGIC_CONFIG_PATH "${OTC_CONFIG_DIR}/${OTC_SUMOLOGIC_CONFIG}") ## - # Source file & directory names & paths + # Local & remote file & directory names & paths # # Specifies the names & paths of local & remote files required to build the # packages. ## - # File names - set(SOURCE_OTC_BINARY "otelcol-sumo-${OTC_VERSION}-sumo-${OTC_SUMO_VERSION}") - set(SOURCE_OTC_CONFIG_BINARY "otelcol-config-${OTC_VERSION}-sumo-${OTC_SUMO_VERSION}") - set(GH_OUTPUT_OTC_BIN "otelcol-sumo") - set(GH_OUTPUT_OTC_CONFIG_BIN "otelcol-config") + # Remote file names + set(REMOTE_OTC_BIN "otelcol-sumo") + set(REMOTE_OTC_CONFIG_BIN "otelcol-config") if(fips) - set(SOURCE_OTC_BINARY "${SOURCE_OTC_BINARY}-fips") - set(SOURCE_OTC_CONFIG_BINARY "${SOURCE_OTC_CONFIG_BINARY}-fips") - set(GH_OUTPUT_OTC_BIN "${GH_OUTPUT_OTC_BIN}-fips") - set(GH_OUTPUT_OTC_CONFIG_BIN "${GH_OUTPUT_OTC_CONFIG_BIN}-fips") + set(REMOTE_OTC_BIN "${REMOTE_OTC_BIN}-fips") + set(REMOTE_OTC_CONFIG_BIN "${REMOTE_OTC_CONFIG_BIN}-fips") endif() - set(SOURCE_OTC_BINARY "${SOURCE_OTC_BINARY}-${goos}_${goarch}") - set(SOURCE_OTC_CONFIG_BINARY "${SOURCE_OTC_CONFIG_BINARY}-${goos}_${goarch}") - set(GH_OUTPUT_OTC_BIN "${GH_OUTPUT_OTC_BIN}-${goos}_${goarch}") - set(GH_OUTPUT_OTC_CONFIG_BIN "${GH_OUTPUT_OTC_CONFIG_BIN}-${goos}_${goarch}") + set(REMOTE_OTC_BIN "${REMOTE_OTC_BIN}-${goos}_${goarch}") + set(REMOTE_OTC_CONFIG_BIN "${REMOTE_OTC_CONFIG_BIN}-${goos}_${goarch}") - # Directories - set(SOURCE_OTC_BINARY_DIR "${ARTIFACTS_DIR}/${SOURCE_OTC_BINARY}") - set(SOURCE_OTC_CONFIG_BINARY_DIR "${ARTIFACTS_DIR}/${SOURCE_OTC_CONFIG_BINARY}") - - # File paths - set(SOURCE_OTC_BINARY_PATH "${SOURCE_OTC_BINARY_DIR}/${OTC_BINARY}") - set(SOURCE_OTC_CONFIG_BINARY_PATH "${SOURCE_OTC_CONFIG_BINARY_DIR}/${OTC_CONFIG_BINARY}") - set(GH_ARTIFACT_OTC_BINARY_PATH "${GH_ARTIFACTS_DIR}/${GH_OUTPUT_OTC_BIN}") - set(GH_ARTIFACT_OTC_CONFIG_BINARY_PATH "${GH_ARTIFACTS_DIR}/${GH_OUTPUT_OTC_CONFIG_BIN}") - set(ACL_LOG_FILE_PATHS "/var/log") + # Remote file paths + set(REMOTE_OTC_BIN_PATH "${CMAKE_BINARY_DIR}/${REMOTE_OTC_BIN}") + set(REMOTE_OTC_CONFIG_BIN_PATH "${CMAKE_BINARY_DIR}/${REMOTE_OTC_CONFIG_BIN}") ## # Other @@ -106,12 +88,4 @@ macro(set_otc_settings) set(CPACK_RESOURCE_FILE_LICENSE "${ASSETS_DIR}/LICENSE") set(CPACK_PACKAGE_DESCRIPTION_FILE "${ASSETS_DIR}/description") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "An agent to send logs, metrics and traces to Sumo Logic") - - # Set target dependencies of the cpack target for this package. The - # otelcol-sumo binary matching the GOOS, GOARCH and FIPS flag are required for - # OTC packages. - set(target_dependencies - "${SOURCE_OTC_BINARY}" - "${SOURCE_OTC_CONFIG_BINARY}" - ) endmacro() diff --git a/utils.cmake b/utils.cmake index c1f340e3..029b4766 100644 --- a/utils.cmake +++ b/utils.cmake @@ -3,3 +3,4 @@ include("${UTILS_DIR}/cpack-state.cmake") include("${UTILS_DIR}/property.cmake") include("${UTILS_DIR}/build-validation.cmake") include("${UTILS_DIR}/targets.cmake") +include("${UTILS_DIR}/detect_version.cmake") diff --git a/utils/detect_version.cmake b/utils/detect_version.cmake new file mode 100644 index 00000000..68f1c4aa --- /dev/null +++ b/utils/detect_version.cmake @@ -0,0 +1,32 @@ +function(detect_version _artifact_bin _working_dir) + # Construct version command + set(_cmd_str "./${_artifact_bin} --version") + separate_arguments(_cmd UNIX_COMMAND ${_cmd_str}) + + message(STATUS "Setting working directory: ${_working_dir}") + message(STATUS "Running version command: ${_cmd_str}") + + # Get output of otelcol-sumo --version + execute_process(COMMAND ${_cmd} + WORKING_DIRECTORY ${_working_dir} + COMMAND_ERROR_IS_FATAL ANY + OUTPUT_VARIABLE _version_output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + message(STATUS "Version output: ${_version_output}") + + string(REGEX MATCH ".* v([0-9]+\.[0-9]+\.[0-9]+)\-sumo\-([0-9]+)\-.*" _ ${_version_output}) + + if(NOT CMAKE_MATCH_COUNT EQUAL 2) + message(FATAL_ERROR "Could not parse version information from version output") + endif() + + set(_otc_version "${CMAKE_MATCH_1}") + set(_sumo_version "${CMAKE_MATCH_2}") + set(_otc_version "${_otc_version}" PARENT_SCOPE) + set(_sumo_version "${_sumo_version}" PARENT_SCOPE) + + message(STATUS "Detected OTC version: ${_otc_version}") + message(STATUS "Detected Sumo version: ${_sumo_version}") +endfunction() diff --git a/utils/variables.cmake b/utils/variables.cmake index 0177e229..9efeb1fd 100644 --- a/utils/variables.cmake +++ b/utils/variables.cmake @@ -6,3 +6,12 @@ function(require_variables varNames) endif() endforeach() endfunction() + +# Print out all variables (for debugging) +function(print_all_variables) + get_cmake_property(_variableNames VARIABLES) + list (SORT _variableNames) + foreach (_variableName ${_variableNames}) + message(STATUS "${_variableName}=${${_variableName}}") + endforeach() +endfunction() diff --git a/version.cmake b/version.cmake index 98501f29..a90df64b 100644 --- a/version.cmake +++ b/version.cmake @@ -1,47 +1,20 @@ -# OTC_VERSION represents the base version of otelcol-sumo. This value is used to -# fetch the otelcol-sumo binary from GitHub and as the version of the packages -# produced by this project. -# E.g. the A.B.C in A.B.C-sumo-X -if(NOT DEFINED ENV{OTC_VERSION}) - message(FATAL_ERROR "OTC_VERSION environment variable must be set") -endif() - -set(OTC_VERSION "$ENV{OTC_VERSION}") - -if(NOT "${OTC_VERSION}" MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+$") - message(FATAL_ERROR - "OTC_VERSION contains an invalid version: ${OTC_VERSION}\n" - "Must be in the form X.Y.Z" - ) -endif() - -message(STATUS "OTC Version is set to: ${OTC_VERSION}") - -# OTC_SUMO_VERSION represents the "sumo" version of otelcol-sumo. It is -# primarily used for fetching the otelcol-sumo binary from GitHub but it will -# also be used for the PACKAGE_RELEASE version (e.g. the X in A.B.C-X) if -# OTC_BUILD_NUMBER is not specified. -# E.g. the X in A.B.C-sumo-X -if(NOT DEFINED ENV{OTC_SUMO_VERSION}) - message(FATAL_ERROR "OTC_SUMO_VERSION environment variable must be set") -endif() - -set(OTC_SUMO_VERSION "$ENV{OTC_SUMO_VERSION}") - -if(NOT ("${OTC_SUMO_VERSION}" MATCHES "^[0-9]+$" OR "${OTC_SUMO_VERSION}" MATCHES "^[0-9]+-rc.[0-9]+$")) - message(FATAL_ERROR - "OTC_SUMO_VERSION contains an invalid version: ${OTC_SUMO_VERSION}\n" - ) -endif() +# Determine the OTC version and OTC Sumo version from the output of a previously +# downloaded build of the otelcol-sumo binary. +set(_version_artifact_bin "otelcol-sumo") +set(_version_detection_dir "${CMAKE_BINARY_DIR}/version_detection") +detect_version("${_version_artifact_bin}" "${_version_detection_dir}") -message(STATUS "OTC Sumo Version is set to: ${OTC_SUMO_VERSION}") +set(OTC_VERSION "${_otc_version}") +set(OTC_SUMO_VERSION "${_sumo_version}") # OTC_BUILD_NUMBER represents the PACKAGE_RELEASE version used for incremental # changes to the packaging code. This should contain a unique, unsigned integer -# that increments with each build to allow upgrades from one package to another. -# A CI job number will typically be used for this value. +# that increments with each build to allow upgrades from one package version to +# another. +# A CI job number will typically be used for this value as it will naturally +# increase with each new package build. # E.g. the X in A.B.C-X or A.B.C.X -if(DEFINED ENV{OTC_BUILD_NUMBER}) +if(DEFINED ENV{OTC_BUILD_NUMBER} AND NOT "$ENV{OTC_BUILD_NUMBER}" STREQUAL "") set(BUILD_NUMBER "$ENV{OTC_BUILD_NUMBER}") else() set(BUILD_NUMBER "${OTC_SUMO_VERSION}") diff --git a/version_artifact.cmake b/version_artifact.cmake new file mode 100644 index 00000000..a821032d --- /dev/null +++ b/version_artifact.cmake @@ -0,0 +1,109 @@ +## +# This file is a CMake script and should be run in CMake's script mode. +# E.g. cmake -P fetch_artifacts.cmake +# +# Its purpose is to fetch otelcol-sumo matching the host system's operating +# system & CPU architecture from a given GitHub Actions workflow. This +# otelcol-sumo binary is used to determine the version for packages and is not +# included in the generated packages. +## + +# Require CMake >= 3.24.1 +cmake_minimum_required(VERSION 3.24.1 FATAL_ERROR) + +# Required environment variables +if(NOT DEFINED ENV{GH_TOKEN}) + message(FATAL_ERROR "GH_TOKEN environment variable must be set") +endif() + +if(NOT DEFINED ENV{GH_WORKFLOW_ID}) + message(FATAL_ERROR "GH_WORKFLOW_ID environment variable must be set") +endif() + +# Required and optional programs. Attempts to find required and optional +# programs used to build the packages. +find_program(GH_PROGRAM gh REQUIRED) + +# Include the CMakeDetermineSystem module manually as it is not included when +# CMake runs in script mode. This is required for the host's CPU architecture +# to be detected. +set(CMAKE_PLATFORM_INFO_DIR "${CMAKE_SOURCE_DIR}/build/cmake") +include(CMakeDetermineSystem) + +# Set supported platforms for version detection +set(_supported_platforms "") +list(APPEND _supported_platforms "darwin_amd64") +list(APPEND _supported_platforms "darwin_arm64") +list(APPEND _supported_platforms "linux_amd64") +list(APPEND _supported_platforms "linux_arm64") +list(APPEND _supported_platforms "windows_amd64") + +# Detect host system +string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" _os) +string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" _arch) + +# Convert _arch to GOARCH equivalent name +if("${_arch}" STREQUAL "aarch64") + set(_arch "arm64") +endif() + +if("${_arch}" STREQUAL "x86_64") + set(_arch "amd64") +endif() + +set(_platform "${_os}_${_arch}") +message(STATUS "Detected platform: ${_platform}") + +if(NOT "${_platform}" IN_LIST _supported_platforms) + message(FATAL_ERROR "This script does not support this machine's platform: ${_platform}") +endif() + +set(_bin_ext "") +if("${_os}" STREQUAL "windows") + set(_bin_ext ".exe") +endif() + +# Set directory variables +set(UTILS_DIR "${CMAKE_SOURCE_DIR}/utils") +set(_build_dir "${CMAKE_SOURCE_DIR}/build") +set(_version_detection_dir "${_build_dir}/version_detection") + +# Include CMake files +include("${CMAKE_SOURCE_DIR}/utils.cmake") + +# GitHub variables +set(_gh_org "SumoLogic") +set(_gh_repo "sumologic-otel-collector") +set(_gh_slug "${_gh_org}/${_gh_repo}") +set(_gh_workflow "$ENV{GH_WORKFLOW_ID}") + +# Remote OTC artifact +set(_artifact_bin "otelcol-sumo-${_os}_${_arch}${_bin_ext}") +set(_artifact_path "${_version_detection_dir}/${_artifact_bin}") +set(_new_artifact_bin "otelcol-sumo${_bin_ext}") +set(_new_artifact_path "${_version_detection_dir}/${_new_artifact_bin}") + +if(NOT EXISTS "${_new_artifact_path}") + # Construct download command + set(_cmd "${GH_PROGRAM}") + set(_args_str "run download -R ${_gh_slug} ${_gh_workflow}") + set(_args_str "${_args_str} -n ${_artifact_bin}") + separate_arguments(_args NATIVE_COMMAND ${_args_str}) + + # Create the version_detection directory + make_directory("${_version_detection_dir}") + + message(STATUS "Setting working directory: ${_version_detection_dir}") + message(STATUS "Running download command: ${_cmd} ${_args_str}") + + # Execute download command + execute_process(COMMAND "${_cmd}" ${_args} + WORKING_DIRECTORY ${_version_detection_dir} + COMMAND_ERROR_IS_FATAL ANY) + + # Rename downloaded artifact to otelcol-sumo + file(RENAME ${_artifact_path} ${_new_artifact_path}) +endif() + +# Detect version +detect_version("${_new_artifact_bin}" "${_version_detection_dir}")