diff --git a/.github/workflows/build_assets.yml b/.github/workflows/build_assets.yml new file mode 100644 index 00000000..b6629bd9 --- /dev/null +++ b/.github/workflows/build_assets.yml @@ -0,0 +1,164 @@ +--- +name: Build Compiled Assets + +on: + workflow_call: + inputs: + release: + type: boolean + default: false + description: "Attach artifacts to a release" + +jobs: + build_assets: + name: Build packages - ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: true + matrix: + include: + - os: macos-latest + TARGET: macos + # currently, wrapt pulls the arm64 version instead of the universal one, so the below is a hack + CMD_REQS: > + mkdir -p pip-packages && cd pip-packages && pip wheel --no-cache-dir --no-binary tree_sitter,ijson,charset_normalizer,PyYAML .. && + rm $(ls | grep wrapt) && pip download wrapt --platform=universal2 --only-binary=:all: && pip install $(ls | grep wrapt) --force-reinstall && cd .. && + pip install --no-deps --no-index --find-links=pip-packages pip-packages/* + CMD_BUILD: > + STATICCODECOV_LIB_PATH=$(find build/ -maxdepth 1 -type d -name 'lib.*' -print -quit | xargs -I {} sh -c "find {} -type f -name 'staticcodecov*' -print -quit | sed 's|^./||'") && + pyinstaller --add-binary ${STATICCODECOV_LIB_PATH}:. --copy-metadata codecov-cli --hidden-import staticcodecov_languages --target-arch universal2 -F codecov_cli/main.py && + mv dist/main dist/codecovcli_macos && + lipo -archs dist/codecovcli_macos | grep 'x86_64 arm64' + OUT_FILE_NAME: codecovcli_macos + ASSET_MIME: application/octet-stream + + - os: ubuntu-22.04 + TARGET: ubuntu + CMD_REQS: > + pip install -r requirements.txt && pip install . + CMD_BUILD: > + STATICCODECOV_LIB_PATH=$(find build/ -maxdepth 1 -type d -name 'lib.*' -print -quit | xargs -I {} sh -c "find {} -type f -name 'staticcodecov*' -print -quit | sed 's|^./||'") && + pyinstaller --add-binary ${STATICCODECOV_LIB_PATH}:. --copy-metadata codecov-cli --hidden-import staticcodecov_languages -F codecov_cli/main.py && + cp ./dist/main ./dist/codecovcli_linux + OUT_FILE_NAME: codecovcli_linux + ASSET_MIME: application/octet-stream + + - os: windows-latest + TARGET: windows + CMD_REQS: > + pip install -r requirements.txt && pip install . + CMD_BUILD: > + pyinstaller --add-binary "build\lib.win-amd64-cpython-311\staticcodecov_languages.cp311-win_amd64.pyd;." --copy-metadata codecov-cli --hidden-import staticcodecov_languages -F codecov_cli\main.py && + Copy-Item -Path ".\dist\main.exe" -Destination ".\dist\codecovcli_windows.exe" + OUT_FILE_NAME: codecovcli_windows.exe + ASSET_MIME: application/vnd.microsoft.portable-executable + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python 3.11 + uses: actions/setup-python@v3 + with: + python-version: "3.11" + + - name: Install dependencies + run: | + cd codecov-cli + ${{matrix.CMD_REQS}} + python setup.py build + + - name: Install pyinstaller + run: pip install pyinstaller + + - name: Build with pyinstaller for ${{matrix.TARGET}} + run: cd codecov-cli && ${{matrix.CMD_BUILD}} + + - name: Upload a Build Artifact + uses: actions/upload-artifact@v4 + if: inputs.release == false + with: + name: ${{ matrix.OUT_FILE_NAME }} + path: ./codecov-cli/dist/${{ matrix.OUT_FILE_NAME }} + + - name: Get auth token + if: inputs.release == true + id: token + uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 + with: + app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} + private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} + + - name: Upload Release Asset + if: inputs.release == true + id: upload-release-asset + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ steps.token.outputs.token }} + file: ./codecov-cli/dist/${{ matrix.OUT_FILE_NAME }} + asset_name: ${{ matrix.OUT_FILE_NAME }} + tag: ${{ github.ref }} + overwrite: true + + build_assets_alpine_arm: + name: Build assets - Alpine and ARM + runs-on: ubuntu-latest + strategy: + matrix: + include: + - distro: "python:3.11-alpine3.18" + arch: arm64 + distro_name: alpine + - distro: "python:3.11-alpine3.18" + arch: x86_64 + distro_name: alpine + - distro: "python:3.11-bullseye" + arch: arm64 + distro_name: linux + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + with: + platforms: ${{ matrix.arch }} + + - name: Run in Docker + run: | + docker run \ + --rm \ + -v $(pwd):/${{ github.workspace }} \ + -w ${{ github.workspace }} \ + --platform linux/${{ matrix.arch }} \ + ${{ matrix.distro }} \ + ./codecov-cli/scripts/build_${{ matrix.distro_name }}_arm.sh ${{ matrix.distro_name }}_${{ matrix.arch }} + + - name: Upload a Build Artifact + uses: actions/upload-artifact@v4 + if: inputs.release == false + with: + name: codecovcli_${{ matrix.distro_name }}_${{ matrix.arch }} + path: ./codecov-cli/dist/codecovcli_${{ matrix.distro_name }}_${{ matrix.arch }} + + - name: Get auth token + if: inputs.release == true + id: token + uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 + with: + app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} + private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} + + - name: Upload Release Asset + if: inputs.release == true + id: upload-release-asset + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ steps.token.outputs.token }} + file: ./codecov-cli/dist/codecovcli_${{ matrix.distro_name }}_${{ matrix.arch }} + asset_name: codecovcli_${{ matrix.distro_name }}_${{ matrix.arch }} + tag: ${{ github.ref }} + overwrite: true diff --git a/.github/workflows/build_for_pypi.yml b/.github/workflows/build_for_pypi.yml new file mode 100644 index 00000000..3d82e104 --- /dev/null +++ b/.github/workflows/build_for_pypi.yml @@ -0,0 +1,71 @@ +--- +name: Build for PyPi + +on: + workflow_call: + inputs: + publish: + type: boolean + default: false + description: "Build for PyPi" + +jobs: + build_src_for_pypi: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + submodules: true + + - name: Install dependencies + run: | + pip install build + + - name: Build src dist + run: | + cd codecov-cli + python -m build --sdist + env: + PIP_CONSTRAINT: requirements.txt + + - name: Store the distribution packages + uses: actions/upload-artifact@v4 + with: + name: cibw-sdist + path: ./**/*.tar.gz + + build_dist_for_pypi: + needs: + - build_src_for_pypi + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + - macos-13 + - macos-latest + - ubuntu-24.04-arm + - ubuntu-latest + - windows-latest + steps: + - name: Download the sdist + uses: actions/download-artifact@v4 + with: + name: cibw-sdist + + - name: Get sdist filename + id: get-sdist + run: | + echo "sdist_filename=$(ls codecov-cli/dist/)" >> "${GITHUB_OUTPUT}" + shell: bash + + - name: Build wheels + uses: pypa/cibuildwheel@v2.22.0 + with: + package-dir: codecov-cli/dist/${{ steps.get-sdist.outputs.sdist_filename }} + + - name: Store the distribution packages + uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }} + path: ./wheelhouse/*.whl diff --git a/.github/workflows/ci-job.yml b/.github/workflows/ci-job.yml index 1fdf120b..496676b7 100644 --- a/.github/workflows/ci-job.yml +++ b/.github/workflows/ci-job.yml @@ -1,6 +1,3 @@ -# This workflow will install Python dependencies, run tests and lint with a variety of Python versions -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - name: CLI CI Job on: @@ -17,10 +14,12 @@ jobs: with: submodules: true fetch-depth: 2 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: "3.12" + - name: Install dependencies run: | cd codecov-cli @@ -28,6 +27,7 @@ jobs: pip install -r requirements.txt python -m pip install -e . pip install -r tests/requirements.txt + - name: Test with pytest run: | cd codecov-cli diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 820f23b7..477afaf1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: true + - name: Check linting with ruff run: | make lint @@ -28,18 +29,22 @@ jobs: - uses: actions/checkout@v4 with: submodules: true + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: "3.12" + - name: Install dependencies run: | python -m pip install --upgrade pip python -m pip install -e codecov-cli python -m pip install -e prevent-cli + - name: Run command_dump run: | ./command_dump.py + - name: Detect changes on commit run: | if [ -n "$(git diff codecov-cli/codecovcli_commands prevent-cli/preventcli_commands)" ]; then @@ -56,16 +61,20 @@ jobs: with: submodules: true fetch-depth: 2 + - uses: actions/setup-python@v5 with: python-version: "3.12" + - name: Install CLI # todo: update this to dogfood prevent cli, maybe try both? run: | pip install codecov-cli + - name: Create commit in codecov run: | codecovcli create-commit -t ${{ secrets.CODECOV_TOKEN }} --git-service github + - name: Create commit report in codecov run: | codecovcli create-report -t ${{ secrets.CODECOV_TOKEN }} --git-service github @@ -82,27 +91,32 @@ jobs: with: submodules: true fetch-depth: 2 + - name: Set up Python ${{matrix.python-version}} uses: actions/setup-python@v5 with: python-version: "${{matrix.python-version}}" + - name: Install dependencies run: | python -m pip install --upgrade pip python -m pip install -e codecov-cli python -m pip install -e prevent-cli pip install -r codecov-cli/tests/requirements.txt + - name: Test with pytest run: | cd codecov-cli pytest --cov --junitxml=${{matrix.os}}-${{matrix.python-version}}junit.xml env: CODECOV_ENV: test + - name: Dogfooding codecov-cli if: ${{ !github.event.pull_request.head.repo.fork && github.repository_owner == 'getsentry' }} run: | codecovcli -v do-upload --fail-on-error -t ${{ secrets.CODECOV_TOKEN }} --plugin pycoverage --flag python${{matrix.python-version}} --flag codecovcli codecovcli do-upload --report-type test_results --fail-on-error -t ${{ secrets.CODECOV_TOKEN }} --plugin pycoverage --flag python${{matrix.python-version}} --flag codecovcli + - name: Dogfooding sentry-prevent-cli if: ${{ !github.event.pull_request.head.repo.fork && github.repository_owner == 'getsentry' }} run: | diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml new file mode 100644 index 00000000..715c131d --- /dev/null +++ b/.github/workflows/create_release.yml @@ -0,0 +1,44 @@ +name: Create CLI Release + +on: + pull_request: + branches: + - main + types: [closed] + +jobs: + create-release: + if: ${{ github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/') && github.repository_owner == 'getsentry' }} + name: Create Github Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + + - id: get-release-vars + name: Configure Release Vars + run: | + release_version=v$(grep -E "version = \"[0-9]+\.[0-9]+\.[0-9]+\"" pyproject.toml | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+") + previous_version=$(git tag --sort=-creatordate | head -n 2 | tail -n 1) + echo "release_version=$release_version" + echo "previous_version=$previous_version" + + echo "release_version=$release_version" >> "$GITHUB_OUTPUT" + echo "previous_version=$previous_version" >> "$GITHUB_OUTPUT" + + - name: Get auth token + id: token + uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 + with: + app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} + private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} + + # todo: potentially switch to https://github.com/getsentry/action-prepare-release once set up with craft + - name: Create GitHub Release + env: + GITHUB_TOKEN: ${{ steps.token.outputs.token }} + run: | + gh release create ${{ steps.get-release-vars.outputs.release_version }} --title "Release ${{ steps.get-release-vars.outputs.release_version }}" --notes "Autogenerated for ${{ steps.get-release-vars.outputs.release_version }}. Created for ${{ github.event.pull_request.html_url }}" --generate-notes --notes-start-tag ${{steps.get-release-vars.outputs.previous_version}} --target ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/create_release_pr.yml b/.github/workflows/create_release_pr.yml new file mode 100644 index 00000000..33267a42 --- /dev/null +++ b/.github/workflows/create_release_pr.yml @@ -0,0 +1,53 @@ +name: Create CLI Release PR + +on: + workflow_dispatch: + inputs: + versionName: + description: 'Name of version (ie 23.9.5)' + required: true + +jobs: + create-release-pr: + name: Create PR + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set sentry-release-bot's Git info + run: | + git config --global user.email "180476844+sentry-release-bot[bot]@users.noreply.github.com" + git config --global user.name "sentry-release-bot[bot]" + + - name: Create release branch + run: git checkout -b release/${{ github.event.inputs.versionName }} + + - name: Update version and push + id: make-commit + run: | + cd codecov-cli + sed -i 's/version\ =\ "[0-9]\+\.[0-9]\+\.[0-9]\+"/version\ =\ "${{ github.event.inputs.versionName }}"/g' pyproject.toml + git add pyproject.toml + git commit --message "Prepare release ${{ github.event.inputs.versionName }}" + echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + git push origin release/${{ github.event.inputs.versionName }} + + - name: Get auth token + id: token + uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 + with: + app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} + private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} + + - name: Create pull request into main + uses: thomaseizinger/create-pull-request@1.3.1 + with: + github_token: ${{ steps.token.outputs.token }} + head: release/${{ github.event.inputs.versionName }} + base: main + title: Release ${{ github.event.inputs.versionName }} + reviewers: ${{ github.event.issue.user.login }} + body: | + Release PR for ${{ github.event.inputs.versionName }} + I've updated the version name and committed: ${{ steps.make-commit.outputs.commit }}. diff --git a/.github/workflows/release_flow.yml b/.github/workflows/release_flow.yml new file mode 100644 index 00000000..ce811ac5 --- /dev/null +++ b/.github/workflows/release_flow.yml @@ -0,0 +1,78 @@ +name: Build and Publish CLI Release + +on: + release: + types: + - created + +jobs: + build_for_pypi: + permissions: + id-token: write # This is required for requesting the JWT + contents: read # This is required for actions/checkout + uses: ./.github/workflows/build_for_pypi.yml + with: + publish: false # todo: back to true when tested + secrets: inherit + + buildassets: + name: Build packages + uses: ./.github/workflows/build_assets.yml + with: + release: false # todo: back to true when tested + secrets: inherit + + publish_to_pypi: + needs: + - build_for_pypi + permissions: + id-token: write # This is required for OIDC + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/codecov-cli + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + path: dist/ + pattern: cibw-* + + - name: Display and move artifacts + run: | + ls -alrt */*/* + mv */*/*/* dist/ + mv */*/* dist/ + echo "Moved files" + ls -alrt */* + echo "Deleting empty directories" + find . -empty -type d -delete + ls -alrt */* + + - name: Publish package to PyPi + uses: pypa/gh-action-pypi-publish@release/v1 + with: + verbose: true + + publish_release: + name: Publish release + needs: [buildassets, publish_to_pypi] + runs-on: ubuntu-latest + permissions: + contents: 'read' + id-token: 'write' + steps: + - id: 'auth' + name: 'Authenticate to Google Cloud' + uses: 'google-github-actions/auth@v1.0.0' + with: + create_credentials_file: 'true' + workload_identity_provider: ${{ secrets.CODECOV_GCP_WIDP }} + service_account: ${{ secrets.CODECOV_GCP_WIDSA }} + + # Publish the release tag to a Pub/Sub topic + - name: Publish a message to a Pub/Sub topic + env: + CLOUDSDK_CORE_PROJECT: ${{ secrets.GCLOUD_UPLOADER_PROJECT_ID }} + run: | + gcloud pubsub topics publish ${{ secrets.GCLOUD_UPLOADER_PUBSUB_TOPIC }} --message '{"release":"'"${{ github.ref_name }}"'", "latest":true}' diff --git a/codecov-cli/scripts/build_alpine_arm.sh b/codecov-cli/scripts/build_alpine_arm.sh index 688c3ab0..20f72770 100755 --- a/codecov-cli/scripts/build_alpine_arm.sh +++ b/codecov-cli/scripts/build_alpine_arm.sh @@ -1,4 +1,5 @@ #!/bin/sh +cd codecov-cli apk add musl-dev build-base pip install -r requirements.txt pip install . diff --git a/codecov-cli/scripts/build_linux_arm.sh b/codecov-cli/scripts/build_linux_arm.sh index 58b4625f..3dab760b 100755 --- a/codecov-cli/scripts/build_linux_arm.sh +++ b/codecov-cli/scripts/build_linux_arm.sh @@ -1,4 +1,5 @@ #!/bin/sh +cd codecov-cli apt install build-essential pip install -r requirements.txt pip install .