From b8e77668aa4c0ddd4aaefd0d7df0010780effa99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 05:26:23 +0000 Subject: [PATCH 1/5] chore(deps): bump the pip-patches group with 2 updates Bumps the pip-patches group with 2 updates: [boto3](https://github.com/boto/boto3) and [pyyaml](https://github.com/yaml/pyyaml). Updates `boto3` from 1.40.36 to 1.40.39 - [Release notes](https://github.com/boto/boto3/releases) - [Commits](https://github.com/boto/boto3/compare/1.40.36...1.40.39) Updates `pyyaml` from 6.0.2 to 6.0.3 - [Release notes](https://github.com/yaml/pyyaml/releases) - [Changelog](https://github.com/yaml/pyyaml/blob/6.0.3/CHANGES) - [Commits](https://github.com/yaml/pyyaml/compare/6.0.2...6.0.3) --- updated-dependencies: - dependency-name: boto3 dependency-version: 1.40.39 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: pip-patches - dependency-name: pyyaml dependency-version: 6.0.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: pip-patches ... Signed-off-by: dependabot[bot] --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 408629cbb..906e10d44 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ aiohttp==3.12.15 beautifulsoup4==4.13.5 -boto3==1.40.36 +boto3==1.40.39 bleach==6.2.0 cryptography===45.0.7 crispy-bootstrap4==2025.6 @@ -40,7 +40,7 @@ python-ldap==3.4.4 python3-openid==3.2.0 python3-saml==1.16.0 pytubefix==9.5.1 -pyyaml==6.0.2 +pyyaml==6.0.3 recipe-scrapers==15.9.0 redis==6.4.0 requests==2.32.5 From ded9fd4223b9c9eafbf8e3581862bc1c0fa8cbde Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 04:30:16 +0000 Subject: [PATCH 2/5] chore(deps): bump boto3 from 1.40.39 to 1.40.40 in the pip-patches group Bumps the pip-patches group with 1 update: [boto3](https://github.com/boto/boto3). Updates `boto3` from 1.40.39 to 1.40.40 - [Release notes](https://github.com/boto/boto3/releases) - [Commits](https://github.com/boto/boto3/compare/1.40.39...1.40.40) --- updated-dependencies: - dependency-name: boto3 dependency-version: 1.40.40 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: pip-patches ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 906e10d44..c512ee04e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ aiohttp==3.12.15 beautifulsoup4==4.13.5 -boto3==1.40.39 +boto3==1.40.40 bleach==6.2.0 cryptography===45.0.7 crispy-bootstrap4==2025.6 From de377e30b0ffe4b9fd5990a025dcd2059c413902 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 04:26:02 +0000 Subject: [PATCH 3/5] chore(deps): bump @codemirror/autocomplete from 6.18.6 to 6.19.0 in /vue Bumps [@codemirror/autocomplete](https://github.com/codemirror/autocomplete) from 6.18.6 to 6.19.0. - [Changelog](https://github.com/codemirror/autocomplete/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/autocomplete/compare/6.18.6...6.19.0) --- updated-dependencies: - dependency-name: "@codemirror/autocomplete" dependency-version: 6.19.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- vue/package.json | 2 +- vue/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/vue/package.json b/vue/package.json index fe755e976..045b6d6a2 100644 --- a/vue/package.json +++ b/vue/package.json @@ -8,7 +8,7 @@ "lint": "vue-cli-service lint" }, "dependencies": { - "@codemirror/autocomplete": "^6.18.6", + "@codemirror/autocomplete": "^6.19.0", "@codemirror/commands": "^6.8.1", "@codemirror/lang-markdown": "^6.3.4", "@codemirror/state": "^6.3.3", diff --git a/vue/yarn.lock b/vue/yarn.lock index 26f6adfe4..2e31ad611 100644 --- a/vue/yarn.lock +++ b/vue/yarn.lock @@ -1092,10 +1092,10 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" -"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.18.6", "@codemirror/autocomplete@^6.7.1": - version "6.18.6" - resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz#de26e864a1ec8192a1b241eb86addbb612964ddb" - integrity sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg== +"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.19.0", "@codemirror/autocomplete@^6.7.1": + version "6.19.0" + resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.19.0.tgz#4e6d6ddc9329ed387b2f7efd38febd3f6e2f63d8" + integrity sha512-61Hfv3cF07XvUxNeC3E7jhG8XNi1Yom1G0lRC936oLnlF+jrbrv8rc/J98XlYzcsAoTVupfsf5fLej1aI8kyIg== dependencies: "@codemirror/language" "^6.0.0" "@codemirror/state" "^6.0.0" From f3df30a7274b2d46e81e8dfd0d6bf00a211b40eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 23:01:33 +0000 Subject: [PATCH 4/5] chore(deps): bump django in the pip group across 1 directory Bumps the pip group with 1 update in the / directory: [django](https://github.com/django/django). Updates `django` from 4.2.24 to 4.2.25 - [Commits](https://github.com/django/django/compare/4.2.24...4.2.25) --- updated-dependencies: - dependency-name: django dependency-version: 4.2.25 dependency-type: direct:production dependency-group: pip ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c512ee04e..bb338dbd8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ boto3==1.40.40 bleach==6.2.0 cryptography===45.0.7 crispy-bootstrap4==2025.6 -Django==4.2.24 +Django==4.2.25 django-allauth==65.11.2 django-annoying==0.10.8 django-auth-ldap==5.2.0 From cd3d3d33893d7fc3ea55246fbef3ec5c71d1c63f Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 2 Oct 2025 00:20:24 +0000 Subject: [PATCH 5/5] Restore upstream infrastructure files for PR - Removed fork-specific .gitattributes - Restored upstream .github/workflows/ - Restored upstream cookbook/version_info.py --- .gitattributes | 10 - .github/workflows/build-docker-open-data.yml | 112 +++++++++ .github/workflows/build-docker.yml | 83 +++++++ .github/workflows/ci.yml | 165 ++++++------- .github/workflows/codeql-analysis.yml | 72 +++--- .github/workflows/create-upstream-pr.yml | 235 +++++++++++++++++++ .github/workflows/dependabot-automerge.yml | 12 +- .github/workflows/docs.yml | 20 ++ .github/workflows/push-orchestrator.yml | 4 +- .github/workflows/stage-branch-for-pr.yml | 2 +- cookbook/version_info.py | 6 +- 11 files changed, 574 insertions(+), 147 deletions(-) delete mode 100644 .gitattributes create mode 100644 .github/workflows/build-docker-open-data.yml create mode 100644 .github/workflows/build-docker.yml create mode 100644 .github/workflows/create-upstream-pr.yml create mode 100644 .github/workflows/docs.yml diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 732ab2a51..000000000 --- a/.gitattributes +++ /dev/null @@ -1,10 +0,0 @@ -# Git attributes configuration for selective merging - -# Prevent merging of GitHub workflow and configuration files - use custom driver -.github/** merge=keep-ours -.github/workflows/** merge=keep-ours -.github/ISSUE_TEMPLATE/** merge=keep-ours - -# Prevent merging of version info files -cookbook/version_info.py merge=ours -version.py merge=ours diff --git a/.github/workflows/build-docker-open-data.yml b/.github/workflows/build-docker-open-data.yml new file mode 100644 index 000000000..597221cac --- /dev/null +++ b/.github/workflows/build-docker-open-data.yml @@ -0,0 +1,112 @@ +name: Build Docker Container with open data plugin installed + +on: + push: + branches: [disabled] + +jobs: + build-container: + name: Build ${{ matrix.name }} Container + runs-on: ubuntu-latest + if: github.repository_owner == 'TandoorRecipes' + continue-on-error: ${{ matrix.continue-on-error }} + permissions: + contents: read + packages: write + strategy: + matrix: + include: + # Standard build config + - name: Standard + dockerfile: Dockerfile + platforms: linux/amd64,linux/arm64 + suffix: "" + continue-on-error: false + steps: + - uses: actions/checkout@v4 + + - name: Get version number + id: get_version + run: | + if [[ "$GITHUB_REF" = refs/tags/* ]]; then + echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT + elif [[ "$GITHUB_REF" = refs/heads/beta ]]; then + echo VERSION=beta >> $GITHUB_OUTPUT + else + echo VERSION=develop >> $GITHUB_OUTPUT + fi + + # clone open data plugin + - name: clone open data plugin repo + uses: actions/checkout@master + with: + repository: TandoorRecipes/open_data_plugin + ref: master + path: ./recipes/plugins/open_data_plugin + + # Build Vue frontend + - uses: actions/setup-node@v4 + with: + node-version: '18' + cache: yarn + cache-dependency-path: vue/yarn.lock + - name: Install dependencies + working-directory: ./vue + run: yarn install --frozen-lockfile + - name: Build dependencies + working-directory: ./vue + run: yarn build + + - name: Setup Open Data Plugin Links + working-directory: ./recipes/plugins/open_data_plugin + run: python setup_repo.py + + - name: Build Open Data Frontend + working-directory: ./recipes/plugins/open_data_plugin/vue + run: yarn build + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + if: github.secret_source == 'Actions' + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + if: github.secret_source == 'Actions' + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + vabene1111/recipes + ghcr.io/TandoorRecipes/recipes + flavor: | + latest=false + suffix=${{ matrix.suffix }} + tags: | + type=raw,value=latest,suffix=-open-data-plugin,enable=${{ startsWith(github.ref, 'refs/tags/') }} + type=semver,suffix=-open-data-plugin,pattern={{version}} + type=semver,suffix=-open-data-plugin,pattern={{major}}.{{minor}} + type=semver,suffix=-open-data-plugin,pattern={{major}} + type=ref,suffix=-open-data-plugin,event=branch + - name: Build and Push + uses: docker/build-push-action@v5 + with: + context: . + file: ${{ matrix.dockerfile }} + pull: true + push: ${{ github.secret_source == 'Actions' }} + platforms: ${{ matrix.platforms }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml new file mode 100644 index 000000000..bc37abf3b --- /dev/null +++ b/.github/workflows/build-docker.yml @@ -0,0 +1,83 @@ +name: Build Docker Container + +on: + push: + branches: [tandoor-1] + +jobs: + build-container: + name: Build ${{ matrix.name }} Container + runs-on: ubuntu-latest + if: github.repository_owner == 'TandoorRecipes' + continue-on-error: ${{ matrix.continue-on-error }} + permissions: + contents: read + packages: write + strategy: + matrix: + include: + # Standard build config + - name: Standard + dockerfile: Dockerfile + platforms: linux/amd64,linux/arm64,linux/arm/v7 + suffix: "" + continue-on-error: false + steps: + - uses: actions/checkout@v4 + + # Build Vue frontend + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: yarn + cache-dependency-path: vue/yarn.lock + - name: Install dependencies + working-directory: ./vue + run: yarn install --frozen-lockfile + - name: Build dependencies + working-directory: ./vue + run: yarn build + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + if: github.secret_source == 'Actions' + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + if: github.secret_source == 'Actions' + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + vabene1111/recipes + ghcr.io/TandoorRecipes/recipes + flavor: | + latest=false + suffix=${{ matrix.suffix }} + tags: | + type=raw,value=tandoor-v1-{{date 'YYYYMMDD'}} + type=raw,value=tandoor-v1 + - name: Build and Push + uses: docker/build-push-action@v5 + with: + context: . + file: ${{ matrix.dockerfile }} + pull: true + push: ${{ github.secret_source == 'Actions' }} + platforms: ${{ matrix.platforms }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e6fc364a4..65a9d9771 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,111 +1,86 @@ name: Continuous Integration -on: - workflow_dispatch: - workflow_call: +on: + push: + branches: [disabled] pull_request: - branches: [ "main", "master", "working" ] + branches: [disabled] -# Cancel redundant runs -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - contents: read jobs: - test: - runs-on: ubuntu-latest - timeout-minutes: 120 - permissions: - contents: read - actions: read + build: + if: github.repository_owner == 'TandoorRecipes' + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: ["3.10"] + node-version: ["18"] - strategy: - fail-fast: false - max-parallel: 4 - matrix: - # 3.13 CI disabled due until https://github.com/TandoorRecipes/recipes/issues/3784 resolved - # python-version: ["3.12", "3.13"] - python-version: ["3.12"] - node-version: ["20"] + steps: + - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + with: + packages: libsasl2-dev python3-dev libxml2-dev libxmlsec1-dev libxslt-dev libxmlsec1-openssl libldap2-dev libssl-dev gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev xmlsec-dev xmlsec build-base g++ curl + version: 1.0 - steps: - - uses: actions/checkout@v4 + # Setup python & dependencies + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" - - uses: awalsh128/cache-apt-pkgs-action@5902b33ae29014e6ca012c5d8025d4346556bd40 # v1.4.3 - with: - packages: libsasl2-dev python3-dev libxml2-dev libxmlsec1-dev libxslt-dev libxmlsec1-openssl libldap2-dev libssl-dev gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev xmlsec-dev xmlsec build-base g++ curl - version: 1.0 + - name: Install Python Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt - # Setup python & dependencies - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: "pip" + - name: Cache StaticFiles + uses: actions/cache@v4 + id: django_cache + with: + path: | + ./cookbook/static + ./vue/webpack-stats.json + ./staticfiles + key: | + ${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue/src/*') }} - - name: Install Python Dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt + # Build Vue frontend & Dependencies + - name: Set up Node ${{ matrix.node-version }} + if: steps.django_cache.outputs.cache-hit != 'true' + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "yarn" + cache-dependency-path: ./vue/yarn.lock - - name: Cache StaticFiles - uses: actions/cache@v4 - id: django_cache - with: - path: | - ./cookbook/static - ./vue/webpack-stats.json - ./staticfiles - key: | - ${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue/src/*') }} + - name: Install Vue dependencies + if: steps.django_cache.outputs.cache-hit != 'true' + working-directory: ./vue + run: yarn install - # Build Vue frontend & Dependencies - - name: Set up Node ${{ matrix.node-version }} - if: steps.django_cache.outputs.cache-hit != 'true' - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: "yarn" - cache-dependency-path: ./vue/yarn.lock + - name: Build Vue dependencies + if: steps.django_cache.outputs.cache-hit != 'true' + working-directory: ./vue + run: yarn build - - name: Install Vue dependencies - if: steps.django_cache.outputs.cache-hit != 'true' - working-directory: ./vue - run: yarn install + - name: Compile Django StaticFiles + if: steps.django_cache.outputs.cache-hit != 'true' + run: | + python3 manage.py collectstatic --noinput + python3 manage.py collectstatic_js_reverse - - name: Build Vue dependencies - if: steps.django_cache.outputs.cache-hit != 'true' - working-directory: ./vue - run: yarn build + - uses: actions/cache/save@v4 + if: steps.django_cache.outputs.cache-hit != 'true' + with: + path: | + ./cookbook/static + ./vue/webpack-stats.json + ./staticfiles + key: | + ${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue/src/*') }} - - name: Compile Django StaticFiles - if: steps.django_cache.outputs.cache-hit != 'true' - run: | - python3 manage.py collectstatic --noinput - python3 manage.py collectstatic_js_reverse - - - uses: actions/cache/save@v4 - if: steps.django_cache.outputs.cache-hit != 'true' - with: - path: | - ./cookbook/static - ./vue/webpack-stats.json - ./staticfiles - key: | - ${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.node-version }}-collectstatic-${{ hashFiles('**/*.css', '**/*.js', 'vue/src/*') }} - - # Testing - - name: Django Testing - run: pytest --junitxml=junit/test-results-${{ matrix.python-version }}.xml --disable-warnings - - # Upload test results - - name: Upload Test Results - uses: actions/upload-artifact@v4 - if: always() - with: - name: test-results-${{ matrix.python-version }}-${{ matrix.node-version }} - path: junit/test-results-*.xml - retention-days: 7 + - name: Django Testing project + run: pytest --junitxml=junit/test-results-${{ matrix.python-version }}.xml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 743a0cc3a..de8521c99 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,41 +1,53 @@ -name: "CodeQL" +name: "Code scanning - action" on: - workflow_dispatch: push: - branches: [ "main", "master", "develop", "working" ] + branches: [disabled] pull_request: - branches: [ "main", "master", "working" ] - schedule: - # Run weekly on Tuesdays at 2:17 AM UTC - - cron: '17 2 * * 2' + branches: [disabled] -permissions: - contents: read jobs: - analyze: - name: Analyze + CodeQL-Build: + if: github.repository_owner == 'TandoorRecipes' runs-on: ubuntu-latest - timeout-minutes: 360 - permissions: - contents: read - security-events: write - actions: read - strategy: - fail-fast: false - matrix: - language: ['python', 'javascript-typescript', 'actions'] - steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - queries: security-extended + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + # Override language selection by uncommenting this and choosing your languages + with: + languages: python, javascript + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + # - name: Autobuild + # uses: github/codeql-action/autobuild@v1 + + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + languages: javascript, python diff --git a/.github/workflows/create-upstream-pr.yml b/.github/workflows/create-upstream-pr.yml new file mode 100644 index 000000000..292753457 --- /dev/null +++ b/.github/workflows/create-upstream-pr.yml @@ -0,0 +1,235 @@ +name: Create Upstream PR + +on: + workflow_run: + workflows: ["Push Workflow"] + types: + - completed + branches: [working] + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + create-upstream-pr: + runs-on: ubuntu-latest + concurrency: + group: upstream-pr + cancel-in-progress: true + if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' + steps: + - name: Generate GitHub App token (for branch push) + id: generate_token_push + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.BOT_APP_ID }} + private-key: ${{ secrets.BOT_PRIVATE_KEY }} + + - name: Checkout fork + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ steps.generate_token_push.outputs.token }} + + - name: Setup git user + run: | + git config user.name "GitHub Action" + git config user.email "action@github.com" + + - name: Add upstream remote + run: | + git remote get-url upstream || git remote add upstream https://github.com/TandoorRecipes/recipes.git + git fetch upstream + + - name: Ensure jq is available + run: | + if ! command -v jq &> /dev/null; then + sudo apt-get update && sudo apt-get install -y jq + fi + + - name: Create upstream PR branch + id: create_branch + run: | + BRANCH_NAME="upstream-pr-$(date +%Y%m%d-%H%M%S)" + git checkout -b "$BRANCH_NAME" || { echo "❌ Failed to create branch $BRANCH_NAME"; exit 1; } + echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT + echo "✅ Created branch: $BRANCH_NAME" + + - name: Restore upstream infrastructure files + id: restore_infra + run: | + BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}" + git checkout "$BRANCH_NAME" + git rm .gitattributes || echo "â„šī¸ .gitattributes not present, skipping removal." + git checkout upstream/tandoor-1 -- .github/workflows/ || echo "â„šī¸ No workflows to restore." + git checkout upstream/tandoor-1 -- cookbook/version_info.py || echo "â„šī¸ No version_info.py to restore." + git add . + if ! git diff --cached --quiet; then + git commit -m $'Restore upstream infrastructure files for PR\n\n- Removed fork-specific .gitattributes\n- Restored upstream .github/workflows/\n- Restored upstream cookbook/version_info.py' + echo "✅ Infrastructure files restored and committed." + else + echo "â„šī¸ No infrastructure changes to commit." + fi + + - name: Push branch to fork (after infra commit) + env: + GITHUB_TOKEN: ${{ steps.generate_token_push.outputs.token }} + run: | + BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}" + echo "Pushing branch $BRANCH_NAME after infra file restore." + git push --set-upstream https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git "$BRANCH_NAME" + echo "✅ Branch pushed: $BRANCH_NAME (infra files)" + + + - name: Merge upstream branch + id: merge_upstream + run: | + BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}" + git checkout "$BRANCH_NAME" + if git merge --no-edit upstream/tandoor-1; then + echo "✅ Merged upstream/tandoor-1 into $BRANCH_NAME" + if ! git diff --cached --quiet || [ -n "$(git log origin/$BRANCH_NAME..$BRANCH_NAME --oneline)" ]; then + echo "merge_commit=true" >> $GITHUB_OUTPUT + else + echo "merge_commit=false" >> $GITHUB_OUTPUT + fi + else + echo "❌ Merge conflict detected during merge with upstream/tandoor-1. Please resolve conflicts manually." >&2 + exit 1 + fi + + - name: Push branch to fork (after merge) + if: steps.merge_upstream.outputs.merge_commit == 'true' + env: + GITHUB_TOKEN: ${{ steps.generate_token_push.outputs.token }} + run: | + BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}" + echo "Pushing branch $BRANCH_NAME after merge." + git push https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git "$BRANCH_NAME" + echo "✅ Branch pushed: $BRANCH_NAME (after merge)" + + + - name: Get commit list + id: get_commits + run: | + BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}" + COMMITS_RAW=$(git log upstream/tandoor-1..$BRANCH_NAME --oneline) + if [ -z "$COMMITS_RAW" ]; then + echo "has_changes=false" >> $GITHUB_OUTPUT + echo "✅ No commits to contribute - exiting gracefully" + exit 0 + fi + echo "commits_raw<> $GITHUB_OUTPUT + printf "%s\n" "$COMMITS_RAW" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + echo "has_changes=true" >> $GITHUB_OUTPUT + + + - name: Get changed files + id: get_files + run: | + BRANCH_NAME="${{ steps.create_branch.outputs.branch_name }}" + CHANGED_FILES=$(git diff upstream/tandoor-1..$BRANCH_NAME --name-only) + echo "changed_files<> $GITHUB_OUTPUT + printf "%s\n" "$CHANGED_FILES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + CODE_COUNT=$(echo "$CHANGED_FILES" | grep -c '^' || true) + echo "code_count=$CODE_COUNT" >> $GITHUB_OUTPUT + + - name: Summarize changes + id: summarize_changes + run: | + CODE_COUNT=${{ steps.get_files.outputs.code_count }} + CHANGES_SUMMARY="Modified $CODE_COUNT code files" + echo "changes_summary=$CHANGES_SUMMARY" >> $GITHUB_OUTPUT + + - name: Prepare commit subjects and JSON + id: prepare_commits + run: | + COMMITS_RAW="${{ steps.get_commits.outputs.commits_raw }}" + CODE_FILES=( $(echo "${{ steps.get_files.outputs.changed_files }}") ) + FILTERED_COMMITS_JSON="[]" + COMMIT_SUBJECTS_ARRAY=() + INFRA_PATTERNS='^\.github/|^cookbook/version_info\.py$|^\.gitattributes$' + while IFS= read -r commit_line; do + if [ -z "$commit_line" ]; then continue; fi + COMMIT_SHA=$(echo "$commit_line" | cut -d' ' -f1) + COMMIT_SUBJECT=$(echo "$commit_line" | cut -d' ' -f2-) + mapfile -t COMMIT_FILES < <(git diff-tree --no-commit-id --name-only -r "$COMMIT_SHA" | grep -Ev "$INFRA_PATTERNS") + # Only include commit if it touches at least one non-infra file that is still different + INCLUDE_COMMIT=false + for file in "${COMMIT_FILES[@]}"; do + for code_file in "${CODE_FILES[@]}"; do + if [ "$file" = "$code_file" ]; then + INCLUDE_COMMIT=true + break 2 + fi + done + done + if [ "$INCLUDE_COMMIT" = true ]; then + COMMIT_SUBJECTS_ARRAY+=("- $COMMIT_SUBJECT") + FILES_JSON=$(printf '%s\n' "${COMMIT_FILES[@]}" | jq -R . | jq -s .) + COMMIT_JSON=$(jq -n --arg sha "$COMMIT_SHA" --arg subject "$COMMIT_SUBJECT" --argjson files "$FILES_JSON" '{sha: $sha, subject: $subject, files: $files}') + FILTERED_COMMITS_JSON=$(echo "$FILTERED_COMMITS_JSON" | jq --argjson item "$COMMIT_JSON" '. + [$item]') + fi + done <<< "$COMMITS_RAW" + echo 'commits_json<> $GITHUB_OUTPUT + printf "%s\n" "$FILTERED_COMMITS_JSON" >> $GITHUB_OUTPUT + echo 'EOF' >> $GITHUB_OUTPUT + echo "commit_subjects<> $GITHUB_OUTPUT + printf '%s\n' "${COMMIT_SUBJECTS_ARRAY[@]}" >> $GITHUB_OUTPUT + echo 'EOF' >> $GITHUB_OUTPUT + + + - name: Build PR content + if: steps.get_commits.outputs.has_changes == 'true' + id: build_pr_content + uses: actions/github-script@v7 + env: + COMMITS_JSON: ${{ steps.prepare_commits.outputs.commits_json }} + CHANGES_SUMMARY: ${{ steps.summarize_changes.outputs.changes_summary }} + BRANCH_NAME: ${{ steps.create_branch.outputs.branch_name }} + GITHUB_REPOSITORY: ${{ github.repository }} + with: + github-token: ${{ steps.generate_token_push.outputs.token }} + script: | + const commits = JSON.parse(process.env.COMMITS_JSON || '[]'); + const changesSummary = process.env.CHANGES_SUMMARY || 'Changes from fork'; + const branchName = process.env.BRANCH_NAME || ''; + const repo = process.env.GITHUB_REPOSITORY || ''; + const [owner, reponame] = repo.split('/'); + const nCommits = commits.length; + let prTitle = 'Sync ' + nCommits + ' commit' + (nCommits !== 1 ? 's' : '') + ' from fork:'; + if (nCommits > 0) { + prTitle += ' ' + commits[0].subject; + } + let prBody = `This PR syncs ${nCommits} commit${nCommits !== 1 ? 's' : ''} from branch ${branchName}.\n\n`; + prBody += `**Changes Summary:**\n${changesSummary}\n\n`; + prBody += `Commits included:\n`; + for (const c of commits) { + prBody += `- ${c.subject} ([${c.sha}](https://github.com/${owner}/${reponame}/commit/${c.sha}))\n`; + } + prBody += `\n---\n`; + core.setOutput('prTitle', prTitle); + core.setOutput('prBody', prBody); + + + - name: Print PR creation instructions + if: steps.get_commits.outputs.has_changes == 'true' + env: + BRANCH_NAME: ${{ steps.create_branch.outputs.branch_name }} + PR_TITLE: ${{ steps.build_pr_content.outputs.prTitle }} + PR_BODY: ${{ steps.build_pr_content.outputs.prBody }} + run: | + echo "✅ Branch pushed: $BRANCH_NAME" + echo + echo "To create a pull request, open:" + echo "https://github.com/TandoorRecipes/recipes/compare/tandoor-1...${{ github.repository_owner }}:$BRANCH_NAME?expand=1" + echo + echo "Suggested PR title:" + echo "$PR_TITLE" + echo + echo "Suggested PR body:" + echo "$PR_BODY" diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 7536c60a7..bf2682293 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -25,18 +25,18 @@ jobs: uses: actions-ecosystem/action-add-labels@1a9c3715c0037e96b97bb38cb4c4b56a1f1d4871 # v1.1.0 with: labels: invalid - + - name: Comment restriction uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 with: issue-number: ${{ github.event.pull_request.number }} body: | âš ī¸ **Automerge Restriction Notice** - + The `automerge` label has been removed from this PR because it has restricted use. Only PRs created by `dependabot[bot]` are allowed to use the automerge functionality. - + If you believe this is an error, please contact a repository maintainer. - + auto-merge: if: github.actor == 'dependabot[bot]' && contains(github.event.pull_request.labels.*.name, 'automerge') runs-on: ubuntu-latest @@ -57,9 +57,9 @@ jobs: github-token: ${{ steps.generate_token.outputs.token }} review-message: | 🤖 **Dependabot Auto-merge** - + This PR has been automatically approved and enabled for auto-merge. It will be merged automatically once all required checks pass. - + - name: Enable auto-merge uses: daneden/enable-automerge-action@f8558b65c5b8d8bfb592c4e74e3d491624a38fbd # v1.0.0 with: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..c679b8062 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,20 @@ +name: Make Docs +on: + # the 1st condition + workflow_run: + workflows: ["Continuous Integration"] + branches: [master] + types: + - completed + +jobs: + deploy: + if: github.repository_owner == 'TandoorRecipes' && ${{ github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - run: pip install mkdocs-material mkdocs-include-markdown-plugin + - run: mkdocs gh-deploy --force diff --git a/.github/workflows/push-orchestrator.yml b/.github/workflows/push-orchestrator.yml index 8f6c795d8..2375afd04 100644 --- a/.github/workflows/push-orchestrator.yml +++ b/.github/workflows/push-orchestrator.yml @@ -16,7 +16,7 @@ jobs: pull-requests: read outputs: pr_merged: ${{ steps.detect_pr.outputs.result }} - steps: + steps: - name: Check if commit is part of a PR id: detect_pr uses: actions/github-script@v7 @@ -30,7 +30,7 @@ jobs: const pr = prs.data.find(pr => pr.merged_at); const merged = pr ? 'true' : 'false'; - + // Set the output explicitly core.setOutput('pr_merged', merged); return merged; diff --git a/.github/workflows/stage-branch-for-pr.yml b/.github/workflows/stage-branch-for-pr.yml index 4b7c6fcbd..4f8b278a8 100644 --- a/.github/workflows/stage-branch-for-pr.yml +++ b/.github/workflows/stage-branch-for-pr.yml @@ -242,7 +242,7 @@ jobs: const prBody = process.env.PR_BODY || ''; const repo = process.env.GITHUB_REPOSITORY || ''; const [owner, reponame] = repo.split('/'); - const prLink = `https://github.com/TandoorRecipes/recipes/compare/tandoor-1...${owner}:${branch}?expand=1&title=${encodeURIComponent(prTitle)}&body=${encodeURIComponent(prBody)}`; + const prLink = `https://github.com/TandoorRecipes/recipes/compare/tandoor-1...${owner}:${branch}?expand=1&title=${encodeURIComponent(prTitle)}`; const issueTitle = `Manual Upstream PR Checklist: ${branch}`; const issueBody = [ `A new branch is ready for upstream PR submission.`, diff --git a/cookbook/version_info.py b/cookbook/version_info.py index d606daee7..65c435815 100644 --- a/cookbook/version_info.py +++ b/cookbook/version_info.py @@ -1,3 +1,3 @@ -TANDOOR_VERSION = "cf0401a119ba4024a53dbdf877e4cdb5522f4f32" -TANDOOR_REF = "cf0401a119ba4024a53dbdf877e4cdb5522f4f32" -VERSION_INFO = [{'name': 'Tandoor ', 'version': 'commit cf0401a119ba4024a53dbdf877e4cdb5522f4f32\nAuthor: smilerz \nDate: Fri Mar 22 15:34:54 2024 -0500\n\n python client generation\n', 'website': 'https://github.com/smilerz/recipes', 'commit_link': 'https://github.com/smilerz/recipes/commit/cf0401a119ba4024a53dbdf877e4cdb5522f4f32', 'ref': 'cf0401a119ba4024a53dbdf877e4cdb5522f4f32', 'branch': 'working', 'tag': ''}] \ No newline at end of file +TANDOOR_VERSION = "" +TANDOOR_REF = "" +VERSION_INFO = []