diff --git a/.github/workflows/algolia-crawler.yml b/.github/workflows/algolia-crawler.yml deleted file mode 100644 index 6431906b7716..000000000000 --- a/.github/workflows/algolia-crawler.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Algolia Indexer - -on: - push: - branches: [ 'develop' ] - paths: - - 'docs/**' - - '.github/workflows/algolia-crawler.yml' - -jobs: - algolia_indexer: - runs-on: ubuntu-latest - env: - APPLICATION_ID: "M7RXTHKYPM" - API_KEY: ${{ secrets.ALGOLIA_ADMIN_API_KEY }} - INDEX_NAME: "ghaction" - CONFIG: > - {"index_name": "ghaction", - "stop_urls": ["https://docs.humansignal.com/guide/index.html", "https://docs.humansignal.com/guide/notion-faq.html", "https://labelstud.io/sdk/index.html"], - "selectors_exclude": [".home-page-index"], - "start_urls": ["https://docs.humansignal.com/guide", "https://docs.humansignal.com/templates", "https://docs.humansignal.com/tags", "https://labelstud.io/sdk/"], - "selectors": { - "lvl0": ".content h1, .ResourcesBannerHeading", - "lvl1": ".content h2, .ResourcesContent h2", - "lvl2": ".content h3, .ResourcesContent h3", - "lvl3": ".content h4, .ResourcesContent h4", - "lvl4": ".content h5, .ResourcesContent h5", - "lvl5": ".content h6, .ResourcesContent h6", - "content": ".content-markdown > *" - }} - name: Index Algolia - steps: - - name: Algolia Docsearch Action - id: algolia - uses: adapttive/algolia-docsearch-action@1.1.1 diff --git a/.github/workflows/bandit.yml b/.github/workflows/bandit.yml deleted file mode 100644 index edd2fe8bb05c..000000000000 --- a/.github/workflows/bandit.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: "Bandit" - -on: - workflow_call: - inputs: - head_sha: - required: true - type: string - -env: - BANDIT_VERSION: 1.7.5 - PROJECT_PATH: 'label_studio/' - REPORT_PATH: 'bandit_results/bandit_security_report.txt' - ACTIONS_STEP_DEBUG: '${{ secrets.ACTIONS_STEP_DEBUG }}' - -jobs: - bandit: - name: "Bandit" - timeout-minutes: 5 - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Checkout - uses: actions/checkout@v3 - with: - ref: ${{ inputs.head_sha }} - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - - name: Install Bandit - run: | - pip install bandit==$BANDIT_VERSION - - - name: Run Bandit - run: | - mkdir -p bandit_results - touch ${{ env.REPORT_PATH }} - bandit -r $PROJECT_PATH -o ${{ env.REPORT_PATH }} -f 'txt' -ll - - - name: Print scan results - if: always() - run: cat ${{ env.REPORT_PATH }} - - - uses: actions/upload-artifact@v3 - if: always() - with: - name: Security check results - path: ${{ env.REPORT_PATH }} diff --git a/.github/workflows/bump-helm-chart.yml b/.github/workflows/bump-helm-chart.yml deleted file mode 100644 index d554df4824c5..000000000000 --- a/.github/workflows/bump-helm-chart.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: "Bump Helm Chart" - -on: - workflow_call: - inputs: - docker_image_version: - description: 'Label Studio Docker Image version' - type: string - required: true - workflow_dispatch: - inputs: - docker_image_version: - description: 'Label Studio Docker Image version' - type: string - required: true - -env: - HELM_CHART_REPO_NAME: 'charts' - LS_CHART_PATH: 'heartex/label-studio/Chart.yaml' - -jobs: - bump-helm-chart: - name: "Bump Helm Chart" - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Configure git - shell: bash - run: | - set -xeuo pipefail - git config --global user.name 'robot-ci-heartex' - git config --global user.email 'robot-ci-heartex@users.noreply.github.com' - - - name: Checkout - uses: actions/checkout@v3 - with: - repository: "${{ github.repository_owner }}/${{ env.HELM_CHART_REPO_NAME }}" - token: ${{ secrets.GIT_PAT }} - - - name: Edit Label Studio Chart - env: - LS_CHART_PATH: ${{ env.LS_CHART_PATH }} - DOCKER_IMAGE_VERSION: ${{ inputs.docker_image_version }} - run: | - regex="^version:[[:space:]]*([0-9-]+).([0-9-]+).([0-9-]+)" - if [[ $(cat ${LS_CHART_PATH} | grep '^version:') =~ $regex ]]; then - minor_version=$((${BASH_REMATCH[3]} + 1)) - new_version="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${minor_version}" - sed -i "s#^version:.*#version: ${new_version}#g" "${LS_CHART_PATH}" - fi - - sed -i "s#^appVersion:.*#appVersion: \"${DOCKER_IMAGE_VERSION}\"#g" "${LS_CHART_PATH}" - cat "${LS_CHART_PATH}" - - - name: Commit and Push - run: | - git add "${LS_CHART_PATH}" - git commit -m 'Bump Label Studio to ${{ inputs.docker_image_version }}' -m 'Workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' - git push origin diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml deleted file mode 100644 index 3a8124545693..000000000000 --- a/.github/workflows/codespell.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Codespell - -on: - push: - branches: [develop,master] - pull_request: - branches: [develop,master] - -jobs: - codespell: - name: Check for spelling errors - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Codespell - uses: codespell-project/actions-codespell@v2 diff --git a/.github/workflows/delete_pr_branch.yml b/.github/workflows/delete_pr_branch.yml deleted file mode 100644 index e1bbd55d8ef5..000000000000 --- a/.github/workflows/delete_pr_branch.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: "Delete PR branch" - -on: - pull_request_target: - types: - - closed - -jobs: - delete-branch: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Delete branch - uses: actions/github-script@v6 - if: startsWith(github.event.pull_request.head.ref, 'fb-') - with: - script: | - const { repo, owner } = context.repo; - await github.rest.git.deleteRef({ - owner, - repo, - ref: 'heads/${{ github.event.pull_request.head.ref }}', - }); - console.log(`Branch ${{ github.event.pull_request.head.ref }} is deleted`) diff --git a/.github/workflows/docker-build-ontop.yml b/.github/workflows/docker-build-ontop.yml deleted file mode 100644 index 5dc75c0bc30f..000000000000 --- a/.github/workflows/docker-build-ontop.yml +++ /dev/null @@ -1,106 +0,0 @@ -name: "Docker build & push OnTop" - -on: - workflow_call: - inputs: - base_docker_image_version: - description: 'Base Docker Image version' - type: string - required: true - tags: - description: 'Comma separated tags' - type: string - required: true - dockerfile_path: - description: "Dockerfile path" - type: string - required: true - ref: - description: "Dockerfile ref or sha" - type: string - required: true - workflow_dispatch: - inputs: - base_docker_image_version: - description: 'Base Docker Image version' - type: string - required: true - tags: - description: 'Comma separated tags' - type: string - required: true - dockerfile_path: - description: "Dockerfile path" - type: string - required: true - ref: - description: "Dockerfile ref or sha" - type: string - required: true - default: develop - -env: - IMAGE_NAME: "${{ vars.DOCKERHUB_ORG }}/label-studio" - -jobs: - docker_build_and_push: - name: "Docker image" - timeout-minutes: 90 - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Checkout - uses: actions/checkout@v3 - with: - submodules: 'recursive' - ref: ${{ inputs.ref }} - fetch-depth: 0 - - - name: Calculate Docker tags - id: calculate-docker-tags - uses: actions/github-script@v6 - env: - TAGS: ${{ inputs.tags }} - IMAGE_NAME: ${{ env.IMAGE_NAME }} - with: - script: | - const raw_tags_input = process.env.TAGS; - const image_name = process.env.IMAGE_NAME; - - const tags = raw_tags_input.split(',').map(x => x.trim()); - const docker_tags = tags.map(x => `${image_name}:${x}`).join(','); - console.log(docker_tags); - core.setOutput("docker-tags", docker_tags); - - - name: Edit Dockerfile - env: - BASE_DOCKER_IMAGE_VERSION: ${{ inputs.base_docker_image_version }} - DOCKERFILE_PATH: ${{ inputs.dockerfile_path }} - run: | - sed -i "s#^FROM .*#FROM ${IMAGE_NAME}:${BASE_DOCKER_IMAGE_VERSION}#g" "${DOCKERFILE_PATH}" - cat "${DOCKERFILE_PATH}" - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.9.1 - - - name: Login to DockerHub - uses: docker/login-action@v2.2.0 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Push Docker image - uses: docker/build-push-action@v4.1.1 - id: docker_build_and_push - with: - context: . - file: ${{ inputs.dockerfile_path }} - platforms: linux/amd64,linux/arm64 - push: true - tags: ${{ steps.calculate-docker-tags.outputs.docker-tags }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.github/workflows/docker-build-ubi.yml b/.github/workflows/docker-build-ubi.yml deleted file mode 100644 index 73c985fdd9ec..000000000000 --- a/.github/workflows/docker-build-ubi.yml +++ /dev/null @@ -1,175 +0,0 @@ -name: "Docker build & push UBI" - -on: - workflow_call: - inputs: - sha: - required: true - type: string - version: - required: true - type: string - -env: - DOCKER_CLI_EXPERIMENTAL: enabled - IMAGE_NAME: "${{ vars.DOCKERHUB_ORG }}/label-studio" - PREFLIGHT_REPO: quay.io/opdev/preflight:stable - DOCKER_CONFIG_PATH: /home/runner/.docker/config.json - -jobs: - docker_build_and_push: - name: "Docker image" - timeout-minutes: 45 - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Checkout - uses: actions/checkout@v3 - with: - submodules: 'recursive' - ref: ${{ inputs.sha }} - fetch-depth: 0 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.9.1 - - - name: Login to RedHat Registry - uses: docker/login-action@v2.2.0 - with: - registry: quay.io - username: ${{ secrets.REDHAT_REGISTRY_LOGIN }} - password: ${{ secrets.REDHAT_REGISTRY_PASSWORD }} - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - - name: Create version_.py - run: | - python3 $(pwd)/label_studio/core/version.py - cat $(pwd)/label_studio/core/version_.py - - - name: Download LaunchDarkly Community config - env: - LAUNCHDARKLY_COMMUNITY_SDK_KEY: ${{ secrets.LAUNCHDARKLY_COMMUNITY_SDK_KEY }} - LAUNCHDARKLY_DOWNLOAD_PATH: "label_studio/feature_flags.json" - run: | - set -xeuo pipefail - curl \ - --connect-timeout 30 \ - --retry 5 \ - --retry-delay 10 \ - -H "Authorization: $LAUNCHDARKLY_COMMUNITY_SDK_KEY" \ - "https://sdk.launchdarkly.com/sdk/latest-all" >"$LAUNCHDARKLY_DOWNLOAD_PATH" - if [ "$(jq 'has("flags")' <<< cat $LAUNCHDARKLY_DOWNLOAD_PATH)" = "true" ]; then - echo "feature_flags.json is valid" - else - echo "feature_flags.json is invalid" - cat $LAUNCHDARKLY_DOWNLOAD_PATH - exit 1 - fi - - - name: Check is latest tag needs to be updated - uses: actions/github-script@v6 - id: generate-tags - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const {repo, owner} = context.repo; - const newTag = '${{ inputs.version }}'; - const dockerHubImageName = '${{ env.IMAGE_NAME }}'; - const redHatImageName = 'quay.io/redhat-isv-containers/${{ secrets.REDHAT_MARKETPLACE_LS_PROJECT_ID }}'; - const regexp = '^[v]?([0-9]+)\.([0-9]+)\.([0-9]+)(\.post([0-9]+))?$'; - - function compareVersions(a, b) { - if (a[1] === b[1]) - if (a[2] === b[2]) - if (a[3] === b[3]) - return (+a[5] || -1) - (+b[5] || -1) - else - return +a[3] - b[3] - else - return +a[2] - b[2] - else - return +a[1] - b[1] - } - - const tags = await github.paginate( - github.rest.repos.listTags, - { - owner, - repo, - per_page: 100 - }, - (response) => response.data - ); - const rawTags = tags.map(e => e.name) - const filteredTags = rawTags.filter(e => e.match(regexp)) - const sortedTags = filteredTags - .map(e => e.match(regexp)) - .sort(compareVersions) - .reverse() - console.log('Sorted tags:') - console.log(sortedTags.map(e => e[0])) - - const newestVersion = sortedTags[0]; - console.log(`Newest tag: ${newestVersion[0]}`) - - let dockerHubUbuntuRawTags = [newTag]; - let dockerHubUbiRawTags = [`ubi_${newTag}`]; - let redHatUbiRawTags = [newTag]; - - - if (compareVersions(newTag.match(regexp), newestVersion) >= 0) { - console.log(`new tag ${newTag} is higher that all existing tags`) - console.log(dockerHubUbuntuRawTags) - dockerHubUbuntuRawTags.push('latest') - dockerHubUbiRawTags.push('ubi_latest') - redHatUbiRawTags.push('latest') - core.setOutput("latest", true); - } else { - console.log('not latest') - core.setOutput("latest", false); - } - - const ubuntuTags = dockerHubUbuntuRawTags.map(e => `${dockerHubImageName}:${e}`) - const redHatTags = redHatUbiRawTags.map(e => `${redHatImageName}:${e}`) - const ubiTags = redHatTags.concat( - dockerHubUbiRawTags.map(e => `${dockerHubImageName}:${e}`) - ) - - console.log('Ubuntu tags:') - console.log(ubuntuTags) - console.log('Ubi tags:') - console.log(ubiTags) - - core.setOutput("ubuntu-tags", ubuntuTags.join(',')); - core.setOutput("redhat-tags", redHatTags.join(',')); - core.setOutput("ubi-tags", ubiTags.join(',')); - - - name: Build and push ubi - uses: docker/build-push-action@v4.1.1 - id: docker_build_and_push_ubi - with: - context: . - file: Dockerfile.redhat - push: true - tags: ${{ steps.generate-tags.outputs.ubi-tags }} - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Run preflight and submit validation results to RedHat - shell: bash - run: | - docker pull ${{ env.PREFLIGHT_REPO }} - while IFS= read -d ',' image; do - docker run --rm -v ${{ env.DOCKER_CONFIG_PATH }}:${{ env.DOCKER_CONFIG_PATH }} \ - --env PFLT_DOCKERCONFIG=${{ env.DOCKER_CONFIG_PATH }} \ - --env PFLT_PYXIS_API_TOKEN=${{ secrets.REDHAT_MARKETPLACE_LS_PYXIS_TOKEN }} \ - --env PFLT_CERTIFICATION_PROJECT_ID=${{ secrets.REDHAT_MARKETPLACE_LS_PROJECT_ID }} \ - ${{ env.PREFLIGHT_REPO }} \ - check container "${image}" \ - --submit - done <<< '${{ steps.generate-tags.outputs.redhat-tags }},' diff --git a/.github/workflows/docker-release-promote.yml b/.github/workflows/docker-release-promote.yml deleted file mode 100644 index b74b937852ad..000000000000 --- a/.github/workflows/docker-release-promote.yml +++ /dev/null @@ -1,251 +0,0 @@ -name: "Docker release promote" - -on: - workflow_dispatch: - inputs: - release_tag: - description: "Release tag for promotion" - required: true - type: string - workflow_call: - inputs: - release_tag: - required: true - type: string - -env: - DOCKER_IMAGE_TAG_CHECK_NAME: "Docker image tag" - IMAGE_NAME: "${{ vars.DOCKERHUB_ORG }}/label-studio" - RELEASE_DOCKERFILE: "Dockerfile.release" - PREFLIGHT_REPO: "quay.io/opdev/preflight:stable" - DOCKER_CONFIG_PATH: "/home/runner/.docker/config.json" - LAUNCHDARKLY_DOWNLOAD_PATH: "feature_flags.json" - -jobs: - docker_release_retag: - name: "Docker image" - timeout-minutes: 90 - runs-on: ubuntu-latest - outputs: - image_version: ${{ steps.get_info.outputs.image_version }} - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Get an artifact from check suite - uses: actions/github-script@v6 - id: get_info - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const {repo, owner} = context.repo; - const check_runs = await github.paginate( - github.rest.checks.listForRef, - { - owner, - repo, - ref: 'tags/${{ inputs.release_tag }}', - status: "completed", - per_page: 100 - }, - (response) => response.data - ); - const check = check_runs.find(e => e.name === '${{ env.DOCKER_IMAGE_TAG_CHECK_NAME }}') - const details = JSON.parse(check.output.summary) - console.log(details) - core.setOutput("branch", details.branch); - core.setOutput("pretty_branch_name", details.pretty_branch_name); - core.setOutput("image_version", details.image_version); - core.setOutput("sha", details.sha); - - - name: Checkout - uses: actions/checkout@v3 - with: - ref: ${{ inputs.release_tag }} - - - name: Check is latest tag needs to be updated - uses: actions/github-script@v6 - id: generate-tags - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const {repo, owner} = context.repo; - const newTag = '${{ inputs.release_tag }}'; - const dockerHubImageName = '${{ env.IMAGE_NAME }}'; - const redHatImageName = 'quay.io/redhat-isv-containers/${{ secrets.REDHAT_MARKETPLACE_LS_PROJECT_ID }}'; - const regexp = '^[v]?([0-9]+)\.([0-9]+)\.([0-9]+)(\.post([0-9]+))?$'; - - function compareVersions(a, b) { - if (a[1] === b[1]) - if (a[2] === b[2]) - if (a[3] === b[3]) - return (+a[5] || -1) - (+b[5] || -1) - else - return +a[3] - b[3] - else - return +a[2] - b[2] - else - return +a[1] - b[1] - } - - const tags = await github.paginate( - github.rest.repos.listTags, - { - owner, - repo, - per_page: 100 - }, - (response) => response.data - ); - const rawTags = tags.map(e => e.name) - const filteredTags = rawTags.filter(e => e.match(regexp)) - const sortedTags = filteredTags - .map(e => e.match(regexp)) - .sort(compareVersions) - .reverse() - console.log('Sorted tags:') - console.log(sortedTags.map(e => e[0])) - - const newestVersion = sortedTags[0]; - console.log(`Newest tag: ${newestVersion[0]}`) - - let dockerHubUbuntuRawTags = [newTag]; - let dockerHubUbiRawTags = [`ubi_${newTag}`]; - let redHatUbiRawTags = [newTag]; - - - if (compareVersions(newTag.match(regexp), newestVersion) >= 0) { - console.log(`new tag ${newTag} is higher that all existing tags`) - console.log(dockerHubUbuntuRawTags) - dockerHubUbuntuRawTags.push('latest') - dockerHubUbiRawTags.push('ubi_latest') - redHatUbiRawTags.push('latest') - core.setOutput("latest", true); - } else { - console.log('not latest') - core.setOutput("latest", false); - } - - const ubuntuTags = dockerHubUbuntuRawTags.map(e => `${dockerHubImageName}:${e}`) - const redHatTags = redHatUbiRawTags.map(e => `${redHatImageName}:${e}`) - const ubiTags = redHatTags.concat( - dockerHubUbiRawTags.map(e => `${dockerHubImageName}:${e}`) - ) - - console.log('Ubuntu tags:') - console.log(ubuntuTags) - console.log('Ubi tags:') - console.log(ubiTags) - - core.setOutput("ubuntu-tags", ubuntuTags.join(',')); - core.setOutput("redhat-tags", redHatTags.join(',')); - core.setOutput("ubi-tags", ubiTags.join(',')); - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' - - - name: Create version_.py - run: | - python3 $(pwd)/label_studio/core/version.py - cat $(pwd)/label_studio/core/version_.py - - - name: Download feature flags - env: - LAUNCHDARKLY_COMMUNITY_SDK_KEY: ${{ secrets.LAUNCHDARKLY_COMMUNITY_SDK_KEY }} - run: | - set -xeuo pipefail - curl \ - --connect-timeout 30 \ - --retry 5 \ - --retry-delay 10 \ - -H "Authorization: $LAUNCHDARKLY_COMMUNITY_SDK_KEY" \ - "https://sdk.launchdarkly.com/sdk/latest-all" >"${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }}" - if [ "$(jq 'has("flags")' <<< cat ${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }})" = "true" ]; then - echo "feature_flags.json is valid" - else - echo "feature_flags.json is invalid" - cat ${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }} - exit 1 - fi - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.9.1 - - - name: Login to DockerHub - uses: docker/login-action@v2.2.0 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Login to RedHat Registry - uses: docker/login-action@v2.2.0 - with: - registry: quay.io - username: ${{ secrets.REDHAT_REGISTRY_LOGIN }} - password: ${{ secrets.REDHAT_REGISTRY_PASSWORD }} - - - name: Prepare Release Dockerfile - id: release_dockerfile - env: - VERSION_OVERRIDE: ${{ inputs.release_tag }} - BRANCH_OVERRIDE: ${{ steps.get_info.outputs.branch }} - shell: bash - run: | - set -euo pipefail ${ACTIONS_STEP_DEBUG:+-x} - - release_dir=release_${{ inputs.release_tag }} - echo "release_dir=$release_dir" >> $GITHUB_OUTPUT - mkdir -p $release_dir - cp label_studio/core/version_.py $release_dir/ - cp ${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }} $release_dir/ - cd $release_dir - - cat < "${{ env.RELEASE_DOCKERFILE }}" - FROM ${{ env.IMAGE_NAME }}:${{ steps.get_info.outputs.image_version }} - COPY --chown=54546:0 version_.py /label-studio/label_studio/core/version_.py - COPY --chown=54546:0 ${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }} /label-studio/label_studio/feature_flags.json - EOF - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Build and Push Release Ubuntu Docker image - uses: docker/build-push-action@v4.1.1 - id: docker_build - with: - context: ${{ steps.release_dockerfile.outputs.release_dir }} - file: ${{ steps.release_dockerfile.outputs.release_dir }}/${{ env.RELEASE_DOCKERFILE }} - push: true - tags: ${{ steps.generate-tags.outputs.ubuntu-tags }} - cache-from: type=gha - cache-to: type=gha,mode=max - platforms: linux/amd64,linux/arm64 - - - name: Copy compiled static from builded Docker image - run: | - # Usually it takes 10-20 sec so the image becomes available - sleep 10s - docker pull ${{ env.IMAGE_NAME }}:${{ inputs.release_tag }} - docker run -v ${{ github.workspace }}:/workspace:rw -u root --rm ${{ env.IMAGE_NAME }}:${{ inputs.release_tag }} cp -r /label-studio/label_studio/frontend/ /workspace/label_studio/ - - - name: Create Sentry release @ backend - uses: getsentry/action-release@v1 - continue-on-error: true - env: - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - SENTRY_ORG: ${{ secrets.SENTRY_ORG }} - with: - version: label-studio@${{ inputs.release_tag }} - projects: opensource-v1-backend - - - name: Create Sentry release @ frontend - uses: getsentry/action-release@v1 - continue-on-error: true - env: - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - SENTRY_ORG: ${{ secrets.SENTRY_ORG }} - with: - version: label-studio@${{ inputs.release_tag }} - projects: opensource-v1-frontend - sourcemaps: label_studio/frontend/dist diff --git a/.github/workflows/feature-flags-update.yml b/.github/workflows/feature-flags-update.yml deleted file mode 100644 index 2602333f2126..000000000000 --- a/.github/workflows/feature-flags-update.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: "Update Feature Flags" - -on: - schedule: - - cron: '0 6 * * 1-5' - workflow_call: - inputs: - ref: - default: develop - required: true - type: string - workflow_dispatch: - inputs: - ref: - description: "Ref" - default: develop - required: true - type: string - -env: - LAUNCHDARKLY_DOWNLOAD_PATH: "label_studio/feature_flags.json" - FEATURE_FLAGS_COMMIT_MESSAGE: "ci: Update Feature Flags" - -jobs: - commit-feature-flags: - name: "Commit Feature Flags" - - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Configure git - shell: bash - run: | - set -xeuo pipefail - git config --global user.name 'robot-ci-heartex' - git config --global user.email 'robot-ci-heartex@users.noreply.github.com' - - - name: Checkout - uses: actions/checkout@v3 - with: - token: ${{ secrets.GIT_PAT }} - fetch-depth: 1 - ref: ${{ inputs.ref }} - - - name: Download feature flags - env: - LAUNCHDARKLY_COMMUNITY_SDK_KEY: ${{ secrets.LAUNCHDARKLY_COMMUNITY_SDK_KEY }} - run: | - set -xeuo pipefail - curl \ - --connect-timeout 30 \ - --retry 5 \ - --retry-delay 10 \ - -H "Authorization: $LAUNCHDARKLY_COMMUNITY_SDK_KEY" \ - "https://sdk.launchdarkly.com/sdk/latest-all" | jq >"${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }}" - if [ "$(jq 'has("flags")' <<< cat ${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }})" = "true" ]; then - echo "feature_flags.json is valid" - else - echo "feature_flags.json is invalid" - cat ${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }} - exit 1 - fi - - - name: Commit and Push - run: | - git add "${{ env.LAUNCHDARKLY_DOWNLOAD_PATH }}" - git status -s - git commit -m '${{ env.FEATURE_FLAGS_COMMIT_MESSAGE }}' -m 'Workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' || true - git push origin HEAD diff --git a/.github/workflows/ff-command.yml b/.github/workflows/ff-command.yml deleted file mode 100644 index 87e24a38bc4a..000000000000 --- a/.github/workflows/ff-command.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: "/ff command" - -on: - repository_dispatch: - types: [ ff-command ] - -concurrency: - group: ${{ github.workflow }}-${{ github.event.client_payload.github.payload.issue.number }}-${{ github.event.client_payload.slash_command.command }}-${{ github.event.client_payload.slash_command.args.unnamed.arg1 || github.event.client_payload.slash_command.args.all }} - -jobs: - - update-prepare: - name: "Update: Prepare" - if: github.event.client_payload.slash_command.args.unnamed.arg1 == 'update' - runs-on: ubuntu-latest - timeout-minutes: 1 - steps: - - name: Update comment - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - - update-update-ff: - name: "Update: Update Feature Flags" - if: github.event.client_payload.slash_command.args.unnamed.arg1 == 'update' - needs: - - update-prepare - uses: ./.github/workflows/feature-flags-update.yml - with: - ref: ${{ github.event.client_payload.pull_request.head.ref }} - secrets: inherit - - update-update-comment: - name: "Update: Update Comment" - if: always() - needs: - - update-update-ff - runs-on: ubuntu-latest - timeout-minutes: 1 - steps: - - name: Get details - id: details - shell: bash - env: - PR_HEAD: ${{ github.event.client_payload.pull_request.head.ref }} - run: | - reaction='-1' - if [[ '${{ needs.update-update-ff.result }}' == 'success' ]]; then - reaction='+1' - fi - echo "reaction=${reaction}" >> $GITHUB_OUTPUT - - - name: Update comment - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - reactions: ${{ steps.details.outputs.reaction }} - - help: - if: ${{ github.event.client_payload.slash_command.args.unnamed.arg1 == 'help' || !contains(fromJson('["update"]'), github.event.client_payload.slash_command.args.unnamed.arg1) }} - runs-on: ubuntu-latest - timeout-minutes: 1 - steps: - - name: Update comment - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > Command | Description - > --- | --- - > /ff update | Update feature flags - reaction-type: hooray diff --git a/.github/workflows/follow-merge-sync-pr.yml b/.github/workflows/follow-merge-sync-pr.yml deleted file mode 100644 index f010182542ec..000000000000 --- a/.github/workflows/follow-merge-sync-pr.yml +++ /dev/null @@ -1,105 +0,0 @@ -name: 'Follow Merge: Sync PR LSE' - -on: - pull_request_target: - types: - - opened - - closed - - converted_to_draft - - ready_for_review - - synchronize - branches: - - develop - - 'lse-release/**' - paths-ignore: - - 'label_studio/frontend/**' - - 'docs/**' - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref }} - -env: - DOWNSTREAM_REPO: label-studio-enterprise - -jobs: - sync: - name: "Sync" - if: startsWith(github.head_ref, 'fb-') - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Check user's membership - uses: actions/github-script@v6 - id: check-membership - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const { repo, owner } = context.repo; - try { - return (await github.rest.orgs.getMembershipForUser({ - org: owner, - username: '${{ github.actor }}', - }))?.data?.state == "active"; - } catch (error) { - return false; - } - - - name: Notify user on failure - if: steps.check-membership.outputs.result == 'false' - uses: actions/github-script@v6 - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const { repo, owner } = context.repo; - const result = await github.rest.issues.createComment({ - owner, - repo, - issue_number: '${{ github.event.number }}', - body: [ - 'Hi @${{ github.actor }}!', - '', - `Unfortunately you don't have membership in ${owner} organization, your PR wasn't synced with ${owner}/${{ env.DOWNSTREAM_REPO }}.` - ].join('\n') - }); - - - name: Sync PR - uses: actions/github-script@v6 - if: steps.check-membership.outputs.result == 'true' - id: sync-pr - env: - TITLE: ${{ github.event.pull_request.title }} - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const { repo, owner } = context.repo; - const [pr_owner, pr_repo] = '${{ github.event.pull_request.head.repo.full_name || github.repository }}'.split('/'); - let event_action = '${{ github.event.action }}' - let commit_sha = '${{ github.event.pull_request.head.sha }}' - if (${{ github.event.pull_request.merged }}) { - event_action = 'merged' - commit_sha = '${{ github.sha }}' - } - const getCommitResponse = await github.rest.repos.getCommit({ - owner: pr_owner, - repo: pr_repo, - ref: commit_sha - }); - const result = await github.rest.repos.createDispatchEvent({ - owner: owner, - repo: '${{ env.DOWNSTREAM_REPO }}', - event_type: 'upstream_repo_update', - client_payload: { - branch_name: '${{ github.head_ref }}', - base_branch_name: '${{ github.base_ref }}', - repo_name: '${{ github.repository }}', - commit_sha : commit_sha, - title: process.env.TITLE, - html_url: '${{ github.event.pull_request.html_url }}', - actor: '${{ github.actor }}', - author_username: getCommitResponse.data.commit.author.name, - author_email: getCommitResponse.data.commit.author.email, - event_action: event_action - } - }); - return result diff --git a/.github/workflows/frontend-command.yml b/.github/workflows/frontend-command.yml deleted file mode 100644 index 05f007adb55d..000000000000 --- a/.github/workflows/frontend-command.yml +++ /dev/null @@ -1,142 +0,0 @@ -name: "/frontend command" - -on: - repository_dispatch: - types: [ frontend-command ] - -env: - NODE: '18' - -jobs: - build: - if: ${{ github.event.client_payload.slash_command.args.unnamed.arg1 == 'build' }} - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout on chat command - uses: actions/checkout@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - - - name: Setup node - uses: actions/setup-node@v3 - with: - node-version: "${{ env.NODE }}" - - - name: Get npm cache directory - id: npm-cache-dir - run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT - - - uses: actions/cache@v3 - name: Configure npm cache - id: npm-cache - with: - path: ${{ steps.npm-cache-dir.outputs.dir }} - key: ${{ env.CACHE_NAME_PREFIX }}-${{ runner.os }}-node-${{ env.NODE }} - restore-keys: | - ${{ runner.os }}-node-${{ env.NODE }}- - - - name: Get build - id: get_build - env: - GITHUB_TOKEN: ${{ secrets.GIT_PAT }} - REPO: ${{ github.event.client_payload.slash_command.args.unnamed.arg2 || 'all' }} - SHA: ${{ github.event.client_payload.slash_command.args.unnamed.arg3 || 'master' }} - run: | - set -xeuo pipefail - if [ "${REPO}" = "all" ]; then - node label_studio/frontend/get-build.js lsf | tee -a /tmp/output - grep 'Build link:' /tmp/output | cut -d":" -f2- >> /tmp/info_commit_msg - node label_studio/frontend/get-build.js dm | tee -a /tmp/output - grep 'Build link:' /tmp/output | cut -d":" -f2- >> /tmp/info_commit_msg - else - node label_studio/frontend/get-build.js "${REPO}" "${SHA}" | tee -a /tmp/output - grep 'Build link:' /tmp/output | cut -d":" -f2- >> /tmp/info_commit_msg - fi - - echo "commit_msg_file=$(cat /tmp/info_commit_msg)" >> $GITHUB_OUTPUT - echo "COMMIT_MSG_FILE<> $GITHUB_ENV - echo "$(cat /tmp/info_commit_msg)" >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - - name: Commit and push - id: commit_and_push - shell: bash - env: - REPO: ${{ github.event.client_payload.slash_command.args.unnamed.arg2 || 'all' }} - run: | - set -xeuo pipefail - - git config --global user.name '${{ github.event.client_payload.github.actor }}' - git config --global user.email '${{ github.event.client_payload.github.actor }}@users.noreply.github.com' - - git add -A - git status -s - if git diff-index --quiet HEAD; then - echo "changes=no" >> $GITHUB_OUTPUT - exit 0 - else - git commit -m "[frontend] Get build ${REPO}" -m 'Workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' - fi - git push origin HEAD - - - name: Add reaction to command comment on nothing to do - if: steps.commit_and_push.outputs.changes == 'no' - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > Already up-to-date. Nothing to commit. - > - > [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - reactions: "confused" - - - name: Add reaction to command comment on success - if: steps.commit_and_push.outputs.changes != 'no' - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > Successfully pushed new changes - > ${{ env.COMMIT_MSG_FILE }} - > - > [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - reactions: "+1" - - - name: Add reaction to command comment on failure - uses: peter-evans/create-or-update-comment@v3 - if: failure() - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > **Error**: failed to get build - > - > [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - reactions: "-1" - - help: - if: ${{ github.event.client_payload.slash_command.args.unnamed.arg1 == 'help' }} - runs-on: ubuntu-latest - timeout-minutes: 1 - steps: - - name: Update comment - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > Command | Description - > --- | --- - > /frontend build | Get build frontend static for all repos - > /frontend build lsf [sha] | Get build frontend static for ${{ github.repository_owner }}/label-studio-frontend only - > /frontend build dm [sha] | Get build frontend static for ${{ github.repository_owner }}/dm2 only - reaction-type: hooray diff --git a/.github/workflows/git-command.yml b/.github/workflows/git-command.yml deleted file mode 100644 index 0ace181a96a5..000000000000 --- a/.github/workflows/git-command.yml +++ /dev/null @@ -1,122 +0,0 @@ -name: "/git command" - -on: - repository_dispatch: - types: [ git-command ] - -concurrency: - group: ${{ github.workflow }}-${{ github.event.client_payload.github.payload.issue.number }}-${{ github.event.client_payload.slash_command.command }}-${{ github.event.client_payload.slash_command.args.unnamed.arg1 || github.event.client_payload.slash_command.args.all }} - -jobs: - merge: - if: ${{ github.event.client_payload.slash_command.args.unnamed.arg1 == 'merge' }} - runs-on: ubuntu-latest - timeout-minutes: 3 - steps: - - name: Checkout on chat command - uses: actions/checkout@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - fetch-depth: 0 - - - name: Check for merge conflict - id: check-conflict - env: - SLASH_COMMAND_ARG_BRANCH: ${{ github.event.client_payload.slash_command.args.unnamed.arg2 }} - shell: bash - run: | - set -xeuo pipefail - git config --global user.name '${{ github.event.client_payload.github.actor }}' - git config --global user.email '${{ github.event.client_payload.github.actor }}@users.noreply.github.com' - echo "merge_conflict=$(git merge-tree $(git merge-base HEAD origin/$SLASH_COMMAND_ARG_BRANCH) origin/$SLASH_COMMAND_ARG_BRANCH HEAD | egrep '<<<<<<<')" >> $GITHUB_OUTPUT - - - name: Add reaction to command comment on merge conflict - uses: peter-evans/create-or-update-comment@v3 - if: ${{ steps.check-conflict.outputs.merge_conflict }} - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > **Error**: Merge conflict detected, please resolve it using the command line. - > - > [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - reactions: "-1" - - - name: Merge branch into current branch - env: - SLASH_COMMAND_ARG_BRANCH: ${{ github.event.client_payload.slash_command.args.unnamed.arg2 }} - if: ${{ !steps.check-conflict.outputs.merge_conflict }} - id: commit_and_push - shell: bash - run: | - set -xeuo pipefail - git merge origin/$SLASH_COMMAND_ARG_BRANCH - if [ $(git cherry -v | wc -l) -ge 1 ]; then - echo "changes=yes" >> $GITHUB_OUTPUT - echo "last_commit_sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - echo "last_commit_msg=$(git log -1 --pretty='%s')" >> $GITHUB_OUTPUT - else - echo "changes=no" >> $GITHUB_OUTPUT - exit 0 - fi - git push origin HEAD - - - name: Add reaction to command comment on nothing to do - if: ${{ !steps.check-conflict.outputs.merge_conflict && steps.commit_and_push.outputs.changes == 'no' }} - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > Already up-to-date. Nothing to commit. - > - > [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - reactions: "confused" - - - name: Add reaction to command comment on success - if: ${{ !steps.check-conflict.outputs.merge_conflict && steps.commit_and_push.outputs.changes == 'yes' }} - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > Successfully pushed new changes: - > ${{ steps.commit_and_push.outputs.last_commit_msg }} (${{ steps.commit_and_push.outputs.last_commit_sha }}) - > - > [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - reactions: "+1" - - - name: Add reaction to command comment on failure - uses: peter-evans/create-or-update-comment@v3 - if: failure() - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > **Error**: failed to execute "${{ github.event.client_payload.slash_command.args.unnamed.arg1 }}" command - > - > [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) - reactions: "-1" - - help: - if: ${{ github.event.client_payload.slash_command.args.unnamed.arg1 == 'help' || !contains(fromJson('["merge", "arg2"]'), github.event.client_payload.slash_command.args.unnamed.arg1) }} - runs-on: ubuntu-latest - timeout-minutes: 1 - steps: - - name: Update comment - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > Command | Description - > --- | --- - > /git merge `branch` | Merge branch `branch` into current branch - reaction-type: hooray \ No newline at end of file diff --git a/.github/workflows/help-command.yml b/.github/workflows/help-command.yml deleted file mode 100644 index 3a8776d8ffba..000000000000 --- a/.github/workflows/help-command.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: "/help command" - -on: - repository_dispatch: - types: [ help-command ] -jobs: - help: - runs-on: ubuntu-latest - timeout-minutes: 1 - steps: - - name: Update comment if empty - if: ${{ github.event.client_payload.slash_command.args.all == '' }} - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GIT_PAT }} - repository: ${{ github.event.client_payload.github.payload.repository.full_name }} - comment-id: ${{ github.event.client_payload.github.payload.comment.id }} - body: | - > Command | Description - > --- | --- - > /frontend [\ ...] | Actions with frontend. Type `/frontend help` for an additional help. - reaction-type: hooray diff --git a/.github/workflows/invite-check.yml b/.github/workflows/invite-check.yml deleted file mode 100644 index 324544cbe1ee..000000000000 --- a/.github/workflows/invite-check.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: "Slack Invite Checker" - -on: - schedule: - - cron: '0 */6 * * *' # At minute 0 past every 6th hour. - workflow_dispatch: - -env: - INVITE_LINK: 'https://slack.labelstud.io/' - -jobs: - check: - runs-on: ubuntu-latest - steps: - - name: Check if the invite link is valid - id: invite_link_is_active - run: | - ! grep -Eo '("|")isSharedInviteError("|")\s*:\s*true' <( - curl --silent --location ${{ env.INVITE_LINK }} -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0' -H "Accept: application/json" - ) - - name: Notify to Slack - if: always() && steps.invite_link_is_active.outcome == 'failure' - uses: slackapi/slack-github-action@v1.24 - with: - channel-id: '${{ secrets.SLACK_LS_MONITORING_CHANNEL }}' - slack-message: "Our <${{ env.INVITE_LINK }}|public invite link> has expired and needs to be manually updated:\n1. without expiry date; you may need to deactivate the previous one first.\n2. Update the permanent redirect link with newly generated link WITHOUT URL SCHEME." - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_LS_BOT_TOKEN }} - - - name: Check if the invite link has teamDomains arg - id: invite_link_has_teamdomains - run: | - grep -Eo '("|")teamSignupDomains("|")\s*:\s*\[\]' <( - curl --silent --location ${{ env.INVITE_LINK }} -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0' -H "Accept: application/json" - ) - - name: Notify to Slack - if: always() && steps.invite_link_has_teamdomains.outcome == 'failure' - uses: slackapi/slack-github-action@v1.24 - with: - channel-id: '${{ secrets.SLACK_LS_MONITORING_CHANNEL }}' - slack-message: "Our <${{ env.INVITE_LINK }}|public invite link> was configured to allow signups only from a list of allowed domains:\n1. Go to , next to `Joining This Workspace`, click `Expand`.\n2. Delete all domains from the list, select `Allow invitations` and click `Save`." - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_LS_BOT_TOKEN }} diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml deleted file mode 100644 index c7451f7851fd..000000000000 --- a/.github/workflows/pr-labeler.yml +++ /dev/null @@ -1,111 +0,0 @@ -name: "PR labeler" - -on: - pull_request_target: - types: - - opened - - edited - - reopened - - synchronize - - ready_for_review - branches: - - master - - develop - - 'release/**' - - 'lse-release/**' - - 'ls-release/**' - -env: - ACTIONS_STEP_DEBUG: '${{ secrets.ACTIONS_STEP_DEBUG }}' - -jobs: - autolabel: - name: "PR label validator" - runs-on: ubuntu-latest - permissions: - pull-requests: write - steps: - - - uses: hmarr/debug-action@v2.1.0 - - - name: "Validate PR's title" - uses: thehanimo/pr-title-checker@v1.4.0 - with: - GITHUB_TOKEN: ${{ github.token }} - pass_on_octokit_error: false - configuration_path: ".github/pr-title-checker-config.json" - - - name: "Set PR's label based on title" - uses: release-drafter/release-drafter@v5.24.0 - with: - disable-releaser: true - config-name: autolabeler.yml - env: - GITHUB_TOKEN: ${{ github.token }} - - release_field: - name: "Set Aha! Releases field" - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Set field - shell: bash - env: - COMMIT_MESSAGE: ${{ github.event.pull_request.title }} - AHA_SERVER: "https://labelstudio.aha.io" - AHA_TOKEN: "${{ secrets.AHA_TOKEN }}" - AHA_RELEASES_FIELD: releases - TAGS: '["oss"]' - run: | - set -euo pipefail ${ACTIONS_STEP_DEBUG:+-x} - - regex="([a-zA-Z]+):[[:space:]]*([a-zA-Z0-9-]+)?:" - if [[ $COMMIT_MESSAGE =~ $regex ]]; then - export TICKET="${BASH_REMATCH[2]}" - if curl -fsSL \ - --request GET \ - --url "${AHA_SERVER}/api/v1/features/${TICKET}" \ - --header "Authorization: Bearer ${AHA_TOKEN}" \ - --header 'Accept: application/json'; then - cur_tags=$(curl -sSL \ - --request GET \ - --url "${AHA_SERVER}/api/v1/features/${TICKET}" \ - --header "Authorization: Bearer ${AHA_TOKEN}" \ - --header "Content-Type: application/json" \ - --header 'Accept: application/json' | - jq -ecr '[ .feature.custom_fields[] | select(.key=="releases") | .value ]') - echo "Current tags: ${cur_tags}" - new_tags=$(jq -ecr ". += ${TAGS} | flatten | unique" <<< $cur_tags) - echo "New tags: ${new_tags}" - curl -sSL \ - --request PUT \ - --url "${AHA_SERVER}/api/v1/features/${TICKET}" \ - --data "{\"feature\":{\"custom_fields\":{\"releases\":${new_tags}}}}" \ - --header "Authorization: Bearer ${AHA_TOKEN}" \ - --header "Content-Type: application/json" \ - --header 'Accept: application/json' - elif curl -fsSL \ - --request GET \ - --url "${AHA_SERVER}/api/v1/requirements/${TICKET}" \ - --header "Authorization: Bearer ${AHA_TOKEN}" \ - --header 'Accept: application/json'; then - cur_tags=$(curl -sSL \ - --request GET \ - --url "${AHA_SERVER}/api/v1/requirements/${TICKET}" \ - --header "Authorization: Bearer ${AHA_TOKEN}" \ - --header "Content-Type: application/json" \ - --header 'Accept: application/json' | - jq -ecr '[ .requirement.custom_fields[] | select(.key=="releases") | .value ]') - echo "Current tags: ${cur_tags}" - new_tags=$(jq -ecr ". += ${TAGS} | flatten | unique" <<< $cur_tags) - echo "New tags: ${new_tags}" - curl -sSL \ - --request PUT \ - --url "${AHA_SERVER}/api/v1/requirements/${TICKET}" \ - --data "{\"requirement\":{\"custom_fields\":{\"releases\":${new_tags}}}}" \ - --header "Authorization: Bearer ${AHA_TOKEN}" \ - --header "Content-Type: application/json" \ - --header 'Accept: application/json' - fi - fi diff --git a/.github/workflows/release-cut-off-release-branch.yml b/.github/workflows/release-cut-off-release-branch.yml deleted file mode 100644 index 589c6495c412..000000000000 --- a/.github/workflows/release-cut-off-release-branch.yml +++ /dev/null @@ -1,191 +0,0 @@ -name: "Release: Cut off release branch" - -on: - workflow_dispatch: - inputs: - version: - description: 'Release version' - required: true - type: string - ref: - description: 'Commit SHA or ref name or tag' - required: true - default: 'develop' - type: string - -env: - RELEASE_BRANCH_PREFIX: "ls-release" - -jobs: - draft-new-release: - name: "Draft new release/hotfix" - runs-on: ubuntu-latest - outputs: - next_develop_version: ${{ steps.calculate_branch_name_and_version.outputs.next_develop_version }} - release_version: ${{ steps.calculate_branch_name_and_version.outputs.release_version }} - release_branch: ${{ steps.calculate_branch_name_and_version.outputs.release_branch }} - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Checkout - uses: actions/checkout@v3 - with: - token: ${{ secrets.GIT_PAT }} - ref: ${{ inputs.ref }} - submodules: 'recursive' - fetch-depth: 0 - - - name: Configure git - shell: bash - run: | - set -xeuo pipefail - git config --global user.name 'robot-ci-heartex' - git config --global user.email 'robot-ci-heartex@users.noreply.github.com' - - - name: Calculate branch name and version - id: calculate_branch_name_and_version - shell: bash - run: | - set -xeuo pipefail - - regexp='^[v]?([0-9]+)\.([0-9]+)\.([0-9]+)$'; - - if [[ "${{ inputs.version }}" =~ $regexp ]]; then - first="${BASH_REMATCH[1]}" - second="${BASH_REMATCH[2]}" - third="${BASH_REMATCH[3]}" - else - echo "${{ inputs.version }} does not mach the regexp ${regexp}" - exit 1 - fi - - release_version="${first}.${second}.${third}" - release_branch="${{ env.RELEASE_BRANCH_PREFIX }}/${first}.${second}.${third}" - next_develop_version="${first}.${second}.$(($third + 1))dev" - - echo "release_branch=${release_branch}" >> $GITHUB_OUTPUT - echo "release_version=${release_version}" >> $GITHUB_OUTPUT - echo "next_develop_version=${next_develop_version}" >> $GITHUB_OUTPUT - - - name: Cut dependencies release branches - uses: actions/github-script@v6 - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const { repo, owner } = context.repo; - const ref = '${{ github.event.inputs.ref }}' - const release = '${{ steps.calculate_branch_name_and_version.outputs.release_branch }}' - - let submodules = [ - {owner: owner, repo: 'label-studio-frontend'}, - {owner: owner, repo: 'dm2'} - ] - - async function getLSSubmoduleVersions(sha) { - let {data: lsTreeData} = await github.rest.git.getTree({ - owner, - repo, - tree_sha: sha - }) - lsTreeData = (await github.rest.git.getTree({ - owner, - repo, - tree_sha: lsTreeData.tree.find(e => e.path === 'label_studio' && e.type === 'tree').sha - })).data - lsTreeData = (await github.rest.git.getTree({ - owner, - repo, - tree_sha: lsTreeData.tree.find(e => e.path === 'frontend' && e.type === 'tree').sha - })).data - lsTreeData = (await github.rest.git.getTree({ - owner, - repo, - tree_sha: lsTreeData.tree.find(e => e.path === 'dist' && e.type === 'tree').sha - })).data - const {data: lsDMTreeData} = await github.rest.git.getTree({ - owner, - repo, - tree_sha: lsTreeData.tree.find(e => e.path === 'dm' && e.type === 'tree').sha - }) - const {data: dmfVersion} = await github.rest.git.getBlob({ - owner, - repo, - file_sha: lsDMTreeData.tree.find(e => e.path === 'version.json' && e.type === 'blob').sha - }) - const dmVersionContent = Buffer.from(dmfVersion.content, dmfVersion.encoding).toString("utf8") - const matchDM = dmVersionContent.match('"commit": "(.*)",') - const {data: lsLSFTreeData} = await github.rest.git.getTree({ - owner, - repo, - tree_sha: lsTreeData.tree.find(e => e.path === 'lsf' && e.type === 'tree').sha - }) - const {data: lsfVersion} = await github.rest.git.getBlob({ - owner, - repo, - file_sha: lsLSFTreeData.tree.find(e => e.path === 'version.json' && e.type === 'blob').sha - }) - const lsfVersionContent = Buffer.from(lsfVersion.content, lsfVersion.encoding).toString("utf8") - const matchLSF = lsfVersionContent.match('"commit": "(.*)",') - return { - 'label-studio-frontend': matchLSF[1], - 'dm2': matchDM[1], - } - } - - const versions = await getLSSubmoduleVersions('${{ inputs.ref }}') - console.log(`submodules versions: ${{ inputs.ref }}`) - console.log(versions) - - for (let submodule of submodules) { - const response = await github.rest.git.createRef({ - owner: submodule.owner, - repo: submodule.repo, - ref: `refs/heads/${release}`, - sha: versions[submodule.repo], - }); - } - - - name: Cut release branch - shell: bash - run: | - set -xeuo pipefail - - git checkout -b "${{ steps.calculate_branch_name_and_version.outputs.release_branch }}" - echo "commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - git push origin HEAD:refs/heads/${{ steps.calculate_branch_name_and_version.outputs.release_branch }} - - set-version-default-branch: - name: 'Set version in default branch' - uses: ./.github/workflows/release-set-version.yml - needs: - - draft-new-release - with: - version: ${{ needs.draft-new-release.outputs.next_develop_version }} - branch: ${{ github.event.repository.default_branch }} - permissions: - contents: write - secrets: inherit - - update-feature-flags: - name: "Update feature flags in release branch" - needs: - - draft-new-release - permissions: - contents: write - uses: ./.github/workflows/feature-flags-update.yml - with: - ref: ${{ needs.draft-new-release.outputs.release_branch }} - secrets: inherit - - set-version-release-branch: - name: 'Set version in release branch' - uses: ./.github/workflows/release-set-version.yml - needs: - - update-feature-flags - - draft-new-release - with: - version: ${{ needs.draft-new-release.outputs.release_version }} - branch: ${{ needs.draft-new-release.outputs.release_branch }} - permissions: - contents: write - secrets: inherit diff --git a/.github/workflows/release-pipeline.yml b/.github/workflows/release-pipeline.yml deleted file mode 100644 index 3e8ecb511a71..000000000000 --- a/.github/workflows/release-pipeline.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: "Release: Pipeline" - -on: - release: - types: - - released - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.pull_request.head.ref || github.ref }} - cancel-in-progress: true - -env: - HOMEBREW_TAP_REPO: "homebrew-tap" - -jobs: - promote_docker_image: - name: "Promote" - permissions: - contents: read - checks: read - uses: ./.github/workflows/docker-release-promote.yml - with: - release_tag: ${{ github.ref_name }} - secrets: inherit - - build_ubi_docker_image: - name: "Build UBI docker image" - uses: ./.github/workflows/docker-build-ubi.yml - with: - sha: ${{ github.ref_name }} - version: ${{ github.ref_name }} - secrets: inherit - - build_hugging_face_docker_image: - name: "Build Hugging Face docker image" - needs: - - promote_docker_image - uses: ./.github/workflows/docker-build-ontop.yml - with: - base_docker_image_version: ${{ github.ref_name }} - tags: "hf-latest,hf-${{ github.ref_name }}" - dockerfile_path: Dockerfile.hgface - ref: ${{ github.ref_name }} - secrets: inherit - - build-pypi: - name: "Build" - permissions: - contents: write - uses: ./.github/workflows/build_pypi.yml - with: - version: ${{ github.ref_name }} - ref: ${{ github.ref_name }} - upload_to_pypi: true - release-id: ${{ github.event.release.id }} - secrets: inherit - - delete-rc-assets: - name: "Delete Release Candidate Assets" - runs-on: ubuntu-latest - needs: - - build-pypi - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Delete Release Candidate Assets - uses: actions/github-script@v6 - env: - RELEASE_ID: "${{ github.event.release.id }}" - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const { repo, owner } = context.repo; - const release_id = process.env.RELEASE_ID; - const rc_regexp = /label[-_]studio-\d+.\d+.\d+rc\d+/; - const {data: release} = await github.rest.repos.getRelease({ - owner, - repo, - release_id, - }); - for (let asset of release.assets) { - const match = asset.name.match(rc_regexp) - if (match) { - console.log(`Deleting asset ${asset.name}`) - await github.rest.repos.deleteReleaseAsset({ - owner, - repo, - asset_id: asset.id, - }); - } - } - - update-homebrew-tap: - name: "Update Homebrew Tap" - runs-on: ubuntu-latest - needs: - - build-pypi - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: DispatchEvent - uses: actions/github-script@v6 - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const {repo, owner} = context.repo; - await github.rest.repos.createDispatchEvent({ - owner: owner, - repo: '${{ env.HOMEBREW_TAP_REPO }}', - event_type: 'upstream_formula_update', - client_payload: { - formula: 'label-studio', - version: '${{ github.ref_name }}', - actor: '${{ github.actor }}', - url: '${{ needs.build-pypi.outputs.pipy-artifact-url }}', - sha256: '${{ needs.build-pypi.outputs.pipy-artifact-digests-sha256 }}', - } - }); - - update-helm-chart: - name: "Update Helm Chart" - needs: - - promote_docker_image - uses: ./.github/workflows/bump-helm-chart.yml - with: - docker_image_version: ${{ github.ref_name }} - secrets: inherit diff --git a/.github/workflows/release-set-version.yml b/.github/workflows/release-set-version.yml deleted file mode 100644 index 992b60fd2b69..000000000000 --- a/.github/workflows/release-set-version.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: "Release: Set version" - -on: - workflow_call: - inputs: - version: - required: true - type: string - branch: - required: true - type: string - workflow_dispatch: - inputs: - version: - description: 'Release version' - required: true - type: string - branch: - description: 'Branch reference' - required: true - default: 'develop' - type: string - -env: - PYTHON_VERSION_FILE: "label_studio/__init__.py" - -jobs: - commit-version: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: Checkout - uses: actions/checkout@v3 - with: - token: ${{ secrets.GIT_PAT }} - ref: ${{ inputs.branch }} - fetch-depth: 1 - - - name: Get GitHub user details - id: get-github-user - uses: actions/github-script@v6 - env: - ACTOR_USERNAME: ${{ github.event.sender.login }} - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const actor_username = process.env.ACTOR_USERNAME; - - let user_name = 'robot-ci-heartex'; - let user_email = 'robot-ci-heartex@users.noreply.github.com'; - - try { - const {data: user} = await github.rest.users.getByUsername({ - username: actor_username, - }); - user_name = user.login; - user_email = user.email; - } catch (e) { - console.log(e) - } - - core.setOutput('user_name', user_name); - core.setOutput('user_email', user_email); - - - name: Configure git - shell: bash - run: | - set -xeuo pipefail - git config --global user.name '${{ steps.get-github-user.outputs.user_name }}' - git config --global user.email '${{ steps.get-github-user.outputs.user_email }}' - - - name: Validate user input - id: validate-user-input - shell: bash - run: | - set -xeuo pipefail - - regexp='^[v]?([0-9]+)\.([0-9]+)\.([0-9]+)[a-zA-Z0-9-]*$' - - if [[ "${{ inputs.version }}" =~ $regexp ]]; then - echo "${{ inputs.version }} does match the regexp ${regexp}" - else - echo "${{ inputs.version }} does not match the regexp ${regexp}" - exit 1 - fi - - - name: Commit version file - id: make-commit - run: | - set -euo pipefail - - sed -i "s/^__version__[ ]*=.*/__version__ = '${{ inputs.version }}'/g" ${{ env.PYTHON_VERSION_FILE }} - - git add ${{ env.PYTHON_VERSION_FILE }} - git commit -m "chore: Bump version to ${{ inputs.version }}" -m 'Workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' - - echo "commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - git push origin HEAD:refs/heads/${{ inputs.branch }} diff --git a/.github/workflows/slash-command-dispatch.yml b/.github/workflows/slash-command-dispatch.yml deleted file mode 100644 index 982c95bfc16c..000000000000 --- a/.github/workflows/slash-command-dispatch.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Slash Command Dispatch -on: - issue_comment: - types: [created] - -env: - commands_list: | - help - frontend - ff - git - -jobs: - slashCommandDispatch: - if: startsWith(github.event.comment.body, '/') - timeout-minutes: 1 - runs-on: ubuntu-latest - steps: - - uses: hmarr/debug-action@v2.1.0 - - - name: 'Validate command' - id: determine_command - uses: actions/github-script@v6 - env: - COMMANDS_LIST: ${{ env.commands_list }} - with: - github-token: ${{ secrets.GIT_PAT }} - script: | - const body = context.payload.comment.body.toLowerCase().trim() - const commands_list = process.env.COMMANDS_LIST.split("\n") - console.log("Detected PR comment: " + body) - console.log("Commands list: " + commands_list) - commandArray = body.split(/\s+/) - const contextCommand = commandArray[0].split('/')[1].trim(); - console.log("contextCommand: " + contextCommand) - core.setOutput('command_state', 'known') - if (! commands_list.includes(contextCommand)) { - core.setOutput('command_state', 'unknown') - core.setOutput('command', contextCommand) - } - - - name: Slash Command Dispatch - id: scd - if: ${{ steps.determine_command.outputs.command_state != 'unknown' }} - uses: peter-evans/slash-command-dispatch@v3 - with: - token: ${{ secrets.GIT_PAT }} - issue-type: "pull-request" - reactions: true - commands: ${{ env.commands_list }} - - - name: Edit comment with error message - if: ${{ steps.determine_command.outputs.command_state == 'unknown' }} - uses: peter-evans/create-or-update-comment@v3 - with: - comment-id: ${{ github.event.comment.id }} - body: | - > '/${{ steps.determine_command.outputs.command }}' is unknown command. - > See '/help' - reactions: eyes, confused diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index a10a2264f9f4..000000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,31 +0,0 @@ -# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. -# -# You can adjust the behavior by modifying this file. -# For more information, see: -# https://github.com/actions/stale -name: "Close stale issues and PRs" - -on: - schedule: - - cron: "30 1 * * *" # At 01:30 - -permissions: - issues: write - pull-requests: write - -jobs: - stale: - runs-on: ubuntu-latest - - steps: - - uses: actions/stale@v8 - with: - days-before-issue-stale: -1 - days-before-issue-close: -1 # never closed automatically - stale-pr-message: "This PR is stale because it has been open 172 days with no activity. Remove stale label or comment or this will be closed in 10 days." - close-pr-message: "This PR was closed because it has been stalled for 10 days with no activity." - days-before-pr-stale: 172 - days-before-pr-close: 10 - stale-pr-label: "no-pr-activity" - exempt-pr-labels: "awaiting-approval,work-in-progress" - exempt-draft-pr: true