From 55964c66cb00af6c86e4fd1e7ce9ae654a18cf96 Mon Sep 17 00:00:00 2001 From: gavin Date: Fri, 4 Sep 2020 11:55:17 +0530 Subject: [PATCH 01/27] feat: Publish built assets to S3 --- .github/workflows/publish-assets.yml | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/publish-assets.yml diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml new file mode 100644 index 0000000000..b673220286 --- /dev/null +++ b/.github/workflows/publish-assets.yml @@ -0,0 +1,37 @@ +# This workflow will install Python dependencies, run tests and lint with a single version of Python +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +name: Build Assets on develop and Publish to Public bucket + +on: + push: + branches: [ develop ] + +jobs: + build: + runs-on: ubuntu-latest + container: frappe/bench:latest + + steps: + - name: Set up bench + run: | + bench init frappe-bench --skip-assets --python $(which python) + cd frappe-bench/apps/frappe && git checkout $GITHUB_SHA + bench build + + - name: Package assets + run: | + cd frappe-bench/sites/assets + tar -cvpzf $GITHUB_SHA.tar.gz /js /css + + - name: Publish assets + uses: jakejarvis/s3-sync-action@master + with: + args: --acl public-read + env: + AWS_S3_BUCKET: 'frappe-assets' + AWS_ACCESS_KEY_ID: ${{ secrets.S3_ASSETS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_ASSETS_SECRET_ACCESS_KEY }} + AWS_S3_ENDPOINT: 'http://s3.fr-par.scw.cloud' + AWS_REGION: 'fr-par' + SOURCE_DIR: $GITHUB_SHA.tar.gz From 662a7ac56ede1f8c1b5f01006c877cdfdbe1162b Mon Sep 17 00:00:00 2001 From: gavin Date: Fri, 4 Sep 2020 12:02:10 +0530 Subject: [PATCH 02/27] feat: Generate artifacts and publish to S3 --- .github/workflows/publish-assets.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index b673220286..50367566bd 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Set up bench run: | - bench init frappe-bench --skip-assets --python $(which python) + sudo bench init frappe-bench --skip-assets --python $(which python) cd frappe-bench/apps/frappe && git checkout $GITHUB_SHA bench build @@ -34,4 +34,10 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_ASSETS_SECRET_ACCESS_KEY }} AWS_S3_ENDPOINT: 'http://s3.fr-par.scw.cloud' AWS_REGION: 'fr-par' - SOURCE_DIR: $GITHUB_SHA.tar.gz + SOURCE_DIR: frappe-bench/sites/assets/$GITHUB_SHA.tar.gz + + - name: Generate Artifacts + uses: actions/upload-artifact@v2 + with: + name: $GITHUB_SHA.tar.gz + path: frappe-bench/sites/assets/$GITHUB_SHA.tar.gz From 2727fafdc1b2a2b3f6f77bbebc881ff0c9f4f7cf Mon Sep 17 00:00:00 2001 From: gavin Date: Fri, 4 Sep 2020 12:09:20 +0530 Subject: [PATCH 03/27] fix: Run bench as frappe user --- .github/workflows/publish-assets.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index 50367566bd..2f3820a79a 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -15,9 +15,9 @@ jobs: steps: - name: Set up bench run: | - sudo bench init frappe-bench --skip-assets --python $(which python) + sudo -H -u frappe bash -c 'bench init frappe-bench --skip-assets --python $(which python)' cd frappe-bench/apps/frappe && git checkout $GITHUB_SHA - bench build + sudo -H -u frappe bash -c 'bench build' - name: Package assets run: | From f398be17cca4ded53f02636c8f143b3440806a28 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 12:21:12 +0530 Subject: [PATCH 04/27] fix: Don't use bench docker image --- .github/workflows/publish-assets.yml | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index 2f3820a79a..5d395b8696 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -1,23 +1,28 @@ -# This workflow will install Python dependencies, run tests and lint with a single version of Python -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - -name: Build Assets on develop and Publish to Public bucket +name: Build and Publish Assets built on: push: - branches: [ develop ] + branches: [ build-assets ] # for testing only + # branches: [ develop ] jobs: build: runs-on: ubuntu-latest - container: frappe/bench:latest steps: + - uses: actions/setup-node@v1 + with: + python-version: '12.x' + - uses: actions/setup-python@v2 + with: + python-version: '3.x' - name: Set up bench run: | - sudo -H -u frappe bash -c 'bench init frappe-bench --skip-assets --python $(which python)' + npm install -g yarn + pip3 install -U frappe-bench + bench init frappe-bench --skip-assets --python $(which python) cd frappe-bench/apps/frappe && git checkout $GITHUB_SHA - sudo -H -u frappe bash -c 'bench build' + bench build - name: Package assets run: | From e326825fde6001dd5e6c259c8e786b8801c3f08b Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 13:05:09 +0530 Subject: [PATCH 05/27] fix: Reduce bulk --- .github/workflows/publish-assets.yml | 66 ++++++++++++++-------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index 5d395b8696..13469973e9 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -10,39 +10,39 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@v1 - with: - python-version: '12.x' - - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - name: Set up bench - run: | - npm install -g yarn - pip3 install -U frappe-bench - bench init frappe-bench --skip-assets --python $(which python) - cd frappe-bench/apps/frappe && git checkout $GITHUB_SHA - bench build + - uses: actions/setup-node@v1 + with: + python-version: '12.x' + - uses: actions/setup-python@v2 + with: + python-version: '3.6' + - name: Set up bench + run: | + npm install -g yarn + pip3 install -U frappe-bench + bench init frappe-bench --no-procfile --no-backups --skip-assets --skip-redis-config-generation --python $(which python) + cd frappe-bench/apps/frappe && git checkout $GITHUB_SHA + bench build - - name: Package assets - run: | - cd frappe-bench/sites/assets - tar -cvpzf $GITHUB_SHA.tar.gz /js /css + - name: Package assets + run: | + cd frappe-bench/sites/assets + tar -cvpzf $GITHUB_SHA.tar.gz /js /css - - name: Publish assets - uses: jakejarvis/s3-sync-action@master - with: - args: --acl public-read - env: - AWS_S3_BUCKET: 'frappe-assets' - AWS_ACCESS_KEY_ID: ${{ secrets.S3_ASSETS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_ASSETS_SECRET_ACCESS_KEY }} - AWS_S3_ENDPOINT: 'http://s3.fr-par.scw.cloud' - AWS_REGION: 'fr-par' - SOURCE_DIR: frappe-bench/sites/assets/$GITHUB_SHA.tar.gz + - name: Publish assets + uses: jakejarvis/s3-sync-action@master + with: + args: --acl public-read + env: + AWS_S3_BUCKET: 'frappe-assets' + AWS_ACCESS_KEY_ID: ${{ secrets.S3_ASSETS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_ASSETS_SECRET_ACCESS_KEY }} + AWS_S3_ENDPOINT: 'http://s3.fr-par.scw.cloud' + AWS_REGION: 'fr-par' + SOURCE_DIR: frappe-bench/sites/assets/$GITHUB_SHA.tar.gz - - name: Generate Artifacts - uses: actions/upload-artifact@v2 - with: - name: $GITHUB_SHA.tar.gz - path: frappe-bench/sites/assets/$GITHUB_SHA.tar.gz + - name: Generate Artifacts + uses: actions/upload-artifact@v2 + with: + name: $GITHUB_SHA.tar.gz + path: frappe-bench/sites/assets/$GITHUB_SHA.tar.gz From cdecb5cd7bf5567e9459a13e863434d8e9988120 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 13:13:38 +0530 Subject: [PATCH 06/27] fix: Use checkout and --frappe-path --- .github/workflows/publish-assets.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index 13469973e9..07d7ce37e9 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -10,19 +10,21 @@ jobs: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v2 + with: + path: 'frappe' - uses: actions/setup-node@v1 with: python-version: '12.x' - uses: actions/setup-python@v2 with: python-version: '3.6' - - name: Set up bench + - name: Set up bench for current push run: | npm install -g yarn pip3 install -U frappe-bench - bench init frappe-bench --no-procfile --no-backups --skip-assets --skip-redis-config-generation --python $(which python) - cd frappe-bench/apps/frappe && git checkout $GITHUB_SHA - bench build + bench init frappe-bench --no-procfile --no-backups --skip-assets --skip-redis-config-generation --python $(which python) --frappe-path $GITHUB_WORKSPACE/frappe + cd frappe-bench && bench build - name: Package assets run: | From e1f8f6e18bd1ece66a5df99d5d28afbbae8382f0 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 13:23:51 +0530 Subject: [PATCH 07/27] fix: Use relative paths for tarring asset files --- .github/workflows/publish-assets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index 07d7ce37e9..de76274bc8 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -29,7 +29,7 @@ jobs: - name: Package assets run: | cd frappe-bench/sites/assets - tar -cvpzf $GITHUB_SHA.tar.gz /js /css + tar -cvpzf $GITHUB_SHA.tar.gz ./js ./css - name: Publish assets uses: jakejarvis/s3-sync-action@master From ed598fef491555034baebcad81b3d4c9043c9a68 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 13:34:44 +0530 Subject: [PATCH 08/27] fix: Path for builds push and artifacts generation --- .github/workflows/publish-assets.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index de76274bc8..44917ddeef 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -28,8 +28,8 @@ jobs: - name: Package assets run: | - cd frappe-bench/sites/assets - tar -cvpzf $GITHUB_SHA.tar.gz ./js ./css + mkdir -p $GITHUB_WORKSPACE/build + tar -cvpzf $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css - name: Publish assets uses: jakejarvis/s3-sync-action@master @@ -41,10 +41,11 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_ASSETS_SECRET_ACCESS_KEY }} AWS_S3_ENDPOINT: 'http://s3.fr-par.scw.cloud' AWS_REGION: 'fr-par' - SOURCE_DIR: frappe-bench/sites/assets/$GITHUB_SHA.tar.gz + SOURCE_DIR: '$GITHUB_WORKSPACE/build' - name: Generate Artifacts + if: always() uses: actions/upload-artifact@v2 with: name: $GITHUB_SHA.tar.gz - path: frappe-bench/sites/assets/$GITHUB_SHA.tar.gz + path: $GITHUB_WORKSPACE/build From 84b9670b947679990519f085eeff8a255b035e93 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 14:18:08 +0530 Subject: [PATCH 09/27] feat: Add built asset to release made --- .github/workflows/publish-assets.yml | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index 44917ddeef..e3f1f1bc8a 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -1,9 +1,12 @@ -name: Build and Publish Assets built +name: Build and Publish Assets on: push: branches: [ build-assets ] # for testing only # branches: [ develop ] + release: + types: + - published jobs: build: @@ -21,6 +24,7 @@ jobs: python-version: '3.6' - name: Set up bench for current push run: | + echo $GITHUB_EVENT_NAME npm install -g yarn pip3 install -U frappe-bench bench init frappe-bench --no-procfile --no-backups --skip-assets --skip-redis-config-generation --python $(which python) --frappe-path $GITHUB_WORKSPACE/frappe @@ -31,7 +35,8 @@ jobs: mkdir -p $GITHUB_WORKSPACE/build tar -cvpzf $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css - - name: Publish assets + - name: Publish assets to S3 + if: $GITHUB_EVENT_NAME == "pull_request" uses: jakejarvis/s3-sync-action@master with: args: --acl public-read @@ -43,9 +48,20 @@ jobs: AWS_REGION: 'fr-par' SOURCE_DIR: '$GITHUB_WORKSPACE/build' - - name: Generate Artifacts + - name: Attach Assets to Release + if: $GITHUB_EVENT_NAME == "release" + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz + asset_name: assets.tar.gz + tag: ${{ github.ref }} + overwrite: true + body: "Assets automatically generated which may be used to avoid re-building on local benches" + + - name: Generate Action Artifacts if: always() uses: actions/upload-artifact@v2 with: - name: $GITHUB_SHA.tar.gz - path: $GITHUB_WORKSPACE/build + name: assets + path: $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz From 93dcb8663f80272e49caeb354d2de6c7ece08e7a Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 14:47:36 +0530 Subject: [PATCH 10/27] fix: Conditonal expressions for steps --- .github/workflows/publish-assets.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index e3f1f1bc8a..d1f1ba3a11 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -24,7 +24,6 @@ jobs: python-version: '3.6' - name: Set up bench for current push run: | - echo $GITHUB_EVENT_NAME npm install -g yarn pip3 install -U frappe-bench bench init frappe-bench --no-procfile --no-backups --skip-assets --skip-redis-config-generation --python $(which python) --frappe-path $GITHUB_WORKSPACE/frappe @@ -36,7 +35,7 @@ jobs: tar -cvpzf $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css - name: Publish assets to S3 - if: $GITHUB_EVENT_NAME == "pull_request" + if: github.event == 'pull_request' uses: jakejarvis/s3-sync-action@master with: args: --acl public-read @@ -49,7 +48,7 @@ jobs: SOURCE_DIR: '$GITHUB_WORKSPACE/build' - name: Attach Assets to Release - if: $GITHUB_EVENT_NAME == "release" + if: github.event == 'release' uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} From af8d94530b87c89f3b001eaa54a8faf56fd7d7a0 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 15:06:31 +0530 Subject: [PATCH 11/27] fix: ready-for-test --- .github/workflows/publish-assets.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets.yml index d1f1ba3a11..8155d36f35 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets.yml @@ -2,8 +2,7 @@ name: Build and Publish Assets on: push: - branches: [ build-assets ] # for testing only - # branches: [ develop ] + branches: [ develop ] release: types: - published From 997e5b9c48143e87349acb2ae518ec6656ebb807 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 15:18:31 +0530 Subject: [PATCH 12/27] fix: Seperate workflows for releases and develop --- ...-assets.yml => publish-assets-develop.yml} | 22 ---------- .github/workflows/publish-assets-releases.yml | 42 +++++++++++++++++++ 2 files changed, 42 insertions(+), 22 deletions(-) rename .github/workflows/{publish-assets.yml => publish-assets-develop.yml} (65%) create mode 100644 .github/workflows/publish-assets-releases.yml diff --git a/.github/workflows/publish-assets.yml b/.github/workflows/publish-assets-develop.yml similarity index 65% rename from .github/workflows/publish-assets.yml rename to .github/workflows/publish-assets-develop.yml index 8155d36f35..f13d98e6a5 100644 --- a/.github/workflows/publish-assets.yml +++ b/.github/workflows/publish-assets-develop.yml @@ -3,9 +3,6 @@ name: Build and Publish Assets on: push: branches: [ develop ] - release: - types: - - published jobs: build: @@ -34,7 +31,6 @@ jobs: tar -cvpzf $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css - name: Publish assets to S3 - if: github.event == 'pull_request' uses: jakejarvis/s3-sync-action@master with: args: --acl public-read @@ -45,21 +41,3 @@ jobs: AWS_S3_ENDPOINT: 'http://s3.fr-par.scw.cloud' AWS_REGION: 'fr-par' SOURCE_DIR: '$GITHUB_WORKSPACE/build' - - - name: Attach Assets to Release - if: github.event == 'release' - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz - asset_name: assets.tar.gz - tag: ${{ github.ref }} - overwrite: true - body: "Assets automatically generated which may be used to avoid re-building on local benches" - - - name: Generate Action Artifacts - if: always() - uses: actions/upload-artifact@v2 - with: - name: assets - path: $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz diff --git a/.github/workflows/publish-assets-releases.yml b/.github/workflows/publish-assets-releases.yml new file mode 100644 index 0000000000..faeba15af4 --- /dev/null +++ b/.github/workflows/publish-assets-releases.yml @@ -0,0 +1,42 @@ +name: Build and Publish Assets built for releases + +on: + release: + types: + - created + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + path: 'frappe' + - uses: actions/setup-node@v1 + with: + python-version: '12.x' + - uses: actions/setup-python@v2 + with: + python-version: '3.6' + - name: Set up bench for current push + run: | + npm install -g yarn + pip3 install -U frappe-bench + bench init frappe-bench --no-procfile --no-backups --skip-assets --skip-redis-config-generation --python $(which python) --frappe-path $GITHUB_WORKSPACE/frappe + cd frappe-bench && bench build + + - name: Package assets + run: | + mkdir -p $GITHUB_WORKSPACE/build + tar -cvpzf $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css + + - name: Attach Assets to Release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_ASSETS_TOKEN }} + file: $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz + asset_name: assets.tar.gz + tag: ${{ github.ref }} + overwrite: true + body: "Assets automatically generated which may be used to avoid re-building on local benches" From 1b90e713c639d02c7a052f3ab99d3d8112e5ac23 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 15:47:06 +0530 Subject: [PATCH 13/27] fix: Use Github token --- .github/workflows/publish-assets-develop.yml | 2 +- .github/workflows/publish-assets-releases.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-assets-develop.yml b/.github/workflows/publish-assets-develop.yml index f13d98e6a5..8546011ebe 100644 --- a/.github/workflows/publish-assets-develop.yml +++ b/.github/workflows/publish-assets-develop.yml @@ -1,4 +1,4 @@ -name: Build and Publish Assets +name: Build and Publish Assets for Development on: push: diff --git a/.github/workflows/publish-assets-releases.yml b/.github/workflows/publish-assets-releases.yml index faeba15af4..c914133fbf 100644 --- a/.github/workflows/publish-assets-releases.yml +++ b/.github/workflows/publish-assets-releases.yml @@ -1,4 +1,4 @@ -name: Build and Publish Assets built for releases +name: Build and Publish Assets built for Releases on: release: @@ -34,7 +34,7 @@ jobs: - name: Attach Assets to Release uses: svenstaro/upload-release-action@v2 with: - repo_token: ${{ secrets.GITHUB_ASSETS_TOKEN }} + repo_token: ${{ secrets.GITHUB_TOKEN }} file: $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz asset_name: assets.tar.gz tag: ${{ github.ref }} From 3cf9569e4946949916d4eaa5f83ae180913eb8f6 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Fri, 4 Sep 2020 16:04:10 +0530 Subject: [PATCH 14/27] fix: Use a different action to attach built asset --- .github/workflows/publish-assets-releases.yml | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish-assets-releases.yml b/.github/workflows/publish-assets-releases.yml index c914133fbf..5c412ea1b0 100644 --- a/.github/workflows/publish-assets-releases.yml +++ b/.github/workflows/publish-assets-releases.yml @@ -2,8 +2,10 @@ name: Build and Publish Assets built for Releases on: release: - types: - - created + types: [ created ] + +env: + GITHUB_TOKEN: ${{ github.token }} jobs: build: @@ -29,14 +31,17 @@ jobs: - name: Package assets run: | mkdir -p $GITHUB_WORKSPACE/build - tar -cvpzf $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css + tar -cvpzf $GITHUB_WORKSPACE/build/assets.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css - - name: Attach Assets to Release - uses: svenstaro/upload-release-action@v2 + - name: Get release + id: get_release + uses: bruceadams/get-release@v1.2.0 + + - name: Upload built Assets to Release + uses: actions/upload-release-asset@v1.0.2 with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz + upload_url: ${{ steps.get_release.outputs.upload_url }} + asset_path: build/assets.tar.gz asset_name: assets.tar.gz - tag: ${{ github.ref }} - overwrite: true - body: "Assets automatically generated which may be used to avoid re-building on local benches" + asset_content_type: application/octet-stream + From 8a9545afdb457f177740cc825f393369d4660977 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Sep 2020 15:10:54 +0530 Subject: [PATCH 15/27] fix: Change assets endpoint --- .github/workflows/publish-assets-develop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-assets-develop.yml b/.github/workflows/publish-assets-develop.yml index 8546011ebe..522cfc815c 100644 --- a/.github/workflows/publish-assets-develop.yml +++ b/.github/workflows/publish-assets-develop.yml @@ -38,6 +38,6 @@ jobs: AWS_S3_BUCKET: 'frappe-assets' AWS_ACCESS_KEY_ID: ${{ secrets.S3_ASSETS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_ASSETS_SECRET_ACCESS_KEY }} - AWS_S3_ENDPOINT: 'http://s3.fr-par.scw.cloud' + AWS_S3_ENDPOINT: 'http://assets.frappeframework.com' AWS_REGION: 'fr-par' SOURCE_DIR: '$GITHUB_WORKSPACE/build' From f53fe3e854572e67e7ec61cbee037e8ca3f7b160 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Sep 2020 15:14:37 +0530 Subject: [PATCH 16/27] feat: Ship Built Assets --- frappe/build.py | 136 ++++++++++++++++++++++++++++++++++----- frappe/commands/utils.py | 12 +++- rollup/build.js | 48 ++++++++++++-- rollup/config.js | 28 +++++++- 4 files changed, 202 insertions(+), 22 deletions(-) diff --git a/frappe/build.py b/frappe/build.py index 761541f7a9..7bfffb3c8c 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -11,24 +11,129 @@ import warnings import tempfile from distutils.spawn import find_executable -from six import iteritems, text_type - import frappe from frappe.utils.minify import JavascriptMinify +import click +from requests import get +from six import iteritems, text_type +from six.moves.urllib.parse import urlparse + timestamps = {} app_paths = None +sites_path = os.path.abspath(os.getcwd()) + + +def download_file(url, prefix): + filename = urlparse(url).path.split("/")[-1] + local_filename = os.path.join(prefix, filename) + with get(url, stream=True, allow_redirects=True) as r: + r.raise_for_status() + with open(local_filename, "wb") as f: + for chunk in r.iter_content(chunk_size=8192): + f.write(chunk) + return local_filename + + +def exists(url): + from requests import head + return head(url, allow_redirects=True) + + +def build_missing_files(): + # check which files dont exist yet from the build.json and tell build.js to build only those! + missing_assets = [] + current_asset_files = [ + "js/{0}".format(x) for x in os.listdir(os.path.join(sites_path, "assets", "js")) + ] + [ + "css/{0}".format(x) for x in os.listdir(os.path.join(sites_path, "assets", "css")) + ] + + with open(os.path.join(sites_path, "assets", "frappe", "build.json")) as f: + all_asset_files = json.load(f).keys() + + for asset in all_asset_files: + if asset.replace("concat:", "") not in current_asset_files: + missing_assets.append(asset) + + if missing_assets: + from subprocess import check_call + from shlex import split + + click.secho("Building Missing Assets...", fg="yellow") + command = split( + "node rollup/build.js --files {0} --no-concat".format(",".join(missing_assets)) + ) + check_call(command, cwd=os.path.join("..", "apps", "frappe")) + + +def download_frappe_assets(): + """Downloads and sets up Frappe assets if they exist based on the current + commit HEAD. + Returns True if correctly setup else returns False. + """ + from subprocess import getoutput + + frappe_head = getoutput("cd ../apps/frappe && git rev-parse HEAD") + exc = False + + if frappe_head: + from tempfile import mkdtemp + + tag = getoutput( + "cd ../apps/frappe && git show-ref --tags -d | grep %s | sed -e 's,.*" + " refs/tags/,,' -e 's/\^{}//'" + % frappe_head + ) + + if tag: + # if tag exists, download assets from github release + url = "https://github.com/frappe/frappe/releases/{0}/assets.tar.gz".format(tag) + else: + url = "http://assets.frappeframework.com/{0}.tar.gz".format(frappe_head) + + try: + click.secho("Retreiving Assets...", fg="yellow") + + if not exists(url): + return False + + prefix = mkdtemp(prefix="frappe-assets-", suffix=frappe_head) + assets_archive = download_file(url, prefix) + + if assets_archive: + import subprocess + + click.secho("Extracting Assets...", fg="yellow") + subprocess.check_output( + ["tar", "xf", assets_archive, "--strip", "3"], cwd=sites_path + ) + build_missing_files() + return True + else: + raise + except Exception: + exc = True + click.secho("No Assets Found...Building...", fg="yellow") + print(frappe.get_traceback()) + finally: + try: + shutil.rmtree(os.path.dirname(assets_archive)) + except Exception: + pass + + return not exc def symlink(target, link_name, overwrite=False): - ''' + """ Create a symbolic link named link_name pointing to target. If link_name exists then FileExistsError is raised, unless overwrite=True. When trying to overwrite a directory, IsADirectoryError is raised. Source: https://stackoverflow.com/a/55742015/10309266 - ''' + """ if not overwrite: return os.symlink(target, link_name) @@ -76,27 +181,28 @@ def setup(): def get_node_pacman(): - pacmans = ['yarn', 'npm'] - for exec_ in pacmans: - exec_ = find_executable(exec_) - if exec_: - return exec_ - raise ValueError('No Node.js Package Manager found.') + exec_ = find_executable("yarn") + if exec_: + return exec_ + raise ValueError("Yarn not found") -def bundle(no_compress, app=None, make_copy=False, restore=False, verbose=False): +def bundle(no_compress, app=None, make_copy=False, restore=False, verbose=False, skip_frappe=False): """concat / minify js files""" setup() make_asset_dirs(make_copy=make_copy, restore=restore) pacman = get_node_pacman() - mode = 'build' if no_compress else 'production' - command = '{pacman} run {mode}'.format(pacman=pacman, mode=mode) + mode = "build" if no_compress else "production" + command = "{pacman} run {mode}".format(pacman=pacman, mode=mode) if app: - command += ' --app {app}'.format(app=app) + command += " --app {app}".format(app=app) - frappe_app_path = os.path.abspath(os.path.join(app_paths[0], '..')) + if skip_frappe: + command += " --skip_frappe" + + frappe_app_path = os.path.abspath(os.path.join(app_paths[0], "..")) check_yarn() frappe.commands.popen(command, cwd=frappe_app_path) diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 721376016c..d688d1ab0c 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -19,14 +19,22 @@ from six import StringIO @click.option('--make-copy', is_flag=True, default=False, help='Copy the files instead of symlinking') @click.option('--restore', is_flag=True, default=False, help='Copy the files instead of symlinking with force') @click.option('--verbose', is_flag=True, default=False, help='Verbose') -def build(app=None, make_copy=False, restore = False, verbose=False): +@click.option('--force', is_flag=True, default=False, help='Force build assets instead of downloading available') +def build(app=None, make_copy=False, restore=False, verbose=False, force=False): "Minify + concatenate JS and CSS files, build translations" import frappe.build import frappe frappe.init('') # don't minify in developer_mode for faster builds no_compress = frappe.local.conf.developer_mode or False - frappe.build.bundle(no_compress, app=app, make_copy=make_copy, restore = restore, verbose=verbose) + + if not (force or app): + # skip building frappe if assets exist remotely + skip_frappe = frappe.build.download_frappe_assets() + else: + skip_frappe = False + + frappe.build.bundle(no_compress, app=app, make_copy=make_copy, restore = restore, verbose=verbose, skip_frappe=skip_frappe) @click.command('watch') diff --git a/rollup/build.js b/rollup/build.js index ea1ac54c09..5fdfe80790 100644 --- a/rollup/build.js +++ b/rollup/build.js @@ -15,17 +15,35 @@ const { } = require('./rollup.utils'); const { - get_options_for + get_options_for, + get_options } = require('./config'); -const build_for_app = process.argv[2] === '--app' ? process.argv[3] : null; +const skip_frappe = process.argv.includes("--skip_frappe") + +if (skip_frappe) { + let idx = apps_list.indexOf("frappe"); + if (idx > -1) { + apps_list.splice(idx, 1); + } +} + +const exists = (flag) => process.argv.indexOf(flag) != -1 +const value = (flag) => (process.argv.indexOf(flag) != -1) ? process.argv[process.argv.indexOf(flag) + 1] : null; + +const files = exists("--files") ? value("--files").split(",") : false; +const build_for_app = exists("--app") ? value("--app") : null; +const concat = !exists("--no-concat"); show_production_message(); ensure_js_css_dirs(); -concatenate_files(); +if (concat) concatenate_files(); create_build_file(); -if (build_for_app) { + +if (files) { + build_files(files); +} else if (build_for_app) { build_assets_for_app(build_for_app) .then(() => { run_build_command_for_app(build_for_app); @@ -68,6 +86,28 @@ function build_assets(app) { }); } +function build_files(files, app="frappe") { + for (let file of files) { + let options = get_options(file, app); + if (!options.length) return Promise.resolve(); + log(chalk.yellow(`\nBuilding ${app} assets...\n`)); + + let promises = options.map(({ inputOptions, outputOptions, output_file}) => { + return build(inputOptions, outputOptions) + .then(() => { + log(`${chalk.green('✔')} Built ${output_file}`); + }); + }); + + let start = Date.now(); + return Promise.all(promises) + .then(() => { + let time = Date.now() - start; + log(chalk.green(`✨ Done in ${time / 1000}s`)); + }); + } +} + function build(inputOptions, outputOptions) { return rollup.rollup(inputOptions) .then(bundle => bundle.write(outputOptions)) diff --git a/rollup/config.js b/rollup/config.js index b1816cb4c6..cdeb8eb952 100644 --- a/rollup/config.js +++ b/rollup/config.js @@ -165,6 +165,31 @@ function get_rollup_options_for_css(output_file, input_files) { }; } +function get_options(file, app="frappe") { + const build_json = get_build_json(app); + if (!build_json) return []; + + return Object.keys(build_json) + .map(output_file => { + if (output_file === file) { + if (output_file.startsWith('concat:')) return null; + const input_files = build_json[output_file] + .map(input_file => { + let prefix = get_app_path(app); + if (input_file.startsWith('node_modules/')) { + prefix = path.resolve(get_app_path(app), '..'); + } + return path.resolve(prefix, input_file); + }); + return Object.assign( + get_rollup_options(output_file, input_files), { + output_file + }); + } + }) + .filter(Boolean); +} + function get_options_for(app) { const build_json = get_build_json(app); if (!build_json) return []; @@ -205,5 +230,6 @@ function ignore_css() { }; module.exports = { - get_options_for + get_options_for, + get_options }; From e9cba25b59d59491d8f6a0aae0920feacd852012 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Sep 2020 15:15:46 +0530 Subject: [PATCH 17/27] style: Black --- frappe/build.py | 84 +++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/frappe/build.py b/frappe/build.py index 7bfffb3c8c..7aa3b430a7 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -213,22 +213,22 @@ def watch(no_compress): pacman = get_node_pacman() - frappe_app_path = os.path.abspath(os.path.join(app_paths[0], '..')) + frappe_app_path = os.path.abspath(os.path.join(app_paths[0], "..")) check_yarn() - frappe_app_path = frappe.get_app_path('frappe', '..') - frappe.commands.popen('{pacman} run watch'.format(pacman=pacman), cwd=frappe_app_path) + frappe_app_path = frappe.get_app_path("frappe", "..") + frappe.commands.popen("{pacman} run watch".format(pacman=pacman), cwd=frappe_app_path) def check_yarn(): - if not find_executable('yarn'): - print('Please install yarn using below command and try again.\nnpm install -g yarn') + if not find_executable("yarn"): + print("Please install yarn using below command and try again.\nnpm install -g yarn") def make_asset_dirs(make_copy=False, restore=False): # don't even think of making assets_path absolute - rm -rf ahead. assets_path = os.path.join(frappe.local.sites_path, "assets") - for dir_path in [os.path.join(assets_path, 'js'), os.path.join(assets_path, 'css')]: + for dir_path in [os.path.join(assets_path, "js"), os.path.join(assets_path, "css")]: if not os.path.exists(dir_path): os.makedirs(dir_path) @@ -237,24 +237,27 @@ def make_asset_dirs(make_copy=False, restore=False): app_base_path = os.path.abspath(os.path.dirname(pymodule.__file__)) symlinks = [] - app_public_path = os.path.join(app_base_path, 'public') + app_public_path = os.path.join(app_base_path, "public") # app/public > assets/app symlinks.append([app_public_path, os.path.join(assets_path, app_name)]) # app/node_modules > assets/app/node_modules if os.path.exists(os.path.abspath(app_public_path)): - symlinks.append([os.path.join(app_base_path, '..', 'node_modules'), os.path.join( - assets_path, app_name, 'node_modules')]) + symlinks.append( + [ + os.path.join(app_base_path, "..", "node_modules"), + os.path.join(assets_path, app_name, "node_modules"), + ] + ) app_doc_path = None - if os.path.isdir(os.path.join(app_base_path, 'docs')): - app_doc_path = os.path.join(app_base_path, 'docs') + if os.path.isdir(os.path.join(app_base_path, "docs")): + app_doc_path = os.path.join(app_base_path, "docs") - elif os.path.isdir(os.path.join(app_base_path, 'www', 'docs')): - app_doc_path = os.path.join(app_base_path, 'www', 'docs') + elif os.path.isdir(os.path.join(app_base_path, "www", "docs")): + app_doc_path = os.path.join(app_base_path, "www", "docs") if app_doc_path: - symlinks.append([app_doc_path, os.path.join( - assets_path, app_name + '_docs')]) + symlinks.append([app_doc_path, os.path.join(assets_path, app_name + "_docs")]) for source, target in symlinks: source = os.path.abspath(source) @@ -268,7 +271,7 @@ def make_asset_dirs(make_copy=False, restore=False): shutil.copytree(source, target) elif make_copy: if os.path.exists(target): - warnings.warn('Target {target} already exists.'.format(target=target)) + warnings.warn("Target {target} already exists.".format(target=target)) else: shutil.copytree(source, target) else: @@ -280,7 +283,7 @@ def make_asset_dirs(make_copy=False, restore=False): try: symlink(source, target, overwrite=True) except OSError: - print('Cannot link {} to {}'.format(source, target)) + print("Cannot link {} to {}".format(source, target)) else: # warnings.warn('Source {source} does not exist.'.format(source = source)) pass @@ -299,7 +302,7 @@ def get_build_maps(): build_maps = {} for app_path in app_paths: - path = os.path.join(app_path, 'public', 'build.json') + path = os.path.join(app_path, "public", "build.json") if os.path.exists(path): with open(path) as f: try: @@ -308,8 +311,7 @@ def get_build_maps(): source_paths = [] for source in sources: if isinstance(source, list): - s = frappe.get_pymodule_path( - source[0], *source[1].split("/")) + s = frappe.get_pymodule_path(source[0], *source[1].split("/")) else: s = os.path.join(app_path, source) source_paths.append(s) @@ -317,36 +319,42 @@ def get_build_maps(): build_maps[target] = source_paths except ValueError as e: print(path) - print('JSON syntax error {0}'.format(str(e))) + print("JSON syntax error {0}".format(str(e))) return build_maps def pack(target, sources, no_compress, verbose): from six import StringIO - outtype, outtxt = target.split(".")[-1], '' + outtype, outtxt = target.split(".")[-1], "" jsm = JavascriptMinify() for f in sources: suffix = None - if ':' in f: - f, suffix = f.split(':') + if ":" in f: + f, suffix = f.split(":") if not os.path.exists(f) or os.path.isdir(f): print("did not find " + f) continue timestamps[f] = os.path.getmtime(f) try: - with open(f, 'r') as sourcefile: - data = text_type(sourcefile.read(), 'utf-8', errors='ignore') + with open(f, "r") as sourcefile: + data = text_type(sourcefile.read(), "utf-8", errors="ignore") extn = f.rsplit(".", 1)[1] - if outtype == "js" and extn == "js" and (not no_compress) and suffix != "concat" and (".min." not in f): - tmpin, tmpout = StringIO(data.encode('utf-8')), StringIO() + if ( + outtype == "js" + and extn == "js" + and (not no_compress) + and suffix != "concat" + and (".min." not in f) + ): + tmpin, tmpout = StringIO(data.encode("utf-8")), StringIO() jsm.minify(tmpin, tmpout) minified = tmpout.getvalue() if minified: - outtxt += text_type(minified or '', 'utf-8').strip('\n') + ';' + outtxt += text_type(minified or "", "utf-8").strip("\n") + ";" if verbose: print("{0}: {1}k".format(f, int(len(minified) / 1024))) @@ -354,27 +362,27 @@ def pack(target, sources, no_compress, verbose): # add to frappe.templates outtxt += html_to_js_template(f, data) else: - outtxt += ('\n/*\n *\t%s\n */' % f) - outtxt += '\n' + data + '\n' + outtxt += "\n/*\n *\t%s\n */" % f + outtxt += "\n" + data + "\n" except Exception: print("--Error in:" + f + "--") print(frappe.get_traceback()) - with open(target, 'w') as f: + with open(target, "w") as f: f.write(outtxt.encode("utf-8")) - print("Wrote %s - %sk" % (target, str(int(os.path.getsize(target)/1024)))) + print("Wrote %s - %sk" % (target, str(int(os.path.getsize(target) / 1024)))) def html_to_js_template(path, content): - '''returns HTML template content as Javascript code, adding it to `frappe.templates`''' + """returns HTML template content as Javascript code, adding it to `frappe.templates`""" return """frappe.templates["{key}"] = '{content}';\n""".format( key=path.rsplit("/", 1)[-1][:-5], content=scrub_html_template(content)) def scrub_html_template(content): - '''Returns HTML content with removed whitespace and comments''' + """Returns HTML content with removed whitespace and comments""" # remove whitespace to a single space content = re.sub("\s+", " ", content) @@ -387,12 +395,12 @@ def scrub_html_template(content): def files_dirty(): for target, sources in iteritems(get_build_maps()): for f in sources: - if ':' in f: - f, suffix = f.split(':') + if ":" in f: + f, suffix = f.split(":") if not os.path.exists(f) or os.path.isdir(f): continue if os.path.getmtime(f) != timestamps.get(f): - print(f + ' dirty') + print(f + " dirty") return True else: return False From a7e0e96e4990ed2563000fcda673c7e9807eebae Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Sep 2020 15:16:00 +0530 Subject: [PATCH 18/27] chore: Drop dead code --- frappe/utils/change_log.py | 1 - frappe/utils/gitutils.py | 24 ------------------------ 2 files changed, 25 deletions(-) delete mode 100644 frappe/utils/gitutils.py diff --git a/frappe/utils/change_log.py b/frappe/utils/change_log.py index c75b3289db..29fee2bac0 100644 --- a/frappe/utils/change_log.py +++ b/frappe/utils/change_log.py @@ -9,7 +9,6 @@ import frappe import requests import subprocess # nosec from frappe.utils import cstr -from frappe.utils.gitutils import get_app_branch from frappe import _, safe_decode diff --git a/frappe/utils/gitutils.py b/frappe/utils/gitutils.py deleted file mode 100644 index 10268a6581..0000000000 --- a/frappe/utils/gitutils.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import unicode_literals - -import subprocess - -def get_app_branch(app): - '''Returns branch of an app''' - try: - branch = subprocess.check_output('cd ../apps/{0} && git rev-parse --abbrev-ref HEAD'.format(app), - shell=True) - branch = branch.decode('utf-8') - branch = branch.strip() - return branch - except Exception: - return '' - -def get_app_last_commit_ref(app): - try: - commit_id = subprocess.check_output('cd ../apps/{0} && git rev-parse HEAD'.format(app), - shell=True) - commit_id = commit_id.decode('utf-8') - commit_id = commit_id.strip()[:7] - return commit_id - except Exception: - return '' From fe44d2b97d0478a438cb80f5bbfbcd6750d17552 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Sep 2020 15:25:47 +0530 Subject: [PATCH 19/27] chore: Optimize imports --- frappe/commands/utils.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index d688d1ab0c..1affeb5a5e 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -1,17 +1,17 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals, absolute_import, print_function -import click -import json, os, sys, subprocess +import json +import os +import subprocess +import sys from distutils.spawn import find_executable + +import click + import frappe -from frappe.commands import pass_context, get_site +from frappe.commands import get_site, pass_context from frappe.exceptions import SiteNotSpecifiedError -from frappe.utils import update_progress_bar, get_bench_path -from frappe.utils.response import json_handler -from coverage import Coverage -import cProfile, pstats -from six import StringIO +from frappe.utils import get_bench_path, update_progress_bar @click.command('build') @@ -23,7 +23,6 @@ from six import StringIO def build(app=None, make_copy=False, restore=False, verbose=False, force=False): "Minify + concatenate JS and CSS files, build translations" import frappe.build - import frappe frappe.init('') # don't minify in developer_mode for faster builds no_compress = frappe.local.conf.developer_mode or False @@ -34,7 +33,7 @@ def build(app=None, make_copy=False, restore=False, verbose=False, force=False): else: skip_frappe = False - frappe.build.bundle(no_compress, app=app, make_copy=make_copy, restore = restore, verbose=verbose, skip_frappe=skip_frappe) + frappe.build.bundle(no_compress, app=app, make_copy=make_copy, restore=restore, verbose=verbose, skip_frappe=skip_frappe) @click.command('watch') @@ -159,12 +158,16 @@ def execute(context, method, args=None, kwargs=None, profile=False): kwargs = {} if profile: + import cProfile pr = cProfile.Profile() pr.enable() ret = frappe.get_attr(method)(*args, **kwargs) if profile: + import pstats + from six import StringIO + pr.disable() s = StringIO() pstats.Stats(pr, stream=s).sort_stats('cumulative').print_stats(.5) @@ -175,6 +178,7 @@ def execute(context, method, args=None, kwargs=None, profile=False): finally: frappe.destroy() if ret: + from frappe.utils.response import json_handler print(json.dumps(ret, default=json_handler)) if not context.sites: @@ -500,6 +504,8 @@ def run_tests(context, app=None, module=None, doctype=None, test=(), frappe.flags.skip_test_records = skip_test_records if coverage: + from coverage import Coverage + # Generate coverage report only for app that is being tested source_path = os.path.join(get_bench_path(), 'apps', app or 'frappe') cov = Coverage(source=[source_path], omit=[ From f975da1cbfcc99827ea80787febd8469095a36a9 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Sep 2020 16:55:43 +0530 Subject: [PATCH 20/27] fix: URL Fixes and code restructure --- frappe/build.py | 88 ++++++++++++++++++++++++---------------- frappe/commands/utils.py | 2 +- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/frappe/build.py b/frappe/build.py index 7aa3b430a7..242c83b15d 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -36,19 +36,18 @@ def download_file(url, prefix): return local_filename -def exists(url): - from requests import head - return head(url, allow_redirects=True) - - def build_missing_files(): # check which files dont exist yet from the build.json and tell build.js to build only those! missing_assets = [] - current_asset_files = [ - "js/{0}".format(x) for x in os.listdir(os.path.join(sites_path, "assets", "js")) - ] + [ - "css/{0}".format(x) for x in os.listdir(os.path.join(sites_path, "assets", "css")) - ] + current_asset_files = [] + + for type in ["css", "js"]: + current_asset_files.extend( + [ + "{0}/{0}".format(type, name) + for name in os.listdir(os.path.join(sites_path, "assets", type)) + ] + ) with open(os.path.join(sites_path, "assets", "frappe", "build.json")) as f: all_asset_files = json.load(f).keys() @@ -68,37 +67,59 @@ def build_missing_files(): check_call(command, cwd=os.path.join("..", "apps", "frappe")) -def download_frappe_assets(): - """Downloads and sets up Frappe assets if they exist based on the current - commit HEAD. - Returns True if correctly setup else returns False. - """ +def get_assets_link(frappe_head): from subprocess import getoutput + from requests import head - frappe_head = getoutput("cd ../apps/frappe && git rev-parse HEAD") - exc = False - - if frappe_head: - from tempfile import mkdtemp - - tag = getoutput( + tag = getoutput( "cd ../apps/frappe && git show-ref --tags -d | grep %s | sed -e 's,.*" " refs/tags/,,' -e 's/\^{}//'" % frappe_head ) - if tag: - # if tag exists, download assets from github release - url = "https://github.com/frappe/frappe/releases/{0}/assets.tar.gz".format(tag) - else: - url = "http://assets.frappeframework.com/{0}.tar.gz".format(frappe_head) + if tag: + # if tag exists, download assets from github release + url = "https://github.com/frappe/frappe/releases/download/{0}/assets.tar.gz".format(tag) + else: + url = "http://assets.frappeframework.com/{0}.tar.gz".format(frappe_head) + if not head(url): + raise ValueError("URL {0} doesn't exist".format(url)) + + return url + + +def handle_verbosity(): + import sys + import wrapt + + @wrapt.decorator + def verbosity(wrapped, instance, args, kwargs): + verbose = kwargs.get("verbose") or False + if not verbose: + sys.stdout = open(os.devnull, "wb") + ret = wrapped(*args, **kwargs) + sys.stdout = sys.__stdout__ + return ret + + return verbosity + +@handle_verbosity() +def download_frappe_assets(verbose=True): + """Downloads and sets up Frappe assets if they exist based on the current + commit HEAD. + Returns True if correctly setup else returns False. + """ + from subprocess import getoutput + from tempfile import mkdtemp + + assets_setup = False + frappe_head = getoutput("cd ../apps/frappe && git rev-parse HEAD") + + if frappe_head: try: + url = get_assets_link(frappe_head) click.secho("Retreiving Assets...", fg="yellow") - - if not exists(url): - return False - prefix = mkdtemp(prefix="frappe-assets-", suffix=frappe_head) assets_archive = download_file(url, prefix) @@ -114,8 +135,7 @@ def download_frappe_assets(): else: raise except Exception: - exc = True - click.secho("No Assets Found...Building...", fg="yellow") + assets_setup = False print(frappe.get_traceback()) finally: try: @@ -123,7 +143,7 @@ def download_frappe_assets(): except Exception: pass - return not exc + return assets_setup def symlink(target, link_name, overwrite=False): diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 1affeb5a5e..9f781d7475 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -29,7 +29,7 @@ def build(app=None, make_copy=False, restore=False, verbose=False, force=False): if not (force or app): # skip building frappe if assets exist remotely - skip_frappe = frappe.build.download_frappe_assets() + skip_frappe = frappe.build.download_frappe_assets(verbose=verbose) else: skip_frappe = False From 1c3bc937d98aa10434d65d63a55acbf4f938bed3 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 7 Sep 2020 17:05:28 +0530 Subject: [PATCH 21/27] fix: Sider --- frappe/build.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frappe/build.py b/frappe/build.py index 242c83b15d..82075d3ee4 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -44,7 +44,7 @@ def build_missing_files(): for type in ["css", "js"]: current_asset_files.extend( [ - "{0}/{0}".format(type, name) + "{0}/{1}".format(type, name) for name in os.listdir(os.path.join(sites_path, "assets", type)) ] ) @@ -136,7 +136,6 @@ def download_frappe_assets(verbose=True): raise except Exception: assets_setup = False - print(frappe.get_traceback()) finally: try: shutil.rmtree(os.path.dirname(assets_archive)) From 1fa5ca0ef708e9beb816dbd23a35ae183011701b Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Tue, 8 Sep 2020 15:29:09 +0530 Subject: [PATCH 22/27] fix: Use tarfile lib instead of tar UNIX tool style: Fix UX to show more outputs --- frappe/build.py | 17 ++++++++++++----- requirements.txt | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/frappe/build.py b/frappe/build.py index 82075d3ee4..4a8d88baf3 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -104,12 +104,13 @@ def handle_verbosity(): return verbosity -@handle_verbosity() + def download_frappe_assets(verbose=True): """Downloads and sets up Frappe assets if they exist based on the current commit HEAD. Returns True if correctly setup else returns False. """ + from simple_chalk import green from subprocess import getoutput from tempfile import mkdtemp @@ -122,14 +123,20 @@ def download_frappe_assets(verbose=True): click.secho("Retreiving Assets...", fg="yellow") prefix = mkdtemp(prefix="frappe-assets-", suffix=frappe_head) assets_archive = download_file(url, prefix) + print("{0} Downloaded assets archive from {1}".format(green('✔'), url)) if assets_archive: - import subprocess + import tarfile click.secho("Extracting Assets...", fg="yellow") - subprocess.check_output( - ["tar", "xf", assets_archive, "--strip", "3"], cwd=sites_path - ) + with tarfile.open(assets_archive) as tar: + for file in tar: + if not file.isdir(): + dest = "." + file.name.replace("./frappe-bench/sites", "") + show = dest.replace("./assets/", "") + tar.makefile(file, dest) + print("{0} Restored {1}".format(green('✔'), show)) + build_missing_files() return True else: diff --git a/requirements.txt b/requirements.txt index af3104cce7..77c80d5911 100644 --- a/requirements.txt +++ b/requirements.txt @@ -57,6 +57,7 @@ RestrictedPython==5.0 rq>=1.1.0 schedule==0.6.0 semantic-version==2.8.4 +simple-chalk==0.1.0 six==1.14.0 sqlparse==0.2.4 stripe==2.40.0 From 5cf3b2416c6e10766b3e39c38bc015947823d287 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Tue, 8 Sep 2020 15:30:09 +0530 Subject: [PATCH 23/27] chore: Drop dead code --- frappe/build.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/frappe/build.py b/frappe/build.py index 4a8d88baf3..2646d67a6c 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -89,22 +89,6 @@ def get_assets_link(frappe_head): return url -def handle_verbosity(): - import sys - import wrapt - - @wrapt.decorator - def verbosity(wrapped, instance, args, kwargs): - verbose = kwargs.get("verbose") or False - if not verbose: - sys.stdout = open(os.devnull, "wb") - ret = wrapped(*args, **kwargs) - sys.stdout = sys.__stdout__ - return ret - - return verbosity - - def download_frappe_assets(verbose=True): """Downloads and sets up Frappe assets if they exist based on the current commit HEAD. From 7f61fa68fceaedfc06658d8c4dfc2f94b16615cd Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Wed, 9 Sep 2020 11:27:19 +0530 Subject: [PATCH 24/27] fix: Consistent spacing and cases for messages --- frappe/build.py | 8 ++++---- rollup/build.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frappe/build.py b/frappe/build.py index 2646d67a6c..b58b3ed3a2 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -60,7 +60,7 @@ def build_missing_files(): from subprocess import check_call from shlex import split - click.secho("Building Missing Assets...", fg="yellow") + click.secho("\nBuilding missing assets...\n", fg="yellow") command = split( "node rollup/build.js --files {0} --no-concat".format(",".join(missing_assets)) ) @@ -104,15 +104,15 @@ def download_frappe_assets(verbose=True): if frappe_head: try: url = get_assets_link(frappe_head) - click.secho("Retreiving Assets...", fg="yellow") + click.secho("Retreiving assets...", fg="yellow") prefix = mkdtemp(prefix="frappe-assets-", suffix=frappe_head) assets_archive = download_file(url, prefix) - print("{0} Downloaded assets archive from {1}".format(green('✔'), url)) + print("\n{0} Downloaded Frappe assets from {1}".format(green('✔'), url)) if assets_archive: import tarfile - click.secho("Extracting Assets...", fg="yellow") + click.secho("\nExtracting assets...\n", fg="yellow") with tarfile.open(assets_archive) as tar: for file in tar: if not file.isdir(): diff --git a/rollup/build.js b/rollup/build.js index 5fdfe80790..db9a032b9f 100644 --- a/rollup/build.js +++ b/rollup/build.js @@ -35,7 +35,7 @@ const files = exists("--files") ? value("--files").split(",") : false; const build_for_app = exists("--app") ? value("--app") : null; const concat = !exists("--no-concat"); -show_production_message(); +if (!files) show_production_message(); ensure_js_css_dirs(); if (concat) concatenate_files(); create_build_file(); From b6fc42724d8156e7d8c07a50964dd46e7aa74f79 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Wed, 9 Sep 2020 08:27:19 +0530 Subject: [PATCH 25/27] fix: Re-use build from options --- rollup/build.js | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/rollup/build.js b/rollup/build.js index db9a032b9f..3375b2d1cd 100644 --- a/rollup/build.js +++ b/rollup/build.js @@ -66,11 +66,7 @@ function build_assets_for_app(app) { return build_assets(app) } -function build_assets(app) { - const options = get_options_for(app); - if (!options.length) return Promise.resolve(); - log(chalk.yellow(`\nBuilding ${app} assets...\n`)); - +function build_from_(options) { const promises = options.map(({ inputOptions, outputOptions, output_file}) => { return build(inputOptions, outputOptions) .then(() => { @@ -86,26 +82,21 @@ function build_assets(app) { }); } +function build_assets(app) { + const options = get_options_for(app); + if (!options.length) return Promise.resolve(); + log(chalk.yellow(`\nBuilding ${app} assets...\n`)); + return build_from_(options); +} + function build_files(files, app="frappe") { + let ret; for (let file of files) { let options = get_options(file, app); if (!options.length) return Promise.resolve(); - log(chalk.yellow(`\nBuilding ${app} assets...\n`)); - - let promises = options.map(({ inputOptions, outputOptions, output_file}) => { - return build(inputOptions, outputOptions) - .then(() => { - log(`${chalk.green('✔')} Built ${output_file}`); - }); - }); - - let start = Date.now(); - return Promise.all(promises) - .then(() => { - let time = Date.now() - start; - log(chalk.green(`✨ Done in ${time / 1000}s`)); - }); + ret += build_from_(options); } + return ret; } function build(inputOptions, outputOptions) { From 043e6804f46c419480538f81a30abaa19d054d03 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Tue, 8 Sep 2020 19:45:26 +0530 Subject: [PATCH 26/27] chore: Add error message if something goes wrong --- frappe/build.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frappe/build.py b/frappe/build.py index b58b3ed3a2..767217a9b9 100644 --- a/frappe/build.py +++ b/frappe/build.py @@ -126,6 +126,8 @@ def download_frappe_assets(verbose=True): else: raise except Exception: + # TODO: log traceback in bench.log + click.secho("An Error occurred while downloading assets...", fg="red") assets_setup = False finally: try: From 55733b9b3876ece13dd180fd922f2a3860f7ce4f Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Mon, 14 Sep 2020 21:00:10 +0530 Subject: [PATCH 27/27] fix: Early skip fetching Frappe Assets if running in CI --- frappe/commands/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 9f781d7475..b7c85268ae 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -27,7 +27,8 @@ def build(app=None, make_copy=False, restore=False, verbose=False, force=False): # don't minify in developer_mode for faster builds no_compress = frappe.local.conf.developer_mode or False - if not (force or app): + # dont try downloading assets if force used, app specified or running via CI + if not (force or app or os.environ.get('CI')): # skip building frappe if assets exist remotely skip_frappe = frappe.build.download_frappe_assets(verbose=verbose) else: