diff --git a/.github/labeler.yml b/.github/labeler.yml
new file mode 100644
index 0000000..2d04e26
--- /dev/null
+++ b/.github/labeler.yml
@@ -0,0 +1,3 @@
+# Add 'code-scanning' label to any changes within 'code-scanning' folder or any subfolders
+code-scanning:
+- code-scanning/**/*
diff --git a/.github/workflows/labeler-triage.yml b/.github/workflows/labeler-triage.yml
new file mode 100644
index 0000000..eba05f0
--- /dev/null
+++ b/.github/workflows/labeler-triage.yml
@@ -0,0 +1,16 @@
+name: "Pull Request Labeler"
+
+permissions:
+ contents: read
+ pull-requests: write
+
+on:
+- pull_request_target
+
+jobs:
+ triage:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/labeler@v3
+ with:
+ repo-token: "${{ secrets.GITHUB_TOKEN }}"
\ No newline at end of file
diff --git a/CODEOWNERS b/CODEOWNERS
index 3732a32..8866d17 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1,3 +1,3 @@
-* @actions/actions-experience
+* @actions/starter-workflows
/code-scanning/ @actions/advanced-security-code-scanning
diff --git a/README.md b/README.md
index e276691..4b5b9f8 100644
--- a/README.md
+++ b/README.md
@@ -10,8 +10,9 @@ These are the workflow files for helping people get started with GitHub Actions.
-**Directory structure:**
-* [ci](ci): solutions for Continuous Integration
+### Directory structure
+
+* [ci](ci): solutions for Continuous Integration and Deployments
* [automation](automation): solutions for automating workflows.
* [code-scanning](code-scanning): starter workflows for [Code Scanning](https://github.com/features/security)
* [icons](icons): svg icons for the relevant template
@@ -20,8 +21,28 @@ Each workflow must be written in YAML and have a `.yml` extension. They also nee
For example: `ci/django.yml` and `ci/properties/django.properties.json`.
-**Valid properties:**
-* `name`: the name shown in onboarding
+### Valid properties
+
+* `name`: the name shown in onboarding. This property is unique within the repository.
* `description`: the description shown in onboarding
-* `iconName`: the icon name in the relevant folder, for example `django` should have an icon `icons/django.svg`. Only SVG is supported at this time
-* `categories`: the categories that it will be shown under
+* `iconName`: the icon name in the relevant folder, for example, `django` should have an icon `icons/django.svg`. Only SVG is supported at this time. Another option is to use [octicon](https://primer.style/octicons/). The format to use an octicon is `octicon <>`. Example: `octicon person`
+* `creator`: creator of the template shown in onboarding. All the workflow templates from an author will have the same `creator` field.
+* `categories`: the categories that it will be shown under. Choose at least one category from the list [here](#categories). Further, choose the categories from the list of languages available [here](https://github.com/github/linguist/blob/master/lib/linguist/languages.yml). When a user views the available templates, those templates that match the same language will feature more prominently.
+
+### Categories
+* continuous-integration
+* deployment
+* testing
+* code-quality
+* code-review
+* dependency-management
+* monitoring
+* Automation
+* utilities
+
+### Variables
+These variables can be placed in the starter workflow and will be substituted as detailed below:
+
+* `$default-branch`: will substitute the branch from the repository, for example `main` and `master`
+* `$protected-branches`: will substitue any protected branches from the repository.
+* `$cron-daily`: will substitute a valid but random time within the day
diff --git a/ci/android.yml b/ci/android.yml
index 4bbc689..3037b9f 100644
--- a/ci/android.yml
+++ b/ci/android.yml
@@ -18,6 +18,7 @@ jobs:
with:
java-version: '11'
distribution: 'adopt'
+ cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
diff --git a/ci/deno.yml b/ci/deno.yml
index cf91f5e..38f2319 100644
--- a/ci/deno.yml
+++ b/ci/deno.yml
@@ -3,7 +3,7 @@
# separate terms of service, privacy policy, and support
# documentation.
-# This workflow will install Deno and run tests across stable and canary builds on Windows, Ubuntu and macOS.
+# This workflow will install Deno then run Deno lint and test.
# For more information see: https://github.com/denoland/setup-deno
name: Deno
@@ -16,12 +16,7 @@ on:
jobs:
test:
- runs-on: ${{ matrix.os }} # runs a test on Ubuntu, Windows and macOS
-
- strategy:
- matrix:
- deno: ["v1.x", "canary"]
- os: [macOS-latest, windows-latest, ubuntu-latest]
+ runs-on: ubuntu-latest
steps:
- name: Setup repo
@@ -29,9 +24,9 @@ jobs:
- name: Setup Deno
# uses: denoland/setup-deno@v1
- uses: denoland/setup-deno@4a4e59637fa62bd6c086a216c7e4c5b457ea9e79
+ uses: denoland/setup-deno@004814556e37c54a2f6e31384c9e18e9833173669
with:
- deno-version: ${{ matrix.deno }} # tests across multiple Deno versions
+ deno-version: v1.x
# Uncomment this step to verify the use of 'deno fmt' on each commit.
# - name: Verify formatting
@@ -40,8 +35,5 @@ jobs:
- name: Run linter
run: deno lint
- - name: Cache dependencies
- run: deno cache deps.ts
-
- name: Run tests
run: deno test -A --unstable
diff --git a/ci/go.yml b/ci/go.yml
index 22a110a..afff652 100644
--- a/ci/go.yml
+++ b/ci/go.yml
@@ -16,7 +16,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
- go-version: 1.16
+ go-version: 1.17
- name: Build
run: go build -v ./...
diff --git a/ci/gradle.yml b/ci/gradle.yml
index 6e7e922..5ecabba 100644
--- a/ci/gradle.yml
+++ b/ci/gradle.yml
@@ -1,4 +1,4 @@
-# This workflow will build a Java project with Gradle
+# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Java CI with Gradle
@@ -21,6 +21,7 @@ jobs:
with:
java-version: '11'
distribution: 'adopt'
+ cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
diff --git a/ci/grunt.yml b/ci/grunt.yml
new file mode 100644
index 0000000..8c83cb6
--- /dev/null
+++ b/ci/grunt.yml
@@ -0,0 +1,28 @@
+name: NodeJS with Grunt
+
+on:
+ push:
+ branches: [ $default-branch ]
+ pull_request:
+ branches: [ $default-branch ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [12.x, 14.x, 16.x]
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Build
+ run: |
+ npm install
+ grunt
diff --git a/ci/gulp.yml b/ci/gulp.yml
new file mode 100644
index 0000000..cc5da13
--- /dev/null
+++ b/ci/gulp.yml
@@ -0,0 +1,28 @@
+name: NodeJS with Gulp
+
+on:
+ push:
+ branches: [ $default-branch ]
+ pull_request:
+ branches: [ $default-branch ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [12.x, 14.x, 16.x]
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Build
+ run: |
+ npm install
+ gulp
diff --git a/ci/ios.yml b/ci/ios.yml
index 032b77a..ab92d32 100644
--- a/ci/ios.yml
+++ b/ci/ios.yml
@@ -26,7 +26,7 @@ jobs:
platform: ${{ 'iOS Simulator' }}
run: |
# xcrun xctrace returns via stderr, not the expected stdout (see https://developer.apple.com/forums/thread/663959)
- device=`xcrun xctrace list devices 2>&1 | grep -oE 'iPhone.*?[^\(]+' | head -1 | awk '{$1=$1;print}'``
+ device=`xcrun xctrace list devices 2>&1 | grep -oE 'iPhone.*?[^\(]+' | head -1 | awk '{$1=$1;print}'`
if [ $scheme = default ]; then scheme=$(cat default); fi
if [ "`ls -A | grep -i \\.xcworkspace\$`" ]; then filetype_parameter="workspace" && file_to_build="`ls -A | grep -i \\.xcworkspace\$`"; else filetype_parameter="project" && file_to_build="`ls -A | grep -i \\.xcodeproj\$`"; fi
file_to_build=`echo $file_to_build | awk '{$1=$1;print}'`
diff --git a/ci/maven.yml b/ci/maven.yml
index 923425b..ac3b6de 100644
--- a/ci/maven.yml
+++ b/ci/maven.yml
@@ -1,4 +1,4 @@
-# This workflow will build a Java project with Maven
+# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI with Maven
@@ -21,5 +21,6 @@ jobs:
with:
java-version: '11'
distribution: 'adopt'
+ cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml
diff --git a/ci/node.js.yml b/ci/node.js.yml
index 2f60984..89b24fe 100644
--- a/ci/node.js.yml
+++ b/ci/node.js.yml
@@ -1,4 +1,4 @@
-# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
@@ -25,6 +25,7 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
+ cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
diff --git a/ci/npm-publish.yml b/ci/npm-publish.yml
index 8462902..025976d 100644
--- a/ci/npm-publish.yml
+++ b/ci/npm-publish.yml
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
- node-version: 12
+ node-version: 14
- run: npm ci
- run: npm test
@@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
- node-version: 12
+ node-version: 14
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm publish
@@ -42,7 +42,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
- node-version: 12
+ node-version: 14
registry-url: $registry-url(npm)
- run: npm ci
- run: npm publish
diff --git a/ci/properties/blank.properties.json b/ci/properties/blank.properties.json
index d244772..610327f 100644
--- a/ci/properties/blank.properties.json
+++ b/ci/properties/blank.properties.json
@@ -1,6 +1,7 @@
{
"name": "Simple workflow",
"description": "Start with a file with the minimum necessary structure.",
+ "creator": "GitHub",
"iconName": "blank",
"categories": null
}
diff --git a/ci/properties/gem-push.properties.json b/ci/properties/gem-push.properties.json
index af43020..0002ac5 100644
--- a/ci/properties/gem-push.properties.json
+++ b/ci/properties/gem-push.properties.json
@@ -2,5 +2,5 @@
"name": "Ruby Gem",
"description": "Pushes a Ruby Gem to RubyGems and GitHub Package Registry.",
"iconName": "ruby-gems",
- "categories": ["Continuous integration", "Ruby", "SDLC"]
+ "categories": ["Continuous integration", "Ruby"]
}
diff --git a/ci/properties/grunt.properties.json b/ci/properties/grunt.properties.json
new file mode 100644
index 0000000..c8a5b9f
--- /dev/null
+++ b/ci/properties/grunt.properties.json
@@ -0,0 +1,6 @@
+{
+ "name": "Grunt",
+ "description": "Build a NodeJS project with npm and grunt.",
+ "iconName": "grunt",
+ "categories": ["JavaScript", "TypeScript", "npm", "Grunt"]
+}
diff --git a/ci/properties/gulp.properties.json b/ci/properties/gulp.properties.json
new file mode 100644
index 0000000..658325b
--- /dev/null
+++ b/ci/properties/gulp.properties.json
@@ -0,0 +1,6 @@
+{
+ "name": "Gulp",
+ "description": "Build a NodeJS project with npm and gulp.",
+ "iconName": "gulp",
+ "categories": ["JavaScript", "TypeScript", "npm", "Gulp"]
+}
diff --git a/ci/properties/node.js.properties.json b/ci/properties/node.js.properties.json
index 3b0b094..1939bd2 100644
--- a/ci/properties/node.js.properties.json
+++ b/ci/properties/node.js.properties.json
@@ -2,5 +2,5 @@
"name": "Node.js",
"description": "Build and test a Node.js project with npm.",
"iconName": "nodejs",
- "categories": ["Continuous integration", "JavaScript", "Node", "Npm"]
+ "categories": ["Continuous integration", "JavaScript", "npm"]
}
diff --git a/ci/properties/npm-publish.properties.json b/ci/properties/npm-publish.properties.json
index a1c3543..9371d7b 100644
--- a/ci/properties/npm-publish.properties.json
+++ b/ci/properties/npm-publish.properties.json
@@ -2,5 +2,5 @@
"name": "Publish Node.js Package",
"description": "Publishes a Node.js package to npm and GitHub Packages.",
"iconName": "node-package-transparent",
- "categories": ["Continuous integration", "JavaScript", "SDLC"]
+ "categories": ["Continuous integration", "JavaScript", "npm"]
}
diff --git a/ci/properties/terraform.properties.json b/ci/properties/terraform.properties.json
index bfeabdf..12afabe 100644
--- a/ci/properties/terraform.properties.json
+++ b/ci/properties/terraform.properties.json
@@ -3,5 +3,5 @@
"description": "Set up Terraform CLI in your GitHub Actions workflow.",
"creator": "HashiCorp",
"iconName": "terraform",
- "categories": null
+ "categories": ["Deployment"]
}
diff --git a/ci/properties/webpack.properties.json b/ci/properties/webpack.properties.json
new file mode 100644
index 0000000..1e22ccb
--- /dev/null
+++ b/ci/properties/webpack.properties.json
@@ -0,0 +1,6 @@
+{
+ "name": "Webpack",
+ "description": "Build a NodeJS project with npm and webpack.",
+ "iconName": "webpack",
+ "categories": ["JavaScript", "TypeScript", "npm", "Webpack"]
+}
diff --git a/ci/pylint.yml b/ci/pylint.yml
index c16ba22..0805af7 100644
--- a/ci/pylint.yml
+++ b/ci/pylint.yml
@@ -9,10 +9,10 @@ jobs:
steps:
- uses: actions/checkout@v2
- - name: Set up Python 3.8
- uses: actions/setup-python@v1
+ - name: Set up Python 3.9
+ uses: actions/setup-python@v2
with:
- python-version: 3.8
+ python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
diff --git a/ci/r.yml b/ci/r.yml
index efc6587..f257fbd 100644
--- a/ci/r.yml
+++ b/ci/r.yml
@@ -16,7 +16,7 @@ on:
jobs:
build:
- runs-on: macOS-latest
+ runs-on: macos-latest
strategy:
matrix:
r-version: [3.5, 3.6]
diff --git a/ci/tencent.yml b/ci/tencent.yml
index 1a059a6..0be339e 100644
--- a/ci/tencent.yml
+++ b/ci/tencent.yml
@@ -43,7 +43,7 @@ jobs:
- name: Login TKE Registry
run: |
- docker login -u ${{ secrets.TENCENT_CLOUD_ACCOUNT_ID }} -p ${{ secrets.TKE_REGISTRY_PASSWORD }} ${TKE_IMAGE_URL}
+ docker login -u ${{ secrets.TENCENT_CLOUD_ACCOUNT_ID }} -p '${{ secrets.TKE_REGISTRY_PASSWORD }}' ${TKE_IMAGE_URL}
# Push the Docker image to TKE Registry
- name: Publish
@@ -73,4 +73,4 @@ jobs:
./kustomize edit set image ${TKE_IMAGE_URL}:${GITHUB_SHA}
./kustomize build . | kubectl apply -f -
kubectl rollout status deployment/${DEPLOYMENT_NAME}
- kubectl get services -o wide
\ No newline at end of file
+ kubectl get services -o wide
diff --git a/ci/webpack.yml b/ci/webpack.yml
new file mode 100644
index 0000000..8edb34f
--- /dev/null
+++ b/ci/webpack.yml
@@ -0,0 +1,28 @@
+name: NodeJS with Webpack
+
+on:
+ push:
+ branches: [ $default-branch ]
+ pull_request:
+ branches: [ $default-branch ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [12.x, 14.x, 16.x]
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Build
+ run: |
+ npm install
+ npx webpack
diff --git a/code-scanning/flawfinder.yml b/code-scanning/flawfinder.yml
new file mode 100644
index 0000000..080953e
--- /dev/null
+++ b/code-scanning/flawfinder.yml
@@ -0,0 +1,38 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+name: flawfinder
+
+on:
+ push:
+ branches: [ $default-branch, $protected-branches ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ $default-branch ]
+ schedule:
+ - cron: $cron-weekly
+
+jobs:
+ flawfinder:
+ name: Flawfinder
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: flawfinder_scan
+ uses: david-a-wheeler/flawfinder@8e4a779ad59dbfaee5da586aa9210853b701959c
+ with:
+ arguments: '--sarif ./'
+ output: 'flawfinder_results.sarif'
+
+ - name: Upload analysis results to GitHub Security tab
+ uses: github/codeql-action/upload-sarif@v1
+ with:
+ sarif_file: ${{github.workspace}}/flawfinder_results.sarif
\ No newline at end of file
diff --git a/code-scanning/properties/devskim.properties.json b/code-scanning/properties/devskim.properties.json
index 0eab5c6..40fd52b 100644
--- a/code-scanning/properties/devskim.properties.json
+++ b/code-scanning/properties/devskim.properties.json
@@ -1,7 +1,7 @@
{
"name": "DevSkim",
"creator": "Microsoft CST-E",
- "description": "DevSkim is security linter that highlights common security issues in source code.",
+ "description": "DevSkim is a security linter that highlights common security issues in source code.",
"iconName": "cst-logo",
"categories": ["Code Scanning", "C", "C#", "C++", "Go", "Java", "JavaScript", "TypeScript", "Python", "Powershell", "Cobol", "Objective C", "PHP", "Ruby", "Rust", "SQL", "Swift", "Visual Basic"]
}
diff --git a/code-scanning/properties/flawfinder.properties.json b/code-scanning/properties/flawfinder.properties.json
new file mode 100644
index 0000000..f784d03
--- /dev/null
+++ b/code-scanning/properties/flawfinder.properties.json
@@ -0,0 +1,7 @@
+{
+ "name": "Flawfinder",
+ "creator": "David A. Wheeler",
+ "description": "Flawfinder is a simple program that scans C/C++ source code and reports potential security flaws.",
+ "iconName": "flawfinder",
+ "categories": [ "Code Scanning", "C", "C++" ]
+}
\ No newline at end of file
diff --git a/code-scanning/properties/stackhawk.properties.json b/code-scanning/properties/stackhawk.properties.json
new file mode 100644
index 0000000..f422535
--- /dev/null
+++ b/code-scanning/properties/stackhawk.properties.json
@@ -0,0 +1,24 @@
+{
+ "name": "StackHawk",
+ "creator": "StackHawk",
+ "description": "Integrate dynamic application security testing (DAST) and API security testing into your CI pipeline with StackHawk",
+ "iconName": "stackhawk",
+ "categories": [
+ "Code Scanning",
+ "C",
+ "C#",
+ "C++",
+ "Go",
+ "Java",
+ "JavaScript",
+ "Kotlin",
+ "Objective C",
+ "PHP",
+ "Python",
+ "Ruby",
+ "Rust",
+ "Scala",
+ "Swift",
+ "TypeScript"
+ ]
+}
diff --git a/code-scanning/stackhawk.yml b/code-scanning/stackhawk.yml
new file mode 100644
index 0000000..9701b1f
--- /dev/null
+++ b/code-scanning/stackhawk.yml
@@ -0,0 +1,57 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+# 🦅 STACKHAWK https://stackhawk.com
+
+# The StackHawk HawkScan action makes it easy to integrate dynamic application security testing (DAST) into your
+# CI pipeline. See the Getting Started guide (https://docs.stackhawk.com/hawkscan/) to get up and running with
+# StackHawk quickly.
+
+# To use this workflow, you must:
+#
+# 1. Create an API Key and Application: Sign up for a free StackHawk account to obtain an API Key and
+# create your first app and configuration file at https://app.stackhawk.com.
+#
+# 2. Save your API Key as a Secret: Save your API key as a GitHub Secret named HAWK_API_KEY.
+#
+# 3. Add your Config File: Add your stackhawk.yml configuration file to the base of your repository directory.
+#
+# 4. Set the Scan Failure Threshold: Add the hawk.failureThreshold configuration option
+# (https://docs.stackhawk.com/hawkscan/configuration/#hawk) to your stackhawk.yml configuration file. If your scan
+# produces alerts that meet or exceed the hawk.failureThreshold alert level, the scan will return exit code 42
+# and trigger a Code Scanning alert with a link to your scan results.
+#
+# 5. Update the "Start your service" Step: Update the "Start your service" step in the StackHawk workflow below to
+# start your service so that it can be scanned with the "Run HawkScan" step.
+
+
+name: "StackHawk"
+
+on:
+ push:
+ branches: [ $default-branch, $protected-branches ]
+ pull_request:
+ branches: [ $default-branch ]
+ schedule:
+ - cron: $cron-weekly
+
+jobs:
+ stackhawk:
+ name: StackHawk
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Start your service
+ run: ./your-service.sh & # ✏️ Update this to run your own service to be scanned
+
+ - name: Run HawkScan
+ uses: stackhawk/hawkscan-action@4c3258cd62248dac6d9fe91dd8d45928c697dee0
+ continue-on-error: true # ✏️ Set to false to break your build on scan errors
+ with:
+ apiKey: ${{ secrets.HAWK_API_KEY }}
+ codeScanningAlerts: true
+ githubToken: ${{ github.token }}
diff --git a/icons/flawfinder.svg b/icons/flawfinder.svg
new file mode 100644
index 0000000..2324dca
--- /dev/null
+++ b/icons/flawfinder.svg
@@ -0,0 +1,16 @@
+
diff --git a/icons/stackhawk.svg b/icons/stackhawk.svg
new file mode 100644
index 0000000..6b47520
--- /dev/null
+++ b/icons/stackhawk.svg
@@ -0,0 +1,17 @@
+
diff --git a/script/sync-ghes/index.ts b/script/sync-ghes/index.ts
index 0fa3440..e37eca3 100755
--- a/script/sync-ghes/index.ts
+++ b/script/sync-ghes/index.ts
@@ -19,6 +19,8 @@ interface WorkflowProperties {
iconName?: string;
categories: string[] | null;
+
+ creator?: string;
}
interface WorkflowsCheckResult {
@@ -28,12 +30,14 @@ interface WorkflowsCheckResult {
async function checkWorkflows(
folders: string[],
- enabledActions: string[]
+ enabledActions: string[],
+ partners: string[]
): Promise {
const result: WorkflowsCheckResult = {
compatibleWorkflows: [],
incompatibleWorkflows: [],
};
+ const partnersSet = new Set(partners.map((x) => x.toLowerCase()));
for (const folder of folders) {
const dir = await fs.readdir(folder, {
@@ -51,11 +55,10 @@ async function checkWorkflows(
));
const iconName: string | undefined = workflowProperties["iconName"];
- const isBlankTemplate = workflowId === "blank";
- const partnerWorkflow = workflowProperties.categories === null;
+ const isPartnerWorkflow = workflowProperties.creator ? partnersSet.has(workflowProperties.creator.toLowerCase()) : false;
const enabled =
- (isBlankTemplate || !partnerWorkflow) &&
+ !isPartnerWorkflow &&
(await checkWorkflow(workflowFilePath, enabledActions));
const workflowDesc: WorkflowDesc = {
@@ -90,7 +93,6 @@ async function checkWorkflow(
): Promise {
// Create set with lowercase action names for easier, case-insensitive lookup
const enabledActionsSet = new Set(enabledActions.map((x) => x.toLowerCase()));
-
try {
const workflowFileContent = await fs.readFile(workflowPath, "utf8");
const workflow = safeLoad(workflowFileContent);
@@ -126,7 +128,8 @@ async function checkWorkflow(
const result = await checkWorkflows(
settings.folders,
- settings.enabledActions
+ settings.enabledActions,
+ settings.partners
);
console.group(
diff --git a/script/sync-ghes/settings.json b/script/sync-ghes/settings.json
index 050ea0a..60b70ed 100644
--- a/script/sync-ghes/settings.json
+++ b/script/sync-ghes/settings.json
@@ -16,5 +16,15 @@
"actions/starter-workflows",
"actions/upload-artifact",
"actions/upload-release-asset"
+ ],
+ "partners": [
+ "Alibaba Cloud",
+ "Amazon Web Services",
+ "Microsoft Azure",
+ "Google Cloud",
+ "IBM",
+ "Red Hat",
+ "Tencent Cloud",
+ "HashiCorp"
]
}
diff --git a/script/validate-data/index.ts b/script/validate-data/index.ts
index 81048f8..8413653 100755
--- a/script/validate-data/index.ts
+++ b/script/validate-data/index.ts
@@ -7,6 +7,7 @@ import { endGroup, error, info, setFailed, startGroup } from '@actions/core';
interface WorkflowWithErrors {
id: string;
+ name: string;
errors: string[];
}
@@ -20,7 +21,7 @@ interface WorkflowProperties {
const propertiesSchema = {
type: "object",
properties: {
- name: { type: "string", required: true },
+ name: { type: "string", required: true , "minLength": 1},
description: { type: "string", required: true },
creator: { type: "string", required: false },
iconName: { type: "string", required: true },
@@ -41,7 +42,7 @@ const propertiesSchema = {
async function checkWorkflows(folders: string[]): Promise {
const result: WorkflowWithErrors[] = []
-
+ const workflow_template_names = new Set()
for (const folder of folders) {
const dir = await fs.readdir(folder, {
withFileTypes: true,
@@ -54,9 +55,12 @@ async function checkWorkflows(folders: string[]): Promise
const workflowFilePath = join(folder, e.name);
const propertiesFilePath = join(folder, "properties", `${fileType}.properties.json`)
- const errors = await checkWorkflow(workflowFilePath, propertiesFilePath);
- if (errors.errors.length > 0) {
- result.push(errors)
+ const workflowWithErrors = await checkWorkflow(workflowFilePath, propertiesFilePath);
+ if(workflowWithErrors.name && workflow_template_names.size == workflow_template_names.add(workflowWithErrors.name).size) {
+ workflowWithErrors.errors.push(`Workflow template name "${workflowWithErrors.name}" already exists`)
+ }
+ if (workflowWithErrors.errors.length > 0) {
+ result.push(workflowWithErrors)
}
}
}
@@ -68,6 +72,7 @@ async function checkWorkflows(folders: string[]): Promise
async function checkWorkflow(workflowPath: string, propertiesPath: string): Promise {
let workflowErrors: WorkflowWithErrors = {
id: workflowPath,
+ name: null,
errors: []
}
@@ -77,17 +82,28 @@ async function checkWorkflow(workflowPath: string, propertiesPath: string): Prom
const propertiesFileContent = await fs.readFile(propertiesPath, "utf8")
const properties: WorkflowProperties = JSON.parse(propertiesFileContent)
-
+ if(properties.name && properties.name.trim().length > 0) {
+ workflowErrors.name = properties.name
+ }
let v = new validator();
const res = v.validate(properties, propertiesSchema)
workflowErrors.errors = res.errors.map(e => e.toString())
-
- if (properties.iconName && !properties.iconName.startsWith("octicon")) {
- try {
- await fs.access(`../../icons/${properties.iconName}.svg`)
- } catch (e) {
- workflowErrors.errors.push(`No icon named ${properties.iconName} found`)
+
+ if (properties.iconName) {
+ if(! /^octicon\s+/.test(properties.iconName)) {
+ try {
+ await fs.access(`../../icons/${properties.iconName}.svg`)
+ } catch (e) {
+ workflowErrors.errors.push(`No icon named ${properties.iconName} found`)
+ }
}
+ else {
+ let iconName = properties.iconName.match(/^octicon\s+(.*)/)
+ if(!iconName || iconName[1].split(".")[0].length <= 0) {
+ workflowErrors.errors.push(`No icon named ${properties.iconName} found`)
+ }
+ }
+
}
} catch (e) {
workflowErrors.errors.push(e.toString())