From 389911907b6f3cce30bb8f43b788a6744d7fcf97 Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Mon, 9 Jan 2023 13:22:08 +0530 Subject: [PATCH 01/15] update: master with bstackdemo, local endpoint, W3C caps --- config/local.json | 10 ++++++---- config/parallel.json | 8 +++++--- config/single.json | 8 +++++--- features/environment.py | 2 +- features/local.feature | 4 ++-- features/single.feature | 11 ++++++----- features/steps/steps.py | 32 ++++++++++++++++++++------------ 7 files changed, 45 insertions(+), 30 deletions(-) diff --git a/config/local.json b/config/local.json index 572441b..a3ca7ae 100644 --- a/config/local.json +++ b/config/local.json @@ -3,10 +3,12 @@ "key": "BROWSERSTACK_ACCESS_KEY", "capabilities": { - "build": "browserstack-build-1", - "name": "BStack local behave", - "browserstack.debug": true, - "browserstack.local": true + "bstack:options": { + "buildName": "browserstack-build-1", + "sessionName": "BStack local behave", + "debug": true, + "local": true + } }, "environments": [{ diff --git a/config/parallel.json b/config/parallel.json index 6bf05f7..77b6876 100644 --- a/config/parallel.json +++ b/config/parallel.json @@ -3,9 +3,11 @@ "key": "BROWSERSTACK_ACCESS_KEY", "capabilities": { - "build": "browserstack-build-1", - "name": "BStack parallel behave", - "browserstack.debug": true + "bstack:options": { + "buildName": "browserstack-build-1", + "sessionName": "BStack parallel behave", + "debug": true + } }, "environments": [{ diff --git a/config/single.json b/config/single.json index 40a2e3d..79cd3cf 100644 --- a/config/single.json +++ b/config/single.json @@ -3,9 +3,11 @@ "key": "BROWSERSTACK_ACCESS_KEY", "capabilities": { - "build": "browserstack-build-1", - "name": "BStack single behave", - "browserstack.debug": true + "bstack:options": { + "buildName": "browserstack-build-1", + "sessionName": "BStack single behave", + "debug": true + } }, "environments": [{ diff --git a/features/environment.py b/features/environment.py index 1995b5f..254326e 100644 --- a/features/environment.py +++ b/features/environment.py @@ -34,7 +34,7 @@ def before_feature(context, feature): if key not in desired_capabilities: desired_capabilities[key] = CONFIG["capabilities"][key] - if "browserstack.local" in desired_capabilities and desired_capabilities["browserstack.local"]: + if "bstack:options" in desired_capabilities and "local" in desired_capabilities["bstack:options"] and desired_capabilities["bstack:options"]["local"]: start_local() context.browser = webdriver.Remote( diff --git a/features/local.feature b/features/local.feature index ba455f5..f7199a3 100644 --- a/features/local.feature +++ b/features/local.feature @@ -1,4 +1,4 @@ Feature: BrowserStack Local Testing Scenario: can check tunnel working - When visit url "http://bs-local.com:45691/check" - Then page contains "Up and running" + When visit url "http://bs-local.com:45454/" + Then title contains "BrowserStack Local" diff --git a/features/single.feature b/features/single.feature index 920572c..a28ea48 100644 --- a/features/single.feature +++ b/features/single.feature @@ -1,5 +1,6 @@ -Feature: Google\'s Search Functionality - Scenario: can find search results - When visit url "http://www.google.com/ncr" - When field with name "q" is given "BrowserStack" - Then title becomes "BrowserStack - Google Search" +Feature: BrowserStack Demo + Scenario: Add product to cart + When visit url "https://bstackdemo.com/" + When item with xpath '//*[@id="1"]/p' is present to be added to cart + When add to cart button '//*[@id="1"]/div[4]' for above item is clicked + Then item in cart '//*[@id="__next"]/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]' is same as the one which was added diff --git a/features/steps/steps.py b/features/steps/steps.py index 3ef316a..e1cf6e0 100644 --- a/features/steps/steps.py +++ b/features/steps/steps.py @@ -1,20 +1,28 @@ import time +from selenium.webdriver.common.by import By @when('visit url "{url}"') def step(context, url): context.browser.get(url) + time.sleep(2) + +@when("item with xpath '{selector}' is present to be added to cart") +def step(context, selector): + item = context.browser.find_element(By.XPATH, selector) + context.item_to_add = item.text -@when('field with name "{selector}" is given "{value}"') -def step(context, selector, value): - elem = context.browser.find_element_by_name(selector) - elem.send_keys(value) - elem.submit() - time.sleep(5) +@when("add to cart button '{selector}' for above item is clicked") +def step(context, selector): + add_btn = context.browser.find_element(By.XPATH, selector) + add_btn.click() + time.sleep(2) -@then('title becomes "{title}"') -def step(context, title): - assert context.browser.title == title +@then("item in cart '{selector}' is same as the one which was added") +def step(context, selector): + item = context.browser.find_element(By.XPATH, selector) + item_in_cart = item.text + assert item_in_cart == context.item_to_add -@then(u'page contains "{body}"') -def step(context, body): - assert body in context.browser.page_source +@then('title contains "{title}"') +def step(context, title): + assert title in context.browser.title From 98dff9526a758ea3070261f141ab1ed08b72fb68 Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Mon, 9 Jan 2023 13:45:52 +0530 Subject: [PATCH 02/15] update: use browserName as cap, specify OS in || --- config/local.json | 2 +- config/parallel.json | 20 +++++++++++++++----- config/single.json | 2 +- features/environment.py | 2 ++ pavement.py | 6 +++--- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/config/local.json b/config/local.json index a3ca7ae..ea3ea22 100644 --- a/config/local.json +++ b/config/local.json @@ -12,6 +12,6 @@ }, "environments": [{ - "browser": "chrome" + "browserName": "chrome" }] } diff --git a/config/parallel.json b/config/parallel.json index 77b6876..a5a6949 100644 --- a/config/parallel.json +++ b/config/parallel.json @@ -11,12 +11,22 @@ }, "environments": [{ - "browser": "chrome" - },{ - "browser": "firefox" + "browserName": "chrome", + "bstack:options": { + "os": "OS X", + "osVersion": "catalina" + } },{ - "browser": "safari" + "browserName": "firefox", + "bstack:options": { + "os": "Windows", + "osVersion": "10" + } },{ - "browser": "internet explorer" + "browserName": "safari", + "bstack:options": { + "osVersion" : "16", + "deviceName" : "iPhone 14" + } }] } diff --git a/config/single.json b/config/single.json index 79cd3cf..d4a94c2 100644 --- a/config/single.json +++ b/config/single.json @@ -11,6 +11,6 @@ }, "environments": [{ - "browser": "chrome" + "browserName": "chrome" }] } diff --git a/features/environment.py b/features/environment.py index 254326e..15f51ed 100644 --- a/features/environment.py +++ b/features/environment.py @@ -33,6 +33,8 @@ def before_feature(context, feature): for key in CONFIG["capabilities"]: if key not in desired_capabilities: desired_capabilities[key] = CONFIG["capabilities"][key] + elif key == "bstack:options": + desired_capabilities[key].update(CONFIG["capabilities"][key]) if "bstack:options" in desired_capabilities and "local" in desired_capabilities["bstack:options"] and desired_capabilities["bstack:options"]["local"]: start_local() diff --git a/pavement.py b/pavement.py index 4c35d56..abe18d4 100644 --- a/pavement.py +++ b/pavement.py @@ -28,13 +28,13 @@ def run(args): run_behave_test(args[0], args[0]) else: jobs = [] - for i in range(4): - p = threading.Thread(target=run_behave_test,args=(args[0], "single",i)) + for i in range(3): + p = threading.Thread(target=run_behave_test,args=(args[0], "single", i)) jobs.append(p) p.start() for th in jobs: - th.join() + th.join() @task def test(): From 0ba1eebe4b279d2503288559ffda34308b7f5f92 Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Mon, 9 Jan 2023 13:47:37 +0530 Subject: [PATCH 03/15] chore: source cap update --- features/environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/environment.py b/features/environment.py index 15f51ed..210ff6f 100644 --- a/features/environment.py +++ b/features/environment.py @@ -29,12 +29,12 @@ def stop_local(): def before_feature(context, feature): desired_capabilities = CONFIG['environments'][TASK_ID] - desired_capabilities['browserstack.source'] = 'behave:sample-master:v1.0' for key in CONFIG["capabilities"]: if key not in desired_capabilities: desired_capabilities[key] = CONFIG["capabilities"][key] elif key == "bstack:options": desired_capabilities[key].update(CONFIG["capabilities"][key]) + desired_capabilities['bstack:options']['source'] = 'behave:sample-master:v1.1' if "bstack:options" in desired_capabilities and "local" in desired_capabilities["bstack:options"] and desired_capabilities["bstack:options"]["local"]: start_local() From 677d25e23acbb89268856149128e6e71824bc630 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Thu, 16 Mar 2023 20:00:05 +0530 Subject: [PATCH 04/15] Added keep_alive --- features/environment.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/environment.py b/features/environment.py index 83b6748..88f6e1b 100644 --- a/features/environment.py +++ b/features/environment.py @@ -39,7 +39,8 @@ def before_feature(context, feature): context.browser = webdriver.Remote( desired_capabilities=desired_capabilities, - command_executor="http://%s:%s@hub.browserstack.com/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY) + command_executor="https://%s:%s@hub.browserstack.com/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY), + keep_alive=True ) def after_feature(context, feature): From 39965d00c4d02e3d9ec46f5e177ec3ba1e8d7aba Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Thu, 23 Mar 2023 16:36:36 +0530 Subject: [PATCH 05/15] Made parallel test as default --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a8c3875..b7791c0 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,8 @@ * Update `*.json` files inside the `config/` directory with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings) ## Running your tests -* To run a single test, run `paver run single` +* To run tests, run `paver run parallel` * To run local tests, run `paver run local` -* To run parallel tests, run `paver run parallel` Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github) From c965c8d58cb21b203ae383a2d6432248e7521953 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Wed, 29 Mar 2023 17:15:26 +0530 Subject: [PATCH 06/15] Add source --- features/environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/environment.py b/features/environment.py index 210ff6f..5868ea6 100644 --- a/features/environment.py +++ b/features/environment.py @@ -34,7 +34,7 @@ def before_feature(context, feature): desired_capabilities[key] = CONFIG["capabilities"][key] elif key == "bstack:options": desired_capabilities[key].update(CONFIG["capabilities"][key]) - desired_capabilities['bstack:options']['source'] = 'behave:sample-master:v1.1' + desired_capabilities['bstack:options']['source'] = 'behave:sample-master:v1.2' if "bstack:options" in desired_capabilities and "local" in desired_capabilities["bstack:options"] and desired_capabilities["bstack:options"]["local"]: start_local() From 3383858098ac2b5bc8c998d7178419acaf5b50c7 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Wed, 12 Apr 2023 13:41:26 +0530 Subject: [PATCH 07/15] Added workflow file in master --- .github/CODEOWNERS | 1 + .github/workflows/reviewing_changes.yml | 88 +++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/reviewing_changes.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..7e1f1b4 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +.github/* @browserstack/asi-devs diff --git a/.github/workflows/reviewing_changes.yml b/.github/workflows/reviewing_changes.yml new file mode 100644 index 0000000..c395c34 --- /dev/null +++ b/.github/workflows/reviewing_changes.yml @@ -0,0 +1,88 @@ +# This job is to test different profiles in sdk branch against Pull Requests raised +# This workflow targets behave + +name: Python SDK Test workflow on workflow_dispatch + +on: + workflow_dispatch: + inputs: + pull_request_number: + description: 'The pull request number to build' + required: true + +jobs: + comment-run: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + max-parallel: 3 + matrix: + python: ['3.7', '3.10', '3.11'] + os: [ macos-latest, windows-latest, ubuntu-latest ] + name: Behave Repo ${{ matrix.python }} - ${{ matrix.os }} Sample + env: + BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} + BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + + steps: + - uses: actions/checkout@v3 + with: + ref: refs/pull/${{ github.event.inputs.pull_request_number }}/head + - name: Fetch Commit SHA + run: | + git log -1 --format='%H' + echo "commit_sha=$(git log -1 --format='%H')" >> $GITHUB_ENV + echo "commit_sha=$(git log -1 --format='%H')" >> $env:GITHUB_ENV + - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 + id: status-check-in-progress + env: + job_name: Behave Repo ${{ matrix.python }} - ${{ matrix.os }} Sample + with: + github-token: ${{ github.token }} + script: | + const result = await github.rest.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: process.env.job_name, + head_sha: process.env.commit_sha, + status: 'in_progress' + }).catch((err) => ({status: err.status, response: err.response})); + console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) + if (result.status !== 201) { + console.log('Failed to create check run') + } + - name: Setup python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + + - name: Install dependencies + run: python -m pip install -r requirements.txt + + - name: run tests in parallel + run: browserstack-sdk behave features/test.feature + + - name: run local tests in parallel + run: browserstack-sdk behave features/local-test.feature + + - if: always() + uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 + id: status-check-completed + env: + conclusion: ${{ job.status }} + job_name: Behave Repo ${{ matrix.python }} - ${{ matrix.os }} Sample + with: + github-token: ${{ github.token }} + script: | + const result = await github.rest.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: process.env.job_name, + head_sha: process.env.commit_sha, + status: 'completed', + conclusion: process.env.conclusion + }).catch((err) => ({status: err.status, response: err.response})); + console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) + if (result.status !== 201) { + console.log('Failed to create check run') + } From 1fad1b9bc1ee2367785cf5e041b8aa9a96d0e863 Mon Sep 17 00:00:00 2001 From: bstack-security-github <116066275+bstack-security-github@users.noreply.github.com> Date: Wed, 21 Jun 2023 17:23:13 +0530 Subject: [PATCH 08/15] Adding Code Scanner Semgrep.yml workflow file --- .github/workflows/Semgrep.yml | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/Semgrep.yml diff --git a/.github/workflows/Semgrep.yml b/.github/workflows/Semgrep.yml new file mode 100644 index 0000000..0347afd --- /dev/null +++ b/.github/workflows/Semgrep.yml @@ -0,0 +1,48 @@ +# Name of this GitHub Actions workflow. +name: Semgrep + +on: + # Scan changed files in PRs (diff-aware scanning): + # The branches below must be a subset of the branches above + pull_request: + branches: ["master", "main"] + push: + branches: ["master", "main"] + schedule: + - cron: '0 6 * * *' + + +permissions: + contents: read + +jobs: + semgrep: + # User definable name of this GitHub Actions job. + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + name: semgrep/ci + # If you are self-hosting, change the following `runs-on` value: + runs-on: ubuntu-latest + + container: + # A Docker image with Semgrep installed. Do not change this. + image: returntocorp/semgrep + + # Skip any PR created by dependabot to avoid permission issues: + if: (github.actor != 'dependabot[bot]') + + steps: + # Fetch project source with GitHub Actions Checkout. + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + # Run the "semgrep ci" command on the command line of the docker image. + - run: semgrep ci --sarif --output=semgrep.sarif + env: + # Add the rules that Semgrep uses by setting the SEMGREP_RULES environment variable. + SEMGREP_RULES: p/default # more at semgrep.dev/explore + + - name: Upload SARIF file for GitHub Advanced Security Dashboard + uses: github/codeql-action/upload-sarif@6c089f53dd51dc3fc7e599c3cb5356453a52ca9e # v2.20.0 + with: + sarif_file: semgrep.sarif + if: always() \ No newline at end of file From eabb5d022abb89654cef22503561953f483d16a2 Mon Sep 17 00:00:00 2001 From: bstack-security-github <116066275+bstack-security-github@users.noreply.github.com> Date: Mon, 3 Jul 2023 20:33:26 +0530 Subject: [PATCH 09/15] Adding CODEOWNERS file --- .github/CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7e1f1b4..09a587d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,3 @@ .github/* @browserstack/asi-devs + +* @browserstack/automate-public-repos From 2a9c9f372b91e61aeadb2a5cdc049b88ed24e5f0 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Mon, 10 Jul 2023 11:50:50 +0530 Subject: [PATCH 10/15] Fix workflow file --- .github/workflows/reviewing_changes.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/reviewing_changes.yml b/.github/workflows/reviewing_changes.yml index c395c34..2e75cdb 100644 --- a/.github/workflows/reviewing_changes.yml +++ b/.github/workflows/reviewing_changes.yml @@ -6,8 +6,8 @@ name: Python SDK Test workflow on workflow_dispatch on: workflow_dispatch: inputs: - pull_request_number: - description: 'The pull request number to build' + commit_sha: + description: 'The commit id to build' required: true jobs: @@ -27,16 +27,12 @@ jobs: steps: - uses: actions/checkout@v3 with: - ref: refs/pull/${{ github.event.inputs.pull_request_number }}/head - - name: Fetch Commit SHA - run: | - git log -1 --format='%H' - echo "commit_sha=$(git log -1 --format='%H')" >> $GITHUB_ENV - echo "commit_sha=$(git log -1 --format='%H')" >> $env:GITHUB_ENV + ref: ${{ github.event.inputs.commit_sha }} - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 id: status-check-in-progress env: job_name: Behave Repo ${{ matrix.python }} - ${{ matrix.os }} Sample + commit_sha: ${{ github.event.inputs.commit_sha }} with: github-token: ${{ github.token }} script: | @@ -71,6 +67,7 @@ jobs: env: conclusion: ${{ job.status }} job_name: Behave Repo ${{ matrix.python }} - ${{ matrix.os }} Sample + commit_sha: ${{ github.event.inputs.commit_sha }} with: github-token: ${{ github.token }} script: | From 05a478646495c5aed9f06f5bb28bdc03c453380f Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Mon, 10 Jul 2023 13:05:56 +0530 Subject: [PATCH 11/15] Fix workflow file --- .github/workflows/reviewing_changes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reviewing_changes.yml b/.github/workflows/reviewing_changes.yml index 2e75cdb..e880c28 100644 --- a/.github/workflows/reviewing_changes.yml +++ b/.github/workflows/reviewing_changes.yml @@ -7,7 +7,7 @@ on: workflow_dispatch: inputs: commit_sha: - description: 'The commit id to build' + description: 'The full commit id to build' required: true jobs: From 56151a38f4ebc759f490a00276f473c3322e9b0f Mon Sep 17 00:00:00 2001 From: Hrithik Katiyar Date: Mon, 1 Jul 2024 16:03:05 +0530 Subject: [PATCH 12/15] Fixed linting issue --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 49a607d..8358268 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ local.log -**.pyc env +**.pyc From d3bbcf1033a867aa0cdcfe7a3adf261ad5a25bf9 Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Tue, 7 Apr 2026 17:15:41 +0530 Subject: [PATCH 13/15] fix github actions workflow --- .github/workflows/reviewing_changes.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reviewing_changes.yml b/.github/workflows/reviewing_changes.yml index e880c28..3074f75 100644 --- a/.github/workflows/reviewing_changes.yml +++ b/.github/workflows/reviewing_changes.yml @@ -16,8 +16,9 @@ jobs: strategy: fail-fast: false max-parallel: 3 + # python 3.7 is not found in github actions runs, hence removing 3.7 version from matrix and adding lts 3.12 version matrix: - python: ['3.7', '3.10', '3.11'] + python: ['3.10', '3.11', '3.12'] os: [ macos-latest, windows-latest, ubuntu-latest ] name: Behave Repo ${{ matrix.python }} - ${{ matrix.os }} Sample env: From f47fae69bc1bbfc8b5daff301923ec916c26f0f9 Mon Sep 17 00:00:00 2001 From: Ayush Agrawal Date: Tue, 28 Apr 2026 15:29:19 +0530 Subject: [PATCH 14/15] SDK-5741: Migrate browserstack-sdk install from PyPI to S3 Update requirements.txt to install browserstack-sdk from BrowserStack-hosted S3 instead of PyPI, as PyPI flagged the package for obfuscated code. Co-Authored-By: Claude Opus 4.6 (1M context) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7bbfffe..bb4533a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ behave browserstack-local selenium psutil -browserstack-sdk +browserstack-sdk @ https://sdk-assets.browserstack.com/python/browserstack_sdk-latest.tar.gz From f75373b52606e777dbdf9bf843506e6bfcab9e11 Mon Sep 17 00:00:00 2001 From: bstack-security-github <116066275+bstack-security-github@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:35:13 +0530 Subject: [PATCH 15/15] semgrep workflow: pin Docker image and actions to version tags Pin returntocorp/semgrep container image to a specific version and GitHub Actions to major version tags to prevent :latest tag resolution and reduce supply-chain attack surface. Fixes: LCNC-15821 Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/Semgrep.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/Semgrep.yml b/.github/workflows/Semgrep.yml index 0347afd..95c5710 100644 --- a/.github/workflows/Semgrep.yml +++ b/.github/workflows/Semgrep.yml @@ -27,8 +27,7 @@ jobs: container: # A Docker image with Semgrep installed. Do not change this. - image: returntocorp/semgrep - + image: returntocorp/semgrep:1.166.0 # Skip any PR created by dependabot to avoid permission issues: if: (github.actor != 'dependabot[bot]')