mirror of https://github.com/grafana/grafana
[release-11.5.5] Backport workflow fixes (#104694)
* Copy workflows and actions from main * add zizmor.ymlpull/104749/head
parent
64a3a01892
commit
7b1be85980
@ -0,0 +1,48 @@ |
||||
name: 'Setup Grafana Enterprise' |
||||
description: 'Clones and sets up Grafana Enterprise repository for testing' |
||||
|
||||
inputs: |
||||
github-app-name: |
||||
description: 'Name of the GitHub App in Vault' |
||||
required: false |
||||
default: 'grafana-ci-bot' |
||||
|
||||
runs: |
||||
using: "composite" |
||||
steps: |
||||
- name: Retrieve GitHub App secrets |
||||
id: get-secrets |
||||
uses: grafana/shared-workflows/actions/get-vault-secrets@get-vault-secrets-v1.0.1 # zizmor: ignore[unpinned-uses] |
||||
with: |
||||
repo_secrets: | |
||||
APP_ID=${{ inputs.github-app-name }}:app-id |
||||
APP_INSTALLATION_ID=${{ inputs.github-app-name }}:app-installation-id |
||||
PRIVATE_KEY=${{ inputs.github-app-name }}:private-key |
||||
|
||||
- name: Generate GitHub App token |
||||
id: generate_token |
||||
uses: actions/create-github-app-token@v1 |
||||
with: |
||||
app-id: ${{ env.APP_ID }} |
||||
private-key: ${{ env.PRIVATE_KEY }} |
||||
repositories: "grafana-enterprise" |
||||
owner: "grafana" |
||||
|
||||
- name: Setup Enterprise |
||||
shell: bash |
||||
env: |
||||
GH_TOKEN: ${{ steps.generate_token.outputs.token }} |
||||
run: | |
||||
git clone https://x-access-token:${GH_TOKEN}@github.com/grafana/grafana-enterprise.git ../grafana-enterprise; |
||||
|
||||
cd ../grafana-enterprise |
||||
|
||||
if git checkout ${GITHUB_HEAD_REF}; then |
||||
echo "checked out ${GITHUB_HEAD_REF}" |
||||
elif git checkout ${GITHUB_BASE_REF}; then |
||||
echo "checked out ${GITHUB_BASE_REF}" |
||||
else |
||||
git checkout main |
||||
fi |
||||
|
||||
./build.sh |
@ -0,0 +1,45 @@ |
||||
name: 'Setup Grafana Bench' |
||||
description: 'Sets up and installs Grafana Bench' |
||||
|
||||
inputs: |
||||
github-app-name: |
||||
description: 'Name of the GitHub App in Vault' |
||||
required: false |
||||
default: 'grafana-ci-bot' |
||||
branch: |
||||
description: 'The branch to install from' |
||||
required: false |
||||
default: 'main' |
||||
|
||||
runs: |
||||
using: "composite" |
||||
steps: |
||||
- name: Retrieve GitHub App secrets |
||||
id: get-secrets |
||||
uses: grafana/shared-workflows/actions/get-vault-secrets@get-vault-secrets-v1.0.1 # zizmor: ignore[unpinned-uses] |
||||
with: |
||||
repo_secrets: | |
||||
APP_ID=${{ inputs.github-app-name }}:app-id |
||||
APP_INSTALLATION_ID=${{ inputs.github-app-name }}:app-installation-id |
||||
PRIVATE_KEY=${{ inputs.github-app-name }}:private-key |
||||
|
||||
- name: Generate GitHub App token |
||||
id: generate_token |
||||
uses: actions/create-github-app-token@v1 |
||||
with: |
||||
app-id: ${{ env.APP_ID }} |
||||
private-key: ${{ env.PRIVATE_KEY }} |
||||
repositories: "grafana-bench" |
||||
owner: "grafana" |
||||
|
||||
- name: Setup Bench |
||||
shell: bash |
||||
env: |
||||
GH_TOKEN: ${{ steps.generate_token.outputs.token }} |
||||
BRANCH: ${{ inputs.branch }} |
||||
run: | |
||||
git clone https://x-access-token:${GH_TOKEN}@github.com/grafana/grafana-bench.git ../grafana-bench |
||||
|
||||
cd ../grafana-bench |
||||
git switch "$BRANCH" |
||||
go install . |
@ -0,0 +1,50 @@ |
||||
name: 'Go Coverage Processor' |
||||
description: 'Process Go test coverage files and generate reports' |
||||
|
||||
inputs: |
||||
test-type: |
||||
description: 'Type of test (e.g., be-unit, be-integration)' |
||||
required: true |
||||
type: string |
||||
coverage-file: |
||||
description: 'Path to the Go coverage file (.cov)' |
||||
required: true |
||||
type: string |
||||
codecov-token: |
||||
description: 'Token for CodeCov (required for CodeCov reporting)' |
||||
required: false |
||||
default: '' |
||||
codecov-flag: |
||||
description: 'Flag to categorize the upload to CodeCov' |
||||
required: false |
||||
default: '' |
||||
codecov-name: |
||||
description: 'Custom name for the upload to CodeCov' |
||||
required: false |
||||
default: '' |
||||
|
||||
runs: |
||||
using: 'composite' |
||||
steps: |
||||
- name: Process Go coverage output |
||||
shell: bash |
||||
env: |
||||
COVERAGE_FILE: ${{ inputs.coverage-file }} |
||||
run: | |
||||
# Ensure valid coverage file even if empty |
||||
if [ ! -s "$COVERAGE_FILE" ]; then |
||||
echo "Coverage file is empty, creating a minimal valid file" |
||||
echo "mode: set" > "$COVERAGE_FILE" |
||||
fi |
||||
|
||||
- name: Report coverage to CodeCov |
||||
uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5 |
||||
if: inputs.codecov-token != '' |
||||
with: |
||||
files: ${{ inputs.coverage-file }} |
||||
flags: ${{ inputs.codecov-flag || inputs.test-type }} |
||||
name: ${{ inputs.codecov-name || inputs.test-type }} |
||||
slug: grafana/grafana |
||||
# This URL doesn't use the Google auth, but is much more locked down. As such, it requires OIDC or a CodeCov-provided token to do anything. |
||||
url: https://codecov-webhook.grafana-dev.net |
||||
token: ${{ inputs.codecov-token }} |
@ -0,0 +1,16 @@ |
||||
name: Add comment about adding a What's new note |
||||
on: |
||||
pull_request: |
||||
types: [labeled] |
||||
|
||||
jobs: |
||||
add-comment: |
||||
if: ${{ ! github.event.pull_request.head.repo.fork && contains(github.event.pull_request.labels.*.name, 'add to what''s new') }} |
||||
runs-on: ubuntu-latest |
||||
permissions: |
||||
pull-requests: write |
||||
steps: |
||||
- uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1 |
||||
with: |
||||
message: | |
||||
Since you've added the `Add to what's new` label, consider drafting a [What's new note](https://admin.grafana.com/content-admin/#/collections/whats-new/new) for this feature. |
@ -0,0 +1,137 @@ |
||||
name: Update Alerting Module |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
|
||||
concurrency: |
||||
group: ${{ github.workflow }}-${{ github.ref }} |
||||
cancel-in-progress: true |
||||
|
||||
jobs: |
||||
update-grafana: |
||||
runs-on: ubuntu-latest |
||||
permissions: |
||||
contents: write |
||||
pull-requests: write |
||||
id-token: write |
||||
|
||||
steps: |
||||
- name: Checkout repository |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2 |
||||
with: |
||||
persist-credentials: false |
||||
- name: Check if update branch exists |
||||
run: | |
||||
if git ls-remote --heads origin update-alerting-module | grep -q 'update-alerting-module'; then |
||||
echo "Branch 'update-alerting-module' already exists. There might be an open PR with Grafana updates." |
||||
echo "Please review and merge/close the existing PR before running this workflow again." |
||||
exit 1 |
||||
fi |
||||
|
||||
- name: Setup Go |
||||
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # 5.3.0 |
||||
with: |
||||
"go-version-file": "go.mod" |
||||
|
||||
- name: Extract current commit hash of alerting module |
||||
id: current-commit |
||||
run: | |
||||
FROM_COMMIT=$(go list -m -json github.com/grafana/alerting | jq -r '.Version' | grep -oP '(?<=-)[a-f0-9]+$') |
||||
echo "from_commit=$FROM_COMMIT" >> $GITHUB_OUTPUT |
||||
|
||||
- name: Get current branch name |
||||
id: current-branch-name |
||||
run: echo "name=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_OUTPUT" |
||||
|
||||
- name: Get latest commit |
||||
id: latest-commit |
||||
env: |
||||
GH_TOKEN: ${{ github.token }} |
||||
run: | |
||||
BRANCH="${{ steps.current-branch-name.outputs.name }}" |
||||
TO_COMMIT=$(gh api repos/grafana/alerting/commits/$BRANCH --jq '.sha') |
||||
if [ -z "$TO_COMMIT" ]; then |
||||
echo "Branch $BRANCH not found in alerting repo, falling back to main branch" |
||||
exit 1 |
||||
fi |
||||
echo "to_commit=$TO_COMMIT" >> $GITHUB_OUTPUT |
||||
|
||||
- name: Compare commit hashes |
||||
run: | |
||||
FROM_COMMIT="${{ steps.current-commit.outputs.from_commit }}" |
||||
TO_COMMIT="${{ steps.latest-commit.outputs.to_commit }}" |
||||
|
||||
# Compare just the length of the shorter hash |
||||
SHORT_TO_COMMIT="${TO_COMMIT:0:${#FROM_COMMIT}}" |
||||
|
||||
if [ "$FROM_COMMIT" = "$SHORT_TO_COMMIT" ]; then |
||||
echo "Current version ($FROM_COMMIT) is already at latest ($SHORT_TO_COMMIT). No update needed." |
||||
exit 0 |
||||
fi |
||||
echo "Updates available: $FROM_COMMIT -> $TO_COMMIT" |
||||
|
||||
- name: Check for commit history |
||||
id: check-commits |
||||
env: |
||||
GH_TOKEN: ${{ github.token }} |
||||
run: | |
||||
# get all commits that contains 'Alerting:' in the message |
||||
ALERTING_COMMITS=$(gh api repos/grafana/alerting/compare/${{ steps.current-commit.outputs.from_commit }}...${{ steps.latest-commit.outputs.to_commit }} \ |
||||
--jq '.commits[].commit.message | split("\n")[0]') || true |
||||
|
||||
# Use printf instead of echo -e for better multiline handling |
||||
printf "%s\n" "$ALERTING_COMMITS" |
||||
|
||||
# make the list for markdown and replace PR numbers with links |
||||
ALERTING_COMMITS_FORMATTED=$(echo "$ALERTING_COMMITS" | while read -r line; do echo "- $line" | sed -E 's/\(#([0-9]+)\)/[#\1](https:\/\/github.com\/grafana\/grafana\/pull\/\1)/g'; done) |
||||
|
||||
echo "alerting_commits<<EOF" >> $GITHUB_OUTPUT |
||||
echo "$ALERTING_COMMITS_FORMATTED" >> $GITHUB_OUTPUT |
||||
echo "EOF" >> $GITHUB_OUTPUT |
||||
|
||||
- name: Update alerting module |
||||
env: |
||||
GOSUMDB: off |
||||
run: | |
||||
go get github.com/grafana/alerting@${{ steps.latest-commit.outputs.to_commit }} |
||||
make update-workspace |
||||
|
||||
- id: get-secrets |
||||
uses: grafana/shared-workflows/actions/get-vault-secrets@main # zizmor: ignore[unpinned-uses] |
||||
with: |
||||
repo_secrets: | |
||||
GITHUB_APP_ID=alerting-team:app-id |
||||
GITHUB_APP_PRIVATE_KEY=alerting-team:private-key |
||||
|
||||
- name: "Generate token" |
||||
id: generate_token |
||||
uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # 1.11.5 |
||||
with: |
||||
app-id: ${{ env.GITHUB_APP_ID }} |
||||
private-key: ${{ env.GITHUB_APP_PRIVATE_KEY }} |
||||
|
||||
- name: Create Pull Request |
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # 7.0.6 |
||||
id: create-pr |
||||
with: |
||||
token: '${{ steps.generate_token.outputs.token }}' |
||||
title: 'Alerting: Update alerting module to ${{ steps.latest-commit.outputs.to_commit }}' |
||||
branch: alerting/update-alerting-module |
||||
delete-branch: true |
||||
body: | |
||||
Updates Grafana Alerting module to latest version. |
||||
|
||||
Compare changes: https://github.com/grafana/alerting/compare/${{ steps.current-commit.outputs.from_commit }}...${{ steps.latest-commit.outputs.to_commit }} |
||||
<details> |
||||
<summary>Commits</summary> |
||||
|
||||
${{ steps.check-commits.outputs.alerting_commits }} |
||||
|
||||
</details> |
||||
|
||||
Created by: [GitHub Action Job](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) |
||||
- name: Add PR URL to Summary |
||||
if: steps.create-pr.outputs.pull-request-url != '' |
||||
run: | |
||||
echo "## Pull Request Created" >> $GITHUB_STEP_SUMMARY |
||||
echo "🔗 [View Pull Request](${{ steps.create-pr.outputs.pull-request-url }})" >> $GITHUB_STEP_SUMMARY |
@ -0,0 +1,25 @@ |
||||
name: Analytics Events Report |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
|
||||
jobs: |
||||
generate-report: |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Checkout repository |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
|
||||
- name: Setup Node.js |
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
|
||||
- name: Install dependencies |
||||
run: yarn install --frozen-lockfile |
||||
|
||||
- name: Generate analytics report |
||||
run: yarn analytics-report |
@ -0,0 +1,74 @@ |
||||
name: Backend Code Checks |
||||
description: Validate go.mod and OpenAPI specifications |
||||
|
||||
on: |
||||
pull_request: |
||||
paths-ignore: |
||||
- '*.md' |
||||
- 'docs/**' |
||||
- 'latest.json' |
||||
push: |
||||
branches: |
||||
- main |
||||
paths-ignore: |
||||
- '*.md' |
||||
- 'docs/**' |
||||
- 'latest.json' |
||||
|
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
|
||||
jobs: |
||||
validate-configs: |
||||
name: Validate Backend Configs |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- name: Setup Go |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
# Explicitly set Go version to 1.24.1 to ensure consistent OpenAPI spec generation |
||||
# The crypto/x509 package has additional fields in Go 1.24.1 that affect the generated specs |
||||
# This ensures the GHAs environment matches what we use in the Drone pipeline |
||||
go-version: 1.24.1 |
||||
cache: true |
||||
|
||||
- name: Verify code generation |
||||
run: | |
||||
CODEGEN_VERIFY=1 make gen-cue |
||||
CODEGEN_VERIFY=1 make gen-jsonnet |
||||
|
||||
- name: Validate go.mod |
||||
run: go run scripts/modowners/modowners.go check go.mod |
||||
|
||||
# Enterprise setup is needed for complete OpenAPI spec generation |
||||
# We only do this for internal PRs |
||||
- name: Setup Grafana Enterprise |
||||
if: github.event.pull_request.head.repo.fork == false |
||||
uses: ./.github/actions/setup-enterprise |
||||
|
||||
- name: Generate and Validate OpenAPI Specs |
||||
run: | |
||||
# For PRs from forks, we'll just run the basic swagger-gen without validation |
||||
if [[ "${{ github.event_name }}" == "pull_request" && "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then |
||||
echo "PR is from a fork, skipping enterprise-based validation" |
||||
make swagger-gen |
||||
exit 0 |
||||
fi |
||||
|
||||
# Clean and regenerate OpenAPI specs |
||||
make swagger-clean && make openapi3-gen |
||||
|
||||
# Check if the generated specs differ from what's in the repository |
||||
for f in public/api-merged.json public/openapi3.json; do git add $f; done |
||||
if [ -z "$(git diff --name-only --cached)" ]; then |
||||
echo "OpenAPI specs are up to date!" |
||||
else |
||||
echo "OpenAPI specs are OUT OF DATE!" |
||||
git diff --cached |
||||
echo "Please ensure the branch is up-to-date, then regenerate the specification by running make swagger-clean && make openapi3-gen" |
||||
exit 1 |
||||
fi |
@ -0,0 +1,71 @@ |
||||
name: Backend Unit Tests |
||||
|
||||
on: |
||||
pull_request: |
||||
paths-ignore: |
||||
- 'docs/**' |
||||
- '**/*.md' |
||||
push: |
||||
branches: |
||||
- main |
||||
- release-*.*.* |
||||
paths-ignore: |
||||
- 'docs/**' |
||||
- '**/*.md' |
||||
|
||||
concurrency: |
||||
group: ${{ github.workflow }}-${{ github.ref }} |
||||
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} |
||||
|
||||
permissions: {} |
||||
|
||||
jobs: |
||||
grafana: |
||||
# Run this workflow only for PRs from forks; if it gets merged into `main` or `release-*`, |
||||
# the `pr-backend-unit-tests-enterprise` workflow will run instead |
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true |
||||
name: Grafana |
||||
runs-on: ubuntu-latest-8-cores |
||||
continue-on-error: true |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- name: Setup Go |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: go.mod |
||||
- name: Generate Go code |
||||
run: make gen-go |
||||
- name: Run unit tests |
||||
run: make test-go-unit |
||||
|
||||
grafana-enterprise: |
||||
# Run this workflow for non-PR events (like pushes to `main` or `release-*`) OR for internal PRs (PRs not from forks) |
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false |
||||
name: Grafana Enterprise |
||||
runs-on: ubuntu-latest-8-cores |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- name: Setup Go |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: go.mod |
||||
- name: Setup Enterprise |
||||
uses: ./.github/actions/setup-enterprise |
||||
with: |
||||
github-app-name: 'grafana-ci-bot' |
||||
- name: Generate Go code |
||||
run: make gen-go |
||||
- name: Run unit tests |
||||
run: make test-go-unit |
@ -1,44 +0,0 @@ |
||||
name: Close milestone |
||||
on: |
||||
workflow_dispatch: |
||||
inputs: |
||||
version: |
||||
required: true |
||||
description: Needs to match, exactly, the name of a milestone |
||||
workflow_call: |
||||
inputs: |
||||
version_call: |
||||
description: Needs to match, exactly, the name of a milestone |
||||
required: true |
||||
type: string |
||||
|
||||
jobs: |
||||
main: |
||||
if: github.repository == 'grafana/grafana' |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Checkout Actions |
||||
uses: actions/checkout@v4 |
||||
with: |
||||
repository: "grafana/grafana-github-actions" |
||||
path: ./actions |
||||
ref: main |
||||
- name: Install Actions |
||||
run: npm install --production --prefix ./actions |
||||
- name: "Generate token" |
||||
id: generate_token |
||||
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 |
||||
with: |
||||
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} |
||||
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} |
||||
- name: Close milestone (manually invoked) |
||||
if: ${{ github.event.inputs.version != '' }} |
||||
uses: ./actions/close-milestone |
||||
with: |
||||
token: ${{ steps.generate_token.outputs.token }} |
||||
- name: Close milestone (workflow invoked) |
||||
if: ${{ inputs.version_call != '' }} |
||||
uses: ./actions/close-milestone |
||||
with: |
||||
version_call: ${{ inputs.version_call }} |
||||
token: ${{ steps.generate_token.outputs.token }} |
@ -1,26 +0,0 @@ |
||||
name: "doc-validator" |
||||
on: |
||||
workflow_dispatch: |
||||
inputs: |
||||
include: |
||||
description: | |
||||
Regular expression that matches paths to include in linting. |
||||
|
||||
For example: docs/sources/(?:alerting|fundamentals)/.+\.md |
||||
required: true |
||||
jobs: |
||||
doc-validator: |
||||
runs-on: "ubuntu-latest" |
||||
container: |
||||
image: "grafana/doc-validator:v5.2.0" |
||||
steps: |
||||
- name: "Checkout code" |
||||
uses: "actions/checkout@v4" |
||||
- name: "Run doc-validator tool" |
||||
# Only run doc-validator on specific directories. |
||||
run: > |
||||
doc-validator |
||||
'--include=${{ inputs.include }}' |
||||
'--skip-checks=^(?:image.+|canonical-does-not-match-pretty-URL)$' |
||||
./docs/sources |
||||
/docs/grafana/latest |
@ -0,0 +1,19 @@ |
||||
name: Documentation CI |
||||
on: |
||||
pull_request: |
||||
branches: ["main"] |
||||
paths: ["docs/sources/**"] |
||||
workflow_dispatch: |
||||
jobs: |
||||
vale: |
||||
runs-on: ubuntu-latest |
||||
container: |
||||
image: grafana/vale:latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- uses: grafana/writers-toolkit/vale-action@vale-action/v1 # zizmor: ignore[unpinned-uses] |
||||
with: |
||||
filter: '.Name in ["Grafana.GrafanaCom", "Grafana.WordList", "Grafana.Spelling", "Grafana.ProductPossessives"]' |
||||
token: ${{ secrets.GITHUB_TOKEN }} |
@ -1,149 +0,0 @@ |
||||
name: When epic issues changed in Platform UX squad projects, check if epic is part of specified child projects and update on Platform UX parent project |
||||
|
||||
on: |
||||
issues: |
||||
types: [opened, closed, edited, reopened, assigned, unassigned, labeled, unlabeled] |
||||
labels: |
||||
- 'type/epic' |
||||
|
||||
env: |
||||
GH_TOKEN: ${{ secrets.GH_BOT_PROJECTS_ACCESS_TOKEN }} |
||||
ORGANIZATION: ${{ github.repository_owner }} |
||||
REPO: ${{ github.event.repository.name }} |
||||
PARENT_PROJECT: 304 |
||||
CHILD_PROJECT_1: 78 |
||||
CHILD_PROJECT_2: 111 |
||||
CHILD_PROJECT_3: 202 |
||||
|
||||
concurrency: |
||||
group: issue-add-to-parent-project-${{ github.event.number }} |
||||
jobs: |
||||
config: |
||||
runs-on: "ubuntu-latest" |
||||
outputs: |
||||
has-secrets: ${{ steps.check.outputs.has-secrets }} |
||||
steps: |
||||
- name: "Check for secrets" |
||||
id: check |
||||
shell: bash |
||||
run: | |
||||
if [ -n "${{ (secrets.GH_BOT_PROJECTS_ACCESS_TOKEN != '') || '' }}" ]; then |
||||
echo "has-secrets=1" >> "$GITHUB_OUTPUT" |
||||
fi |
||||
|
||||
main: |
||||
needs: config |
||||
if: needs.config.outputs.has-secrets && contains(github.event.issue.labels.*.name, 'type/epic') |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Check if issue is in child or parent projects |
||||
run: | |
||||
gh api graphql -f query=' |
||||
query($org: String!, $repo: String!) { |
||||
repository(name: $repo, owner: $org) { |
||||
issue (number: ${{ github.event.issue.number }}) { |
||||
projectItems(first:20) { |
||||
nodes { |
||||
id, |
||||
project { |
||||
number, |
||||
title |
||||
}, |
||||
fieldValueByName(name:"Status") { |
||||
... on ProjectV2ItemFieldSingleSelectValue { |
||||
optionId |
||||
name |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}' -f org=$ORGANIZATION -f repo=$REPO > projects_data.json |
||||
|
||||
echo 'IN_PARENT_PROJ='$(jq '.data.repository.issue.projectItems.nodes[] | select(.project.number==${{ env.PARENT_PROJECT }}) | .project != null' projects_data.json) >> $GITHUB_ENV |
||||
echo 'PARENT_PROJ_STATUS_ID='$(jq '.data.repository.issue.projectItems.nodes[] | select(.project.number==${{ env.PARENT_PROJECT }}) | select(.fieldValueByName != null) | .fieldValueByName.optionId' projects_data.json) >> $GITHUB_ENV |
||||
echo 'ITEM_ID='$(jq '.data.repository.issue.projectItems.nodes[] | select(.project.number==${{ env.PARENT_PROJECT }}) | .id' projects_data.json) >> $GITHUB_ENV |
||||
echo 'IN_CHILD_PROJ='$(jq 'first(.data.repository.issue.projectItems.nodes[] | select(.project.number==${{ env.CHILD_PROJECT_1 }} or .project.number==${{ env.CHILD_PROJECT_2 }} or .project.number==${{ env.CHILD_PROJECT_3 }}) | .project != null)' projects_data.json) >> $GITHUB_ENV |
||||
echo 'CHILD_PROJ_STATUS='$(jq -r '.data.repository.issue.projectItems.nodes[] | select(.project.number==${{ env.CHILD_PROJECT_1 }} or .project.number==${{ env.CHILD_PROJECT_2 }} or .project.number==${{ env.CHILD_PROJECT_3 }}) | select(.fieldValueByName != null) | .fieldValueByName.name' projects_data.json) >> $GITHUB_ENV |
||||
- name: Get parent project project data |
||||
if: env.IN_CHILD_PROJ |
||||
run: | |
||||
gh api graphql -f query=' |
||||
query($org: String!, $number: Int!) { |
||||
organization(login: $org){ |
||||
projectV2(number: $number) { |
||||
id |
||||
fields(first:20) { |
||||
nodes { |
||||
... on ProjectV2Field { |
||||
id |
||||
name |
||||
} |
||||
... on ProjectV2SingleSelectField { |
||||
id |
||||
name |
||||
options { |
||||
id |
||||
name |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}' -f org=$ORGANIZATION -F number=$PARENT_PROJECT > project_data.json |
||||
|
||||
echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV |
||||
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV |
||||
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV |
||||
echo 'PROGRESS_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="In Progress") |.id' project_data.json) >> $GITHUB_ENV |
||||
echo 'DONE_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="Done") |.id' project_data.json) >> $GITHUB_ENV |
||||
- name: Add issue to parent project |
||||
if: env.IN_CHILD_PROJ && !env.IN_PARENT_PROJ |
||||
run: | |
||||
item_id="$( gh api graphql -f query=' |
||||
mutation($project:ID!, $issue:ID!) { |
||||
addProjectV2ItemById(input: {projectId: $project, contentId: $issue}) { |
||||
item { |
||||
id |
||||
} |
||||
} |
||||
}' -f project=$PROJECT_ID -f issue=${{ github.event.issue.node_id }} --jq '.data.addProjectV2ItemById.item.id')" |
||||
|
||||
echo 'ITEM_ID='$item_id >> $GITHUB_ENV |
||||
- name: Set parent project status Done |
||||
if: contains(env.CHILD_PROJ_STATUS, 'Done') |
||||
run: | |
||||
echo 'OPTION_ID='$DONE_OPTION_ID >> $GITHUB_ENV |
||||
- name: Set parent project status In Progress |
||||
if: contains(env.CHILD_PROJ_STATUS, 'In ') || contains(env.CHILD_PROJ_STATUS, 'Blocked') |
||||
run: | |
||||
echo 'OPTION_ID='$PROGRESS_OPTION_ID >> $GITHUB_ENV |
||||
- name: Set parent project status To do |
||||
if: env.CHILD_PROJ_STATUS && !contains(env.CHILD_PROJ_STATUS, 'In ') && !contains(env.CHILD_PROJ_STATUS, 'Blocked') && ! contains(env.CHILD_PROJ_STATUS, 'Done') |
||||
run: | |
||||
echo 'OPTION_ID='$TODO_OPTION_ID >> $GITHUB_ENV |
||||
- name: Set issue status in parent project |
||||
if: env.OPTION_ID && (env.OPTION_ID != env.PARENT_PROJ_STATUS_ID) |
||||
run: | |
||||
gh api graphql -f query=' |
||||
mutation ( |
||||
$project: ID! |
||||
$item: ID! |
||||
$status_field: ID! |
||||
$status_value: String! |
||||
) { |
||||
set_status: updateProjectV2ItemFieldValue(input: { |
||||
projectId: $project |
||||
itemId: $item |
||||
fieldId: $status_field |
||||
value: { |
||||
singleSelectOptionId: $status_value |
||||
} |
||||
}) { |
||||
projectV2Item { |
||||
id |
||||
} |
||||
} |
||||
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.OPTION_ID }} --silent |
@ -0,0 +1,25 @@ |
||||
name: Feature toggles CI |
||||
|
||||
on: |
||||
pull_request: |
||||
paths: |
||||
- 'pkg/services/featuremgmt/toggles_gen_test.go' |
||||
- 'pkg/services/featuremgmt/registry.go' |
||||
- 'docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md' |
||||
|
||||
jobs: |
||||
test: |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
|
||||
- name: Set up Go |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: 'go.mod' |
||||
cache: true |
||||
|
||||
- name: Run feature toggle tests |
||||
run: go test -v -run TestFeatureToggleFiles ./pkg/services/featuremgmt/ |
@ -0,0 +1,133 @@ |
||||
name: Lint Frontend |
||||
on: |
||||
pull_request: |
||||
push: |
||||
branches: |
||||
- main |
||||
- release-*.*.* |
||||
|
||||
permissions: {} |
||||
|
||||
jobs: |
||||
lint-frontend-verify-i18n: |
||||
name: Verify i18n |
||||
runs-on: ubuntu-latest |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
cache-dependency-path: 'yarn.lock' |
||||
- run: yarn install --immutable --check-cache |
||||
- run: | |
||||
extract_error_message='::error::Extraction failed. Make sure that you have no dynamic translation phrases, such as "t(`preferences.theme.{themeID}`, themeName)" and that no translation key is used twice. Search the output for '[warning]' to find the offending file.' |
||||
make i18n-extract || (echo "${extract_error_message}" && false) |
||||
- run: | |
||||
uncommited_error_message="::error::Translation extraction has not been committed. Please run 'make i18n-extract', commit the changes and push again." |
||||
file_diff=$(git diff --dirstat public/locales) |
||||
if [ -n "$file_diff" ]; then |
||||
echo $file_diff |
||||
echo "${uncommited_error_message}" |
||||
exit 1 |
||||
fi |
||||
lint-frontend-prettier: |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
# Run this workflow only for PRs from forks; if it gets merged into `main` or `release-*`, |
||||
# the `lint-frontend-prettier-enterprise` workflow will run instead |
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true |
||||
name: Lint |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
cache-dependency-path: 'yarn.lock' |
||||
- run: yarn install --immutable --check-cache |
||||
- run: yarn run prettier:check |
||||
- run: yarn run lint |
||||
lint-frontend-prettier-enterprise: |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
# Run this workflow for non-PR events (like pushes to `main` or `release-*`) OR for internal PRs (PRs not from forks) |
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false |
||||
name: Lint |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
cache-dependency-path: 'yarn.lock' |
||||
- name: Setup Enterprise |
||||
uses: ./.github/actions/setup-enterprise |
||||
with: |
||||
github-app-name: 'grafana-ci-bot' |
||||
- run: yarn install --immutable --check-cache |
||||
- run: yarn run prettier:check |
||||
- run: yarn run lint |
||||
lint-frontend-typecheck: |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
# Run this workflow only for PRs from forks; if it gets merged into `main` or `release-*`, |
||||
# the `lint-frontend-typecheck-enterprise` workflow will run instead |
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true |
||||
name: Typecheck |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
cache-dependency-path: 'yarn.lock' |
||||
- run: yarn install --immutable --check-cache |
||||
- run: yarn run typecheck |
||||
lint-frontend-typecheck-enterprise: |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
# Run this workflow for non-PR events (like pushes to `main` or `release-*`) OR for internal PRs (PRs not from forks) |
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false |
||||
name: Typecheck |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
cache-dependency-path: 'yarn.lock' |
||||
- name: Setup Enterprise |
||||
uses: ./.github/actions/setup-enterprise |
||||
with: |
||||
github-app-name: 'grafana-ci-bot' |
||||
- run: yarn install --immutable --check-cache |
||||
- run: yarn run typecheck |
||||
lint-frontend-betterer: |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
name: Betterer |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
cache-dependency-path: 'yarn.lock' |
||||
- run: yarn install --immutable --check-cache |
||||
- run: yarn run betterer:ci |
@ -0,0 +1,32 @@ |
||||
name: golangci-lint |
||||
on: |
||||
push: |
||||
paths: |
||||
- pkg/** |
||||
- .github/workflows/go-lint.yml |
||||
- go.* |
||||
branches: |
||||
- main |
||||
pull_request: |
||||
|
||||
permissions: |
||||
contents: read |
||||
|
||||
jobs: |
||||
lint-go: |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: ./go.mod |
||||
- run: make gen-go |
||||
- name: golangci-lint |
||||
uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd |
||||
with: |
||||
version: v2.0.2 |
||||
args: | |
||||
--verbose $(go list -m -f '{{.Dir}}' | xargs -I{} sh -c 'test ! -f {}/.nolint && echo {}/...') |
||||
install-mode: binary |
@ -0,0 +1,27 @@ |
||||
name: Crowdin Create Tasks |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
# schedule: |
||||
# - cron: "0 0 * * *" |
||||
|
||||
jobs: |
||||
create-tasks-in-crowdin: |
||||
runs-on: ubuntu-latest |
||||
|
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
|
||||
- name: Setup Node.js |
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
|
||||
- name: Create tasks |
||||
env: |
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} |
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} |
||||
run: node ./.github/workflows/scripts/crowdin/create-tasks.js |
@ -0,0 +1,62 @@ |
||||
name: Documentation |
||||
|
||||
on: |
||||
pull_request: |
||||
paths: |
||||
- '*.md' |
||||
- 'docs/**' |
||||
- 'packages/**/*.md' |
||||
- 'latest.json' |
||||
push: |
||||
branches: |
||||
- main |
||||
paths: |
||||
- '*.md' |
||||
- 'docs/**' |
||||
- 'packages/**/*.md' |
||||
- 'latest.json' |
||||
|
||||
jobs: |
||||
docs: |
||||
name: Build & Verify Docs |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
|
||||
- name: Setup Node.js |
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version: '22.11.0' |
||||
cache: 'yarn' |
||||
|
||||
- name: Install dependencies |
||||
run: yarn install --immutable |
||||
|
||||
- name: Lint docs |
||||
run: yarn run prettier:checkDocs |
||||
env: |
||||
# Increase memory for prettier due to large number of files |
||||
NODE_OPTIONS: --max_old_space_size=8192 |
||||
|
||||
- name: Build docs website |
||||
run: | |
||||
# Create and start a container from the docs-base image in detached mode |
||||
docker run -d --name docs-builder grafana/docs-base:latest tail -f /dev/null |
||||
|
||||
# Create the directory structure inside the container |
||||
docker exec docs-builder mkdir -p /hugo/content/docs/grafana/latest |
||||
|
||||
# Create the _index.md file |
||||
docker exec docs-builder /bin/sh -c "echo -e '---\nredirectURL: /docs/grafana/latest/\ntype: redirect\nversioned: true\n---\n' > /hugo/content/docs/grafana/_index.md" |
||||
|
||||
# Copy the docs sources from the host to the container |
||||
docker cp docs/sources/. docs-builder:/hugo/content/docs/grafana/latest/ |
||||
|
||||
# Run the make prod command inside the container |
||||
docker exec -w /hugo docs-builder make prod || echo "Build completed with warnings" |
||||
|
||||
# Clean up the container |
||||
docker rm -f docs-builder |
@ -1,19 +0,0 @@ |
||||
name: Close Milestone |
||||
on: |
||||
workflow_dispatch: |
||||
inputs: |
||||
version_input: |
||||
description: 'The version to be released please respect: major.minor.patch, major.minor.patch-preview or major.minor.patch-preview<number> format. example: 7.4.3, 7.4.3-preview or 7.4.3-preview1' |
||||
required: true |
||||
jobs: |
||||
call-remove-milestone: |
||||
uses: grafana/grafana/.github/workflows/remove-milestone.yml@main |
||||
with: |
||||
version_call: ${{ github.event.inputs.version_input }} |
||||
secrets: inherit |
||||
call-close-milestone: |
||||
uses: grafana/grafana/.github/workflows/close-milestone.yml@main |
||||
with: |
||||
version_call: ${{ github.event.inputs.version_input }} |
||||
secrets: inherit |
||||
needs: call-remove-milestone |
@ -0,0 +1,71 @@ |
||||
name: Coverage |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
push: |
||||
branches: |
||||
- main |
||||
paths-ignore: |
||||
- 'docs/**' |
||||
- '**/*.md' |
||||
|
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
|
||||
env: |
||||
EDITION: 'oss' |
||||
WIRE_TAGS: 'oss' |
||||
|
||||
jobs: |
||||
main: |
||||
name: Backend Unit Tests |
||||
runs-on: ubuntu-latest-8-cores |
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- name: Setup Go |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: go.mod |
||||
cache: true |
||||
- name: Install dependencies |
||||
run: | |
||||
sudo apt-get update |
||||
sudo apt-get install -y build-essential shared-mime-info |
||||
go install github.com/mfridman/tparse@c1754a1f484ac5cd422697b0fec635177ddc8507 # v0.17.0 |
||||
- name: Generate Go code |
||||
run: make gen-go |
||||
- name: Run unit tests |
||||
run: COVER_OPTS="-coverprofile=be-unit.cov -coverpkg=github.com/grafana/grafana/..." GO_TEST_OUTPUT="/tmp/unit.log" make test-go-unit-cov |
||||
- name: Process and upload coverage |
||||
uses: ./.github/actions/test-coverage-processor |
||||
with: |
||||
test-type: 'be-unit' |
||||
# Needs to be named 'unit.cov' based on the Makefile command `make test-go-unit` |
||||
coverage-file: 'unit.cov' |
||||
codecov-token: ${{ secrets.CODECOV_TOKEN }} |
||||
codecov-flag: 'be-unit' |
||||
codecov-name: 'be-unit' |
||||
|
||||
- name: Install Grafana Bench |
||||
# We can't allow forks here, as we need secret access. |
||||
if: ${{ github.event_name != 'pull_request' }} |
||||
uses: ./.github/actions/setup-grafana-bench |
||||
|
||||
- name: Process output for Bench |
||||
if: ${{ github.event_name != 'pull_request' }} |
||||
run: | |
||||
grafana-bench report \ |
||||
--trigger pr-backend-unit-tests-oss \ |
||||
--report-input go \ |
||||
--report-output log \ |
||||
--grafana-version "$(git rev-parse HEAD)" \ |
||||
--suite-name grafana-oss-unit-tests \ |
||||
/tmp/unit.log || true |
||||
|
||||
concurrency: |
||||
group: ${{ github.workflow }}-${{ github.ref }} |
||||
cancel-in-progress: false |
@ -1,53 +0,0 @@ |
||||
name: "CodeQL for PR / go" |
||||
|
||||
on: |
||||
workflow_dispatch: |
||||
pull_request: |
||||
branches: [main] |
||||
paths: |
||||
- '**/*.go' |
||||
|
||||
permissions: |
||||
security-events: write |
||||
|
||||
jobs: |
||||
analyze: |
||||
name: Analyze |
||||
runs-on: ubuntu-latest |
||||
if: github.repository == 'grafana/grafana' |
||||
|
||||
steps: |
||||
- name: "Generate token" |
||||
id: generate_token |
||||
continue-on-error: true |
||||
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a |
||||
with: |
||||
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} |
||||
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} |
||||
|
||||
- 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 |
||||
token: ${{ steps.generate_token.outputs.token }} |
||||
|
||||
- name: Set go version |
||||
uses: actions/setup-go@v4 |
||||
with: |
||||
go-version-file: go.mod |
||||
|
||||
# Initializes the CodeQL tools for scanning. |
||||
- name: Initialize CodeQL |
||||
uses: github/codeql-action/init@v2 |
||||
with: |
||||
languages: "go" |
||||
|
||||
- name: Build go files |
||||
run: | |
||||
go mod verify |
||||
make build-go |
||||
|
||||
- name: Perform CodeQL Analysis |
||||
uses: github/codeql-action/analyze@v2 |
@ -0,0 +1,72 @@ |
||||
name: End-to-end tests |
||||
|
||||
on: |
||||
pull_request: |
||||
push: |
||||
branches: |
||||
- main |
||||
- release-*.*.* |
||||
|
||||
concurrency: |
||||
group: ${{ github.workflow }}-${{ github.ref }} |
||||
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} |
||||
|
||||
jobs: |
||||
build-grafana: |
||||
name: Build & Package Grafana |
||||
runs-on: ubuntu-latest-16-cores |
||||
outputs: |
||||
artifact: ${{ steps.artifact.outputs.artifact }} |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
repository: 'grafana/grafana-build' |
||||
ref: 'main' |
||||
persist-credentials: false |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
path: ./grafana |
||||
- run: echo "GRAFANA_GO_VERSION=$(grep "go 1." grafana/go.work | cut -d\ -f2)" >> "$GITHUB_ENV" |
||||
- uses: dagger/dagger-for-github@e47aba410ef9bb9ed81a4d2a97df31061e5e842e |
||||
with: |
||||
verb: run |
||||
args: go run ./cmd artifacts -a targz:grafana:linux/amd64 --grafana-dir=grafana --go-version=${GRAFANA_GO_VERSION} > out.txt |
||||
- run: mv $(cat out.txt) grafana.tar.gz |
||||
- run: echo "artifact=grafana-e2e-${{github.run_number}}" >> "$GITHUB_OUTPUT" |
||||
id: artifact |
||||
- uses: actions/upload-artifact@v4 |
||||
id: upload |
||||
with: |
||||
retention-days: 1 |
||||
name: ${{ steps.artifact.outputs.artifact }} |
||||
path: grafana.tar.gz |
||||
e2e-matrix: |
||||
name: ${{ matrix.suite }} |
||||
strategy: |
||||
matrix: |
||||
suite: |
||||
- various-suite |
||||
- dashboards-suite |
||||
- smoke-tests-suite |
||||
- panels-suite |
||||
needs: |
||||
- build-grafana |
||||
uses: ./.github/workflows/run-e2e-suite.yml |
||||
with: |
||||
package: ${{ needs.build-grafana.outputs.artifact }} |
||||
suite: ${{ matrix.suite }} |
||||
e2e-matrix-old-arch: |
||||
name: ${{ matrix.suite }} (old arch) |
||||
strategy: |
||||
matrix: |
||||
suite: |
||||
- old-arch/various-suite |
||||
- old-arch/dashboards-suite |
||||
- old-arch/smoke-tests-suite |
||||
- old-arch/panels-suite |
||||
needs: |
||||
- build-grafana |
||||
uses: ./.github/workflows/run-e2e-suite.yml |
||||
with: |
||||
package: ${{ needs.build-grafana.outputs.artifact }} |
||||
suite: ${{ matrix.suite }} |
@ -0,0 +1,69 @@ |
||||
name: Frontend tests |
||||
on: |
||||
pull_request: |
||||
push: |
||||
branches: |
||||
- main |
||||
- release-*.*.* |
||||
|
||||
permissions: {} |
||||
|
||||
jobs: |
||||
frontend-unit-tests: |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
# Run this workflow only for PRs from forks; if it gets merged into `main` or `release-*`, |
||||
# the `frontend-unit-tests-enterprise` workflow will run instead |
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true |
||||
runs-on: ubuntu-latest-8-cores |
||||
name: "Unit tests (${{ matrix.chunk }} / 8)" |
||||
strategy: |
||||
fail-fast: false |
||||
matrix: |
||||
chunk: [1, 2, 3, 4, 5, 6, 7, 8] |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
cache-dependency-path: 'yarn.lock' |
||||
- run: yarn install --immutable --check-cache |
||||
- run: yarn run test:ci |
||||
env: |
||||
TEST_MAX_WORKERS: 2 |
||||
TEST_SHARD: ${{ matrix.chunk }} |
||||
TEST_SHARD_TOTAL: 8 |
||||
|
||||
frontend-unit-tests-enterprise: |
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
# Run this workflow for non-PR events (like pushes to `main` or `release-*`) OR for internal PRs (PRs not from forks) |
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false |
||||
runs-on: ubuntu-latest-8-cores |
||||
name: "Unit tests (${{ matrix.chunk }} / 8)" |
||||
strategy: |
||||
fail-fast: false |
||||
matrix: |
||||
chunk: [1, 2, 3, 4, 5, 6, 7, 8] |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: '.nvmrc' |
||||
cache: 'yarn' |
||||
cache-dependency-path: 'yarn.lock' |
||||
- name: Setup Enterprise |
||||
uses: ./.github/actions/setup-enterprise |
||||
with: |
||||
github-app-name: 'grafana-ci-bot' |
||||
- run: yarn install --immutable --check-cache |
||||
- run: yarn run test:ci |
||||
env: |
||||
TEST_MAX_WORKERS: 2 |
||||
TEST_SHARD: ${{ matrix.chunk }} |
||||
TEST_SHARD_TOTAL: 8 |
@ -0,0 +1,89 @@ |
||||
name: Integration Tests |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- main |
||||
- release-*.*.* |
||||
pull_request: |
||||
|
||||
concurrency: |
||||
group: ${{ github.workflow }}-${{ github.ref }} |
||||
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} |
||||
|
||||
jobs: |
||||
sqlite: |
||||
name: Sqlite |
||||
runs-on: ubuntu-latest-8-cores |
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- name: Setup Go |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: go.mod |
||||
cache: true |
||||
- run: | |
||||
make gen-go |
||||
go test -tags=sqlite -timeout=5m -run '^TestIntegration' $(find ./pkg -type f -name '*_test.go' -exec grep -l '^func TestIntegration' '{}' '+' | grep -o '\(.*\)/' | sort -u) |
||||
mysql: |
||||
name: MySQL |
||||
runs-on: ubuntu-latest-8-cores |
||||
env: |
||||
GRAFANA_TEST_DB: mysql |
||||
MYSQL_HOST: 127.0.0.1 |
||||
services: |
||||
mysql: |
||||
image: mysql:8.0.32 |
||||
env: |
||||
MYSQL_ROOT_PASSWORD: rootpass |
||||
MYSQL_DATABASE: grafana_tests |
||||
MYSQL_USER: grafana |
||||
MYSQL_PASSWORD: password |
||||
options: --health-cmd="mysqladmin ping --silent" --health-interval=10s --health-timeout=5s --health-retries=3 |
||||
ports: |
||||
- 3306:3306 |
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- name: Setup Go |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: go.mod |
||||
cache: true |
||||
- run: | |
||||
sudo apt-get update -yq && sudo apt-get install mariadb-client |
||||
cat devenv/docker/blocks/mysql_tests/setup.sql | mariadb -h 127.0.0.1 -P 3306 -u root -prootpass --disable-ssl-verify-server-cert |
||||
make gen-go |
||||
go test -tags=mysql -p=1 -timeout=5m -run '^TestIntegration' $(find ./pkg -type f -name '*_test.go' -exec grep -l '^func TestIntegration' '{}' '+' | grep -o '\(.*\)/' | sort -u) |
||||
postgres: |
||||
name: Postgres |
||||
runs-on: ubuntu-latest-8-cores |
||||
services: |
||||
postgres: |
||||
image: postgres:12.3-alpine |
||||
env: |
||||
POSTGRES_USER: grafanatest |
||||
POSTGRES_PASSWORD: grafanatest |
||||
POSTGRES_DB: grafanatest |
||||
ports: |
||||
- 5432:5432 |
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- name: Setup Go |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: go.mod |
||||
cache: true |
||||
- env: |
||||
GRAFANA_TEST_DB: postgres |
||||
PGPASSWORD: grafanatest |
||||
POSTGRES_HOST: 127.0.0.1 |
||||
run: | |
||||
sudo apt-get update -yq && sudo apt-get install postgresql-client |
||||
psql -p 5432 -h 127.0.0.1 -U grafanatest -d grafanatest -f devenv/docker/blocks/postgres_tests/setup.sql |
||||
make gen-go |
||||
go test -p=1 -tags=postgres -timeout=5m -run '^TestIntegration' $(find ./pkg -type f -name '*_test.go' -exec grep -l '^func TestIntegration' '{}' '+' | grep -o '\(.*\)/' | sort -u) |
@ -1,60 +0,0 @@ |
||||
name: Remove milestone |
||||
on: |
||||
workflow_dispatch: |
||||
inputs: |
||||
version: |
||||
required: true |
||||
description: Needs to match, exactly, the name of a milestone |
||||
workflow_call: |
||||
inputs: |
||||
version_call: |
||||
description: Needs to match, exactly, the name of a milestone |
||||
required: true |
||||
type: string |
||||
|
||||
jobs: |
||||
config: |
||||
runs-on: "ubuntu-latest" |
||||
outputs: |
||||
has-secrets: ${{ steps.check.outputs.has-secrets }} |
||||
steps: |
||||
- name: "Check for secrets" |
||||
id: check |
||||
shell: bash |
||||
run: | |
||||
if [ -n "${{ (secrets.GRAFANA_DELIVERY_BOT_APP_ID != '' && secrets.GRAFANA_DELIVERY_BOT_APP_PEM != '') || '' }}" ]; then |
||||
echo "has-secrets=1" >> "$GITHUB_OUTPUT" |
||||
fi |
||||
|
||||
main: |
||||
needs: config |
||||
if: needs.config.outputs.has-secrets |
||||
permissions: |
||||
issues: write |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Checkout Actions |
||||
uses: actions/checkout@v4 |
||||
with: |
||||
repository: "grafana/grafana-github-actions" |
||||
path: ./actions |
||||
ref: main |
||||
- name: Install Actions |
||||
run: npm install --production --prefix ./actions |
||||
- name: "Generate token" |
||||
id: generate_token |
||||
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 |
||||
with: |
||||
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} |
||||
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} |
||||
- name: Remove milestone from open issues (manually invoked) |
||||
if: ${{ github.event.inputs.version != '' }} |
||||
uses: ./actions/remove-milestone |
||||
with: |
||||
token: ${{ steps.generate_token.outputs.token }} |
||||
- name: Remove milestone from open issues (workflow invoked) |
||||
if: ${{ inputs.version_call != '' }} |
||||
uses: ./actions/remove-milestone |
||||
with: |
||||
version_call: ${{ inputs.version_call }} |
||||
token: ${{ steps.generate_token.outputs.token }} |
@ -0,0 +1,130 @@ |
||||
name: run-dashboard-search-e2e |
||||
|
||||
on: |
||||
workflow_run: |
||||
workflows: |
||||
- trigger-dashboard-search-e2e |
||||
types: |
||||
- completed |
||||
workflow_dispatch: |
||||
|
||||
env: |
||||
ARCH: linux-amd64 |
||||
|
||||
permissions: {} |
||||
|
||||
jobs: |
||||
setup: |
||||
runs-on: ubuntu-latest |
||||
if: github.event.pull_request.draft == false |
||||
outputs: |
||||
ini_files: ${{ steps.get_files.outputs.ini_files }} |
||||
|
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
steps: |
||||
- name: Checkout |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- name: Pin Go version to mod file |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: 'go.mod' |
||||
cache: true |
||||
- run: go version |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version: 20 |
||||
cache: 'yarn' |
||||
- name: Cache Node Modules |
||||
id: cache-node-modules |
||||
uses: actions/cache@v3 |
||||
with: |
||||
path: | |
||||
node_modules |
||||
/home/runner/.cache/Cypress |
||||
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} |
||||
- name: Install dependencies |
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true' |
||||
run: yarn install --immutable |
||||
- name: Install Cypress dependencies |
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true' |
||||
uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f |
||||
with: |
||||
runTests: false |
||||
- name: Cache Grafana Build and Dependencies |
||||
id: cache-grafana |
||||
uses: actions/cache@v3 |
||||
with: |
||||
path: | |
||||
bin/ |
||||
scripts/grafana-server/ |
||||
tools/ |
||||
public/ |
||||
conf/ |
||||
e2e/test-plugins/ |
||||
devenv/ |
||||
key: ${{ runner.os }}-grafana-${{ hashFiles('go.mod', 'package-lock.json', 'Makefile', 'pkg/storage/**/*.go', 'public/app/features/search/**/*.ts', 'public/app/features/search/**/*.tsx') }} |
||||
# only rebuild grafana if search files have changed ( or dependencies ) |
||||
- name: Build Grafana (Runs Only If Not Cached) |
||||
if: steps.cache-grafana.outputs.cache-hit != 'true' |
||||
run: make build |
||||
|
||||
- name: Get list of .ini files |
||||
id: get_files |
||||
run: | |
||||
INI_FILES=$(ls ${{ github.workspace }}/e2e/dashboards-search-suite/*.ini | jq -R -s -c 'split("\n")[:-1]') |
||||
echo "ini_files=$INI_FILES" >> $GITHUB_OUTPUT |
||||
shell: bash |
||||
|
||||
run_tests: |
||||
needs: setup |
||||
runs-on: ubuntu-latest |
||||
continue-on-error: true |
||||
if: github.event.pull_request.draft == false |
||||
strategy: |
||||
matrix: |
||||
ini_file: ${{ fromJson(needs.setup.outputs.ini_files) }} |
||||
|
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
|
||||
steps: |
||||
- name: Checkout repository |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
- name: Restore Cached Node Modules |
||||
uses: actions/cache@v3 |
||||
with: |
||||
path: | |
||||
node_modules |
||||
/home/runner/.cache/Cypress |
||||
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} |
||||
|
||||
- name: Restore Cached Grafana Build and Dependencies |
||||
uses: actions/cache@v3 |
||||
with: |
||||
path: | |
||||
bin/ |
||||
scripts/grafana-server/ |
||||
tools/ |
||||
public/ |
||||
conf/ |
||||
e2e/test-plugins/ |
||||
devenv/ |
||||
key: ${{ runner.os }}-grafana-${{ hashFiles('go.mod', 'package-lock.json', 'Makefile', 'pkg/storage/**/*.go', 'public/app/features/search/**/*.ts', 'public/app/features/search/**/*.tsx') }} |
||||
- name: Set the step name |
||||
id: set_file_name |
||||
env: |
||||
INI_NAME: ${{ matrix.ini_file }} |
||||
run: | |
||||
FILE_NAME=$(basename "$env.INI_NAME" .ini) |
||||
echo "FILE_NAME=$FILE_NAME" >> $GITHUB_OUTPUT |
||||
- name: Run tests for ${{ steps.set_file_name.outputs.FILE_NAME }} |
||||
env: |
||||
INI_NAME: ${{ matrix.ini_file }} |
||||
run: | |
||||
cp -rf $INI_NAME ${{ github.workspace }}/scripts/grafana-server/custom.ini |
||||
yarn e2e:dashboards-search || echo "Test failed but marking as success since unified search is behind a feature flag and should not block PRs" |
@ -0,0 +1,39 @@ |
||||
name: e2e suite |
||||
|
||||
on: |
||||
workflow_call: |
||||
inputs: |
||||
package: |
||||
type: string |
||||
required: true |
||||
suite: |
||||
type: string |
||||
required: true |
||||
|
||||
jobs: |
||||
main: |
||||
runs-on: ubuntu-latest-8-cores |
||||
steps: |
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- uses: actions/download-artifact@v4 |
||||
with: |
||||
name: ${{ inputs.package }} |
||||
- uses: dagger/dagger-for-github@e47aba410ef9bb9ed81a4d2a97df31061e5e842e |
||||
if: inputs.old-arch == false |
||||
with: |
||||
verb: run |
||||
args: go run ./pkg/build/e2e --package=grafana.tar.gz --suite=${{ inputs.suite }} |
||||
- name: Set suite name |
||||
id: set-suite-name |
||||
env: |
||||
SUITE: ${{ inputs.suite }} |
||||
run: | |
||||
echo "suite=$(echo $SUITE | sed 's/\//-/g')" >> $GITHUB_OUTPUT |
||||
- uses: actions/upload-artifact@v4 |
||||
if: ${{ always() && inputs.old-arch != true }} |
||||
with: |
||||
name: e2e-${{ steps.set-suite-name.outputs.suite }}-${{github.run_number}} |
||||
path: videos |
||||
retention-days: 1 |
@ -0,0 +1,46 @@ |
||||
name: Run dashboard schema v2 e2e |
||||
|
||||
on: |
||||
push: |
||||
branches: |
||||
- main |
||||
pull_request: |
||||
branches: |
||||
- '**' |
||||
|
||||
env: |
||||
ARCH: linux-amd64 |
||||
|
||||
jobs: |
||||
dashboard-schema-v2-e2e: |
||||
runs-on: ubuntu-latest |
||||
continue-on-error: true |
||||
if: github.event.pull_request.draft == false |
||||
steps: |
||||
- name: Checkout |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
- name: Pin Go version to mod file |
||||
uses: actions/setup-go@111f3307d8850f501ac008e886eec1fd1932a34 |
||||
with: |
||||
go-version-file: 'go.mod' |
||||
- run: go version |
||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version: 20 |
||||
cache: 'yarn' |
||||
- name: Install dependencies |
||||
run: yarn install --immutable |
||||
- name: Build grafana |
||||
run: make build |
||||
- name: Install Cypress dependencies |
||||
uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f |
||||
with: |
||||
runTests: false |
||||
- name: Run dashboard scenes e2e |
||||
run: yarn e2e:schema-v2 || echo "Test failed but marking as success since schema V2 is behind a feature flag and should not block PRs" |
||||
|
||||
- name: Always succeed # This is a workaround to make the job pass even if the previous step fails |
||||
if: failure() |
||||
run: exit 0 |
@ -1,15 +0,0 @@ |
||||
name: syft-sbom-ci |
||||
on: |
||||
release: |
||||
types: [ published ] |
||||
workflow_dispatch: |
||||
jobs: |
||||
syft-sbom: |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: Checkout |
||||
uses: actions/checkout@v4 |
||||
- name: Anchore SBOM Action |
||||
uses: grafana/shared-workflows/actions@syft-sbom-v0.0.1 |
||||
with: |
||||
artifact-name: ${{ github.event.repository.name }}-spdx.json |
@ -0,0 +1,84 @@ |
||||
const crowdin = require('@crowdin/crowdin-api-client'); |
||||
const TRANSLATED_CONNECTOR_DESCRIPTION = '{{tos_service_type: premium}}'; |
||||
|
||||
const API_TOKEN = process.env.CROWDIN_PERSONAL_TOKEN; |
||||
if (!API_TOKEN) { |
||||
console.error('Error: CROWDIN_PERSONAL_TOKEN environment variable is not set'); |
||||
process.exit(1); |
||||
} |
||||
|
||||
const PROJECT_ID = process.env.CROWDIN_PROJECT_ID; |
||||
if (!PROJECT_ID) { |
||||
console.error('Error: CROWDIN_PROJECT_ID environment variable is not set'); |
||||
process.exit(1); |
||||
} |
||||
|
||||
const { tasksApi, projectsGroupsApi, sourceFilesApi } = new crowdin.default({ |
||||
token: API_TOKEN, |
||||
organization: 'grafana' |
||||
}); |
||||
|
||||
const languages = await getLanguages(); |
||||
const fileIds = await getFileIds(); |
||||
console.log('Languages: ', languages); |
||||
console.log('File IDs: ', fileIds); |
||||
|
||||
// for (const language of languages) {
|
||||
// const { name, id } = language;
|
||||
// await createTask(`Translate to ${name}`, id, fileIds);
|
||||
// }
|
||||
|
||||
async function getLanguages() { |
||||
try { |
||||
const project = await projectsGroupsApi.getProject(PROJECT_ID); |
||||
const languages = project.data.targetLanguages; |
||||
return languages; |
||||
} catch (error) { |
||||
console.error('Failed to fetch languages: ', error.message); |
||||
if (error.response && error.response.data) { |
||||
console.error('Error details: ', JSON.stringify(error.response.data, null, 2)); |
||||
} |
||||
process.exit(1); |
||||
} |
||||
} |
||||
|
||||
async function getFileIds() { |
||||
try { |
||||
const response = await sourceFilesApi.listProjectFiles(PROJECT_ID); |
||||
const files = response.data; |
||||
const fileIds = files.map(file => file.data.id); |
||||
return fileIds; |
||||
} catch (error) { |
||||
console.error('Failed to fetch file IDs: ', error.message); |
||||
if (error.response && error.response.data) { |
||||
console.error('Error details: ', JSON.stringify(error.response.data, null, 2)); |
||||
} |
||||
process.exit(1); |
||||
} |
||||
} |
||||
|
||||
async function createTask(title, languageId, fileIds) { |
||||
try { |
||||
const taskParams = { |
||||
title, |
||||
description: TRANSLATED_CONNECTOR_DESCRIPTION, |
||||
languageId, |
||||
type: 2, // Translation by vendor
|
||||
workflowStepId: 78, // Translation step ID
|
||||
skipAssignedStrings: true, |
||||
fileIds, |
||||
}; |
||||
|
||||
console.log(`Creating Crowdin task: "${title}" for language ${languageId}`); |
||||
|
||||
const response = await tasksApi.addTask(PROJECT_ID, taskParams); |
||||
console.log(`Task created successfully! Task ID: ${response.data.id}`); |
||||
return response.data; |
||||
} catch (error) { |
||||
console.error('Failed to create Crowdin task: ', error.message); |
||||
if (error.response && error.response.data) { |
||||
console.error('Error details: ', JSON.stringify(error.response.data, null, 2)); |
||||
} |
||||
process.exit(1); |
||||
} |
||||
} |
@ -0,0 +1,106 @@ |
||||
name: Add issues and PRs to Skye project board |
||||
on: |
||||
workflow_dispatch: |
||||
inputs: |
||||
manual_issue_number: |
||||
description: 'Issue/PR number to add to project' |
||||
required: false |
||||
type: number |
||||
issues: |
||||
types: [opened] |
||||
pull_request: |
||||
types: [opened] |
||||
|
||||
permissions: |
||||
contents: read |
||||
id-token: write |
||||
|
||||
env: |
||||
ORGANIZATION: grafana |
||||
REPO: grafana |
||||
PROJECT_ID: "PVT_kwDOAG3Mbc4AxfcI" # Retrieved manually from GitHub GraphQL Explorer |
||||
|
||||
concurrency: |
||||
group: skye-add-to-project-${{ github.event.number }} |
||||
|
||||
jobs: |
||||
main: |
||||
if: github.repository == 'grafana/grafana' |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: "Get vault secrets" |
||||
id: vault-secrets |
||||
uses: grafana/shared-workflows/actions/get-vault-secrets@main # zizmor: ignore[unpinned-uses] |
||||
with: |
||||
# Vault secret paths: |
||||
# - ci/repo/grafana/grafana/plugins_platform_issue_commands_github_bot |
||||
# - ci/repo/grafana/grafana/frontend_platform_skye_usernames (comma separated list of usernames) |
||||
repo_secrets: | |
||||
GH_APP_ID=plugins_platform_issue_commands_github_bot:app_id |
||||
GH_APP_PEM=plugins_platform_issue_commands_github_bot:app_pem |
||||
ALLOWED_USERS=frontend_platform_skye_usernames:allowed_users |
||||
|
||||
- name: Generate token |
||||
id: generate_token |
||||
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 |
||||
with: |
||||
app_id: ${{ env.GH_APP_ID }} |
||||
private_key: ${{ env.GH_APP_PEM }} |
||||
|
||||
# Check if the user is in the list from the secret |
||||
- name: Check if user is allowed |
||||
id: check_user |
||||
env: |
||||
ALLOWED_USERS: ${{ env.ALLOWED_USERS }} |
||||
USERNAME: ${{ github.event.sender.login }} |
||||
run: | |
||||
# Convert the comma-separated list to an array |
||||
IFS=',' read -ra ALLOWED_USERS <<< "$ALLOWED_USERS" |
||||
|
||||
# Check if user is in the allowed list |
||||
for allowed_user in "${ALLOWED_USERS[@]}"; do |
||||
if [ "$allowed_user" = "$USERNAME" ]; then |
||||
echo "user_allowed=true" >> $GITHUB_OUTPUT |
||||
exit 0 |
||||
fi |
||||
done |
||||
echo "user_allowed=false" >> $GITHUB_OUTPUT |
||||
|
||||
# Convert the issue/PR number to a node ID for the GraphQL API |
||||
- name: Get node ID for item |
||||
if: steps.check_user.outputs.user_allowed == 'true' |
||||
id: get_node_id |
||||
uses: octokit/graphql-action@51bf543c240dcd14761320e2efc625dc32ec0d32 |
||||
with: |
||||
query: | |
||||
query getNodeId($owner: String!, $repo: String!, $number: Int!) { |
||||
repository(owner: $owner, name: $repo) { |
||||
issueOrPullRequest(number: $number) { |
||||
... on Issue { id } |
||||
... on PullRequest { id } |
||||
} |
||||
} |
||||
} |
||||
variables: | |
||||
owner: ${{ env.ORGANIZATION }} |
||||
repo: ${{ env.REPO }} |
||||
number: ${{ github.event.number || github.event.inputs.manual_issue_number }} |
||||
env: |
||||
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} |
||||
|
||||
# Finally, add the issue/PR to the project board |
||||
- name: Add to project board |
||||
if: steps.check_user.outputs.user_allowed == 'true' |
||||
uses: octokit/graphql-action@51bf543c240dcd14761320e2efc625dc32ec0d32 |
||||
with: |
||||
query: | |
||||
mutation addItem($projectid: ID!, $itemid: ID!) { |
||||
addProjectV2ItemById(input: {projectId: $projectid, contentId: $itemid}) { |
||||
item { id } |
||||
} |
||||
} |
||||
variables: | |
||||
projectid: ${{ env.PROJECT_ID }} |
||||
itemid: ${{ fromJSON(steps.get_node_id.outputs.data).repository.issueOrPullRequest.id }} |
||||
env: |
||||
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} |
@ -0,0 +1,48 @@ |
||||
name: Verify Storybook |
||||
|
||||
on: |
||||
pull_request: |
||||
paths: |
||||
- 'packages/grafana-ui/**' |
||||
- '!docs/**' |
||||
- '!*.md' |
||||
push: |
||||
branches: |
||||
- main |
||||
paths: |
||||
- 'packages/grafana-ui/**' |
||||
- '!docs/**' |
||||
- '!*.md' |
||||
|
||||
jobs: |
||||
verify-storybook: |
||||
name: Verify Storybook |
||||
runs-on: ubuntu-latest |
||||
|
||||
steps: |
||||
- name: Checkout code |
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
||||
with: |
||||
persist-credentials: false |
||||
|
||||
- name: Setup Node.js |
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e |
||||
with: |
||||
node-version-file: 'package.json' |
||||
cache: 'yarn' |
||||
|
||||
- name: Install dependencies |
||||
run: yarn install --immutable |
||||
|
||||
- name: Run Storybook and E2E tests |
||||
uses: cypress-io/github-action@108b8684ae52e735ff7891524cbffbcd4be5b19f |
||||
with: |
||||
browser: chrome |
||||
start: yarn storybook --quiet |
||||
wait-on: 'http://localhost:9001' |
||||
wait-on-timeout: 60 |
||||
command: yarn e2e:storybook |
||||
install: false |
||||
env: |
||||
HOST: localhost |
||||
PORT: 9001 |
@ -0,0 +1,28 @@ |
||||
name: trigger-dashboard-search-e2e |
||||
# triggers the dashboard search e2e tests which runs async |
||||
# doesn't block prs, allows setting up notifications from grafana |
||||
on: |
||||
push: |
||||
branches: |
||||
- main |
||||
paths: |
||||
- public/app/features/search/**/*.ts |
||||
- public/app/features/search/**/*.tsx |
||||
- pkg/storage/**/*.go |
||||
pull_request: |
||||
branches: |
||||
- main |
||||
paths: |
||||
- public/app/features/search/**/*.ts |
||||
- public/app/features/search/**/*.tsx |
||||
- pkg/storage/**/*.go |
||||
env: |
||||
ARCH: linux-amd64 |
||||
|
||||
jobs: |
||||
trigger-search-e2e: |
||||
runs-on: ubuntu-latest |
||||
if: github.event.pull_request.draft == false |
||||
steps: |
||||
- name: Trigger Dashboard Search E2E |
||||
run: echo "Triggered Dashboard Search e2e..." |
@ -1,52 +0,0 @@ |
||||
name: Update changelog |
||||
on: |
||||
workflow_dispatch: |
||||
inputs: |
||||
version: |
||||
required: true |
||||
description: 'Needs to match, exactly, the name of a milestone. The version to be released please respect: major.minor.patch, major.minor.patch-preview or major.minor.patch-preview<number> format. example: 7.4.3, 7.4.3-preview or 7.4.3-preview1' |
||||
skip_pr: |
||||
required: false |
||||
default: "0" |
||||
skip_community_post: |
||||
required: false |
||||
default: "0" |
||||
jobs: |
||||
config: |
||||
runs-on: "ubuntu-latest" |
||||
outputs: |
||||
has-secrets: ${{ steps.check.outputs.has-secrets }} |
||||
steps: |
||||
- name: "Check for secrets" |
||||
id: check |
||||
shell: bash |
||||
run: | |
||||
if [ -n "${{ (secrets.GRAFANA_DELIVERY_BOT_APP_ID != '' && |
||||
secrets.GRAFANA_DELIVERY_BOT_APP_PEM != '' && |
||||
secrets.GRAFANA_MISC_STATS_API_KEY != '' && |
||||
secrets.GRAFANABOT_FORUM_KEY != '' |
||||
) || '' }}" ]; then |
||||
echo "has-secrets=1" >> "$GITHUB_OUTPUT" |
||||
fi |
||||
|
||||
main: |
||||
needs: config |
||||
if: needs.config.outputs.has-secrets |
||||
runs-on: ubuntu-latest |
||||
steps: |
||||
- name: "Generate token" |
||||
id: generate_token |
||||
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 |
||||
with: |
||||
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} |
||||
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} |
||||
- name: Run update changelog (manually invoked) |
||||
uses: grafana/grafana-github-actions-go/update-changelog@main |
||||
with: |
||||
token: ${{ steps.generate_token.outputs.token }} |
||||
version: ${{ inputs.version }} |
||||
metrics_api_key: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }} |
||||
community_api_key: ${{ secrets.GRAFANABOT_FORUM_KEY }} |
||||
community_api_username: grafanabot |
||||
skip_pr: ${{ inputs.skip_pr }} |
||||
skip_community_post: ${{ inputs.skip_community_post }} |
@ -0,0 +1,23 @@ |
||||
name: Zizmor GitHub Actions static analysis |
||||
on: |
||||
pull_request: |
||||
push: |
||||
branches: |
||||
- main |
||||
|
||||
jobs: |
||||
zizmor: |
||||
name: Analyse with Zizmor |
||||
|
||||
permissions: |
||||
actions: read |
||||
contents: read |
||||
# required to comment on pull requests with the results of the check |
||||
pull-requests: write |
||||
# required to upload the results to GitHub's code scanning service |
||||
security-events: write |
||||
|
||||
uses: grafana/shared-workflows/.github/workflows/reusable-zizmor.yml@main # zizmor: ignore[unpinned-uses] |
||||
with: |
||||
fail-severity: high |
||||
min-severity: high |
@ -0,0 +1,31 @@ |
||||
rules: |
||||
unpinned-uses: |
||||
config: |
||||
policies: |
||||
"*": hash-pin |
||||
actions/*: any |
||||
github/*: any |
||||
grafana/*: any |
||||
forbidden-uses: |
||||
config: |
||||
deny: |
||||
# Policy-banned by our security team due to CVE-2025-30066 & CVE-2025-30154. |
||||
# https://www.cisa.gov/news-events/alerts/2025/03/18/supply-chain-compromise-third-party-tj-actionschanged-files-cve-2025-30066-and-reviewdogaction |
||||
# https://nvd.nist.gov/vuln/detail/cve-2025-30066 |
||||
# https://nvd.nist.gov/vuln/detail/cve-2025-30154 |
||||
- reviewdog/* |
||||
cache-poisoning: |
||||
ignore: |
||||
- backend-unit-tests.yml |
||||
- frontend-lint.yml |
||||
- pr-frontend-unit-tests.yml |
||||
- pr-test-integration.yml |
||||
- publish-kinds-release.yml |
||||
dangerous-triggers: |
||||
ignore: |
||||
- auto-milestone.yml |
||||
- backport.yml |
||||
- pr-checks.yml |
||||
- pr-commands.yml |
||||
- pr-patch-check-event.yml |
||||
- run-dashboard-search-e2e.yml |
Loading…
Reference in new issue