diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..56f37d2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,213 @@ +name: CI + +on: + push: + branches: + - master + - main + pull_request: + branches: + - master + - main + +permissions: read-all + +jobs: + build: + name: Build, lint and unit tests + runs-on: ubuntu-latest + outputs: + plugin-id: ${{ steps.metadata.outputs.plugin-id }} + plugin-version: ${{ steps.metadata.outputs.plugin-version }} + has-e2e: ${{ steps.check-for-e2e.outputs.has-e2e }} + has-backend: ${{ steps.check-for-backend.outputs.has-backend }} + env: + GRAFANA_ACCESS_POLICY_TOKEN: ${{ secrets.GRAFANA_ACCESS_POLICY_TOKEN }} + steps: + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + version: 8.6.2 + run_install: false + + - name: Install dependencies + run: pnpm ci + + - name: Check types + run: pnpm run typecheck + - name: Lint + run: pnpm run lint + - name: Unit tests + run: pnpm run test:ci + - name: Build frontend + run: pnpm run build + + - name: Check for backend + id: check-for-backend + run: | + if [ -f "Magefile.go" ] + then + echo "has-backend=true" >> $GITHUB_OUTPUT + fi + + - name: Setup Go environment + if: steps.check-for-backend.outputs.has-backend == 'true' + uses: actions/setup-go@v5 + with: + go-version: '1.21' + + - name: Test backend + if: steps.check-for-backend.outputs.has-backend == 'true' + uses: magefile/mage-action@v3 + with: + version: latest + args: coverage + + - name: Build backend + if: steps.check-for-backend.outputs.has-backend == 'true' + uses: magefile/mage-action@v3 + with: + version: latest + args: buildAll + + - name: Check for E2E + id: check-for-e2e + run: | + if [ -f "playwright.config.ts" ] + then + echo "has-e2e=true" >> $GITHUB_OUTPUT + fi + + - name: Sign plugin + run: pnpm run sign + if: ${{ env.GRAFANA_ACCESS_POLICY_TOKEN != '' }} + + - name: Get plugin metadata + id: metadata + run: | + sudo apt-get install jq + + export GRAFANA_PLUGIN_ID=$(cat dist/plugin.json | jq -r .id) + export GRAFANA_PLUGIN_VERSION=$(cat dist/plugin.json | jq -r .info.version) + export GRAFANA_PLUGIN_ARTIFACT=${GRAFANA_PLUGIN_ID}-${GRAFANA_PLUGIN_VERSION}.zip + + echo "plugin-id=${GRAFANA_PLUGIN_ID}" >> $GITHUB_OUTPUT + echo "plugin-version=${GRAFANA_PLUGIN_VERSION}" >> $GITHUB_OUTPUT + echo "archive=${GRAFANA_PLUGIN_ARTIFACT}" >> $GITHUB_OUTPUT + + - name: Package plugin + id: package-plugin + run: | + mv dist ${{ steps.metadata.outputs.plugin-id }} + zip ${{ steps.metadata.outputs.archive }} ${{ steps.metadata.outputs.plugin-id }} -r + + - name: Archive Build + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.metadata.outputs.plugin-id }}-${{ steps.metadata.outputs.plugin-version }} + path: ${{ steps.metadata.outputs.plugin-id }} + retention-days: 5 + + resolve-versions: + name: Resolve e2e images + runs-on: ubuntu-latest + timeout-minutes: 3 + needs: build + if: ${{ needs.build.outputs.has-e2e == 'true' }} + outputs: + matrix: ${{ steps.resolve-versions.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Resolve Grafana E2E versions + id: resolve-versions + uses: grafana/plugin-actions/e2e-version@main + + playwright-tests: + needs: [resolve-versions, build] + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + GRAFANA_IMAGE: ${{fromJson(needs.resolve-versions.outputs.matrix)}} + name: e2e test ${{ matrix.GRAFANA_IMAGE.name }}@${{ matrix.GRAFANA_IMAGE.VERSION }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: | + provisioning + tests + .config + + - name: Download plugin + if: needs.build.outputs.has-backend == 'true' + uses: actions/download-artifact@v4 + with: + path: dist + name: ${{ needs.build.outputs.plugin-id }}-${{ needs.build.outputs.plugin-version }} + + - name: Execute permissions on binary + if: needs.build.outputs.has-backend == 'true' + run: | + chmod +x ./dist/gpx_cicd_linux_amd64 + + - name: Setup Node.js environment + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dev dependencies + run: pnpm ci + + - name: Start Grafana + run: | + docker-compose pull + DEVELOPMENT=false GRAFANA_VERSION=${{ matrix.GRAFANA_IMAGE.VERSION }} GRAFANA_IMAGE=${{ matrix.GRAFANA_IMAGE.NAME }} docker-compose up -d + + - name: Wait for Grafana to start + uses: nev7n/wait_for_response@v1 + with: + url: 'http://localhost:3000/' + responseCode: 200 + timeout: 60000 + interval: 500 + + - name: Install Playwright Browsers + run: npx playwright install chromium --with-deps + + - name: Run Playwright tests + id: run-tests + run: pnpm run e2e + + - name: Docker logs + if: ${{ always() && steps.run-tests.outcome == 'failure' }} + run: | + docker logs factry-historian-datasource >& grafana-server.log + + - name: Stop grafana docker + run: docker-compose down + + - name: Upload server log + uses: actions/upload-artifact@v4 + if: ${{ always() && steps.run-tests.outcome == 'failure' }} + with: + name: ${{ matrix.GRAFANA_IMAGE.NAME }}-v${{ matrix.GRAFANA_IMAGE.VERSION }}-${{github.run_id}}-server-log + path: grafana-server.log + retention-days: 5 + + # If your repository is public, uploading the Playwright report will make it public on the Internet. + # Beware not to expose sensitive information. + - name: Upload artifacts + uses: actions/upload-artifact@v4 + if: ${{ always() && steps.run-tests.outcome == 'failure' }} + with: + name: playwright-report-${{ matrix.GRAFANA_IMAGE.NAME }}-v${{ matrix.GRAFANA_IMAGE.VERSION }}-${{github.run_id}} + path: playwright-report/ + retention-days: 5 diff --git a/.github/workflows/is-compatible.yml b/.github/workflows/is-compatible.yml new file mode 100644 index 0000000..f9a4601 --- /dev/null +++ b/.github/workflows/is-compatible.yml @@ -0,0 +1,24 @@ +name: Latest Grafana API compatibility check +on: [pull_request] + +jobs: + compatibilitycheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + version: 8.6.2 + run_install: false + - name: Install dependencies + run: pnpm ci + - name: Build plugin + run: pnpm run build + - name: Compatibility check + run: npx @grafana/levitate@latest is-compatible --path src/module.ts --target @grafana/data,@grafana/ui,@grafana/runtime diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..523ba64 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,26 @@ +# This GitHub Action automates the process of building Grafana plugins. +# (For more information, see https://github.com/grafana/plugin-actions/blob/main/build-plugin/README.md) +name: Release + +on: + push: + tags: + - 'v*' # Run workflow on version tags, e.g. v1.0.0. + +permissions: read-all + +jobs: + release: + permissions: + contents: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: grafana/plugin-actions/build-plugin@release + # Uncomment to enable plugin signing + # (For more info on how to generate the access policy token see https://grafana.com/developers/plugin-tools/publish-a-plugin/sign-a-plugin#generate-an-access-policy-token) + #with: + # Make sure to save the token in your repository secrets + #policy_token: $ + # Usage of GRAFANA_API_KEY is deprecated, prefer `policy_token` option above + #grafana_token: $ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6d9e2ae..a82f39f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,11 +1,11 @@ image: golang:latest variables: - PROJECT_NAME: grafana-datasource - REMOTES: "historian.factry.dev demo.factry.io" - REMOTE_PATH: "/opt/factry/grafana-datasource" - CLIENT_PORTAL_SERVER : "portal.factry.cloud" - CLIENT_PORTAL_DOWNLOAD_PATH: "/opt/factry/portal.factry.cloud" + PROJECT_NAME: factry-historian-datasource + REMOTES: 'historian.factry.dev demo.factry.io' + REMOTE_PATH: '/opt/factry/factry-historian-datasource' + CLIENT_PORTAL_SERVER: 'portal.factry.cloud' + CLIENT_PORTAL_DOWNLOAD_PATH: '/opt/factry/portal.factry.cloud' workflow: rules: @@ -65,9 +65,9 @@ deploy-branch: stage: deploy script: - for REMOTE in $REMOTES; do - ssh gitlab@$REMOTE rm -rf $REMOTE_PATH/$CI_COMMIT_BRANCH; - ssh gitlab@$REMOTE mkdir $REMOTE_PATH/$CI_COMMIT_BRANCH; - scp -r dist/* gitlab@$REMOTE:$REMOTE_PATH/$CI_COMMIT_BRANCH; + ssh gitlab@$REMOTE rm -rf $REMOTE_PATH/$CI_COMMIT_BRANCH; + ssh gitlab@$REMOTE mkdir $REMOTE_PATH/$CI_COMMIT_BRANCH; + scp -r dist/* gitlab@$REMOTE:$REMOTE_PATH/$CI_COMMIT_BRANCH; done artifacts: expire_in: 1 day @@ -80,9 +80,9 @@ deploy-tag: stage: deploy script: - for REMOTE in $REMOTES; do - ssh gitlab@$REMOTE rm -rf $REMOTE_PATH/$CI_COMMIT_TAG; - ssh gitlab@$REMOTE mkdir $REMOTE_PATH/$CI_COMMIT_TAG; - scp -r dist/* gitlab@$REMOTE:$REMOTE_PATH/$CI_COMMIT_TAG; + ssh gitlab@$REMOTE rm -rf $REMOTE_PATH/$CI_COMMIT_TAG; + ssh gitlab@$REMOTE mkdir $REMOTE_PATH/$CI_COMMIT_TAG; + scp -r dist/* gitlab@$REMOTE:$REMOTE_PATH/$CI_COMMIT_TAG; done artifacts: expire_in: 1 day @@ -106,8 +106,8 @@ deploy-tag: optional: false artifacts: true variables: - PORTAL_URL: "" - PORTAL_PRODUCT_UPDATES_JWT_TOKEN: "" + PORTAL_URL: '' + PORTAL_PRODUCT_UPDATES_JWT_TOKEN: '' before_script: - apk add --no-cache curl zip script: @@ -125,20 +125,20 @@ deploy-tag: echo "uploading $file ($version) to portal at ${PORTAL_URL}/api/product-updates" curl -X POST -H "Authorization: Bearer $PORTAL_PRODUCT_UPDATES_JWT_TOKEN" -F "productType=${productType}" -F "product=${product}" -F "os=${os}" -F "arch=${arch}" -F "version=${version}" -F "signature=${signature}" -F "binary=@${path}" --url "${PORTAL_URL}/api/product-updates" -"publish:prod": +'publish:prod': variables: PORTAL_URL: ${PORTAL_URL_PROD} PORTAL_PRODUCT_UPDATES_JWT_TOKEN: ${PORTAL_PRODUCT_UPDATES_JWT_TOKEN_PROD} extends: .publish -"publish:qa": +'publish:qa': allow_failure: true variables: PORTAL_URL: ${PORTAL_URL_QA} PORTAL_PRODUCT_UPDATES_JWT_TOKEN: ${PORTAL_PRODUCT_UPDATES_JWT_TOKEN_QA} extends: .publish -"publish:staging": +'publish:staging': allow_failure: true variables: PORTAL_URL: ${PORTAL_URL_STAGING} diff --git a/Makefile b/Makefile index fbdce8b..8784d66 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ major = 2 minor = 0 patch = 0 prerelease = -alpha -project_name=grafana-datasource +project_name=factry-historian-datasource COMMIT=$(shell git rev-parse --short HEAD) PROTO_DIR= pkg/proto diff --git a/docker-compose.yaml b/docker-compose.yaml index 576dac6..84a2cf1 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,10 +10,10 @@ services: - 'seccomp:unconfined' environment: NODE_ENV: development - GF_LOG_FILTERS: plugin.factry-awesomeo-datasource:debug + GF_LOG_FILTERS: plugin.factry-historian-datasource:debug GF_LOG_LEVEL: debug GF_DATAPROXY_LOGGING: 1 - GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: factry-awesomeo-datasource + GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: factry-historian-datasource build: context: ./.config args: diff --git a/src/plugin.json b/src/plugin.json index 124e4c8..d8cc25f 100644 --- a/src/plugin.json +++ b/src/plugin.json @@ -27,7 +27,7 @@ }, { "name": "License", - "url": "https://github.com/factrylabs/factry-historian-grafana-datasource/blob/main/LICENSE" + "url": "https://github.com/factrylabs/factry-historian-factry-historian-datasource/blob/main/LICENSE" } ], "screenshots": [